Merge pull request #872 from ey6es/ssao

Performance improvement for the SSAO blur step, cleanup.
This commit is contained in:
ZappoMan 2013-08-20 15:40:48 -07:00
commit a6a38b4ebe
6 changed files with 42 additions and 29 deletions

View file

@ -59,7 +59,7 @@ void main(void) {
vec3 offset = center + rotation * (radius * sampleKernel[i]);
vec4 projected = gl_ProjectionMatrix * vec4(offset, 1.0);
float depth = texCoordToViewSpaceZ(projected.xy * 0.5 / projected.w + vec2(0.5, 0.5));
occlusion += 1.0 - step(offset.z, depth); // * step(abs(center.z - depth), radius);
occlusion += 1.0 - step(offset.z, depth);
}
gl_FragColor = vec4(occlusion, occlusion, occlusion, 0.0) / 16.0;

View file

@ -11,15 +11,14 @@
// the original texture
uniform sampler2D originalTexture;
// the scale for the blur kernel
uniform vec2 blurScale;
void main(void) {
float ds = dFdx(gl_TexCoord[0].s);
float dt = dFdy(gl_TexCoord[0].t);
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
sum += texture2D(originalTexture, gl_TexCoord[0].st +
vec2(ds, dt) * vec2(-2.0 + float(i), -2.0 + float(j)));
}
}
gl_FragColor = sum / 16.0;
vec2 minExtents = gl_TexCoord[0].st + blurScale * vec2(-0.5, -0.5);
vec2 maxExtents = gl_TexCoord[0].st + blurScale * vec2(1.5, 1.5);
gl_FragColor = (texture2D(originalTexture, minExtents) +
texture2D(originalTexture, vec2(maxExtents.s, minExtents.t)) +
texture2D(originalTexture, vec2(minExtents.s, maxExtents.t)) +
texture2D(originalTexture, maxExtents)) * 0.25;
}

View file

@ -32,15 +32,6 @@ void AmbientOcclusionEffect::init() {
_occlusionProgram->addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/ambient_occlusion.frag");
_occlusionProgram->link();
_blurProgram = new ProgramObject();
_blurProgram->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/ambient_occlusion.vert");
_blurProgram->addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/occlusion_blur.frag");
_blurProgram->link();
_blurProgram->bind();
_blurProgram->setUniformValue("originalTexture", 0);
_blurProgram->release();
// create the sample kernel: an array of spherically distributed offset vectors
const int SAMPLE_KERNEL_SIZE = 16;
QVector3D sampleKernel[SAMPLE_KERNEL_SIZE];
@ -83,6 +74,17 @@ void AmbientOcclusionEffect::init() {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
_blurProgram = new ProgramObject();
_blurProgram->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/ambient_occlusion.vert");
_blurProgram->addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/occlusion_blur.frag");
_blurProgram->link();
_blurProgram->bind();
_blurProgram->setUniformValue("originalTexture", 0);
_blurProgram->release();
_blurScaleLocation = _blurProgram->uniformLocation("blurScale");
}
void AmbientOcclusionEffect::render() {
@ -131,6 +133,7 @@ void AmbientOcclusionEffect::render() {
glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture());
_blurProgram->bind();
_blurProgram->setUniformValue(_blurScaleLocation, 1.0f / size.width(), 1.0f / size.height());
renderFullscreenQuad();
@ -138,7 +141,6 @@ void AmbientOcclusionEffect::render() {
glBindTexture(GL_TEXTURE_2D, 0);
//glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);

View file

@ -32,6 +32,7 @@ private:
int _noiseScaleLocation;
ProgramObject* _blurProgram;
int _blurScaleLocation;
GLuint _rotationTextureID;
};

View file

@ -64,12 +64,11 @@ GLuint TextureCache::getPermutationNormalTextureID() {
QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() {
if (_primaryFramebufferObject == NULL) {
QSize size = Application::getInstance()->getGLWidget()->size();
_primaryFramebufferObject = new QOpenGLFramebufferObject(size);
Application::getInstance()->getGLWidget()->installEventFilter(this);
_primaryFramebufferObject = createFramebufferObject();
glGenTextures(1, &_primaryDepthTextureID);
glBindTexture(GL_TEXTURE_2D, _primaryDepthTextureID);
QSize size = Application::getInstance()->getGLWidget()->size();
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size.width(), size.height(),
0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -91,16 +90,14 @@ GLuint TextureCache::getPrimaryDepthTextureID() {
QOpenGLFramebufferObject* TextureCache::getSecondaryFramebufferObject() {
if (_secondaryFramebufferObject == NULL) {
_secondaryFramebufferObject = new QOpenGLFramebufferObject(Application::getInstance()->getGLWidget()->size());
Application::getInstance()->getGLWidget()->installEventFilter(this);
_secondaryFramebufferObject = createFramebufferObject();
}
return _secondaryFramebufferObject;
}
QOpenGLFramebufferObject* TextureCache::getTertiaryFramebufferObject() {
if (_tertiaryFramebufferObject == NULL) {
_tertiaryFramebufferObject = new QOpenGLFramebufferObject(Application::getInstance()->getGLWidget()->size());
Application::getInstance()->getGLWidget()->installEventFilter(this);
_tertiaryFramebufferObject = createFramebufferObject();
}
return _tertiaryFramebufferObject;
}
@ -124,3 +121,15 @@ bool TextureCache::eventFilter(QObject* watched, QEvent* event) {
}
return false;
}
QOpenGLFramebufferObject* TextureCache::createFramebufferObject() {
QOpenGLFramebufferObject* fbo = new QOpenGLFramebufferObject(Application::getInstance()->getGLWidget()->size());
Application::getInstance()->getGLWidget()->installEventFilter(this);
glBindTexture(GL_TEXTURE_2D, fbo->texture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
return fbo;
}

View file

@ -46,6 +46,8 @@ public:
private:
QOpenGLFramebufferObject* createFramebufferObject();
GLuint _permutationNormalTextureID;
QOpenGLFramebufferObject* _primaryFramebufferObject;