From 7f4557fe1a32f132c8d93076fa1f51cc7b75393d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 10:50:25 -0700 Subject: [PATCH 1/4] Add blur scale uniform. --- .../src/renderer/AmbientOcclusionEffect.cpp | 20 ++++++++++--------- .../src/renderer/AmbientOcclusionEffect.h | 1 + 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index ff86615b26..f4931c5f71 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -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() { diff --git a/interface/src/renderer/AmbientOcclusionEffect.h b/interface/src/renderer/AmbientOcclusionEffect.h index d41bb65381..416d97c236 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.h +++ b/interface/src/renderer/AmbientOcclusionEffect.h @@ -32,6 +32,7 @@ private: int _noiseScaleLocation; ProgramObject* _blurProgram; + int _blurScaleLocation; GLuint _rotationTextureID; }; From 22598ceb4f702ad04b6d45ce18a90cd381884200 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 11:52:43 -0700 Subject: [PATCH 2/4] Optimizations for occlusion blur (the main one being that we only need to sample the texture four, not sixteen, times if we turn on linear filtering and sample between the texels). --- .../resources/shaders/occlusion_blur.frag | 19 +++++++------- .../src/renderer/AmbientOcclusionEffect.cpp | 5 ++-- interface/src/renderer/TextureCache.cpp | 25 +++++++++++++------ interface/src/renderer/TextureCache.h | 2 ++ 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/interface/resources/shaders/occlusion_blur.frag b/interface/resources/shaders/occlusion_blur.frag index 2ee5eaf2cb..5b86aec68d 100644 --- a/interface/resources/shaders/occlusion_blur.frag +++ b/interface/resources/shaders/occlusion_blur.frag @@ -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; } diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index f4931c5f71..184298fd06 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -112,8 +112,8 @@ void AmbientOcclusionEffect::render() { _occlusionProgram->setUniformValue(_leftBottomLocation, left, bottom); _occlusionProgram->setUniformValue(_rightTopLocation, right, top); QSize size = Application::getInstance()->getGLWidget()->size(); - _occlusionProgram->setUniformValue(_noiseScaleLocation, size.width() / (float)ROTATION_WIDTH, - size.height() / (float)ROTATION_HEIGHT); + QVector2D noiseScale(size.width() / (float)ROTATION_WIDTH, size.height() / (float)ROTATION_HEIGHT); + _occlusionProgram->setUniformValue(_noiseScaleLocation, noiseScale); renderFullscreenQuad(); @@ -133,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(); diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index 5696475487..603ff2ccf0 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -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; +} diff --git a/interface/src/renderer/TextureCache.h b/interface/src/renderer/TextureCache.h index 1f2fc96ac5..9be048f398 100644 --- a/interface/src/renderer/TextureCache.h +++ b/interface/src/renderer/TextureCache.h @@ -46,6 +46,8 @@ public: private: + QOpenGLFramebufferObject* createFramebufferObject(); + GLuint _permutationNormalTextureID; QOpenGLFramebufferObject* _primaryFramebufferObject; From 11be8c752baa685e1481ebf8819d919881985ec9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 13:40:45 -0700 Subject: [PATCH 3/4] Cleanup. --- interface/src/renderer/AmbientOcclusionEffect.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index 184298fd06..368546a566 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -112,8 +112,8 @@ void AmbientOcclusionEffect::render() { _occlusionProgram->setUniformValue(_leftBottomLocation, left, bottom); _occlusionProgram->setUniformValue(_rightTopLocation, right, top); QSize size = Application::getInstance()->getGLWidget()->size(); - QVector2D noiseScale(size.width() / (float)ROTATION_WIDTH, size.height() / (float)ROTATION_HEIGHT); - _occlusionProgram->setUniformValue(_noiseScaleLocation, noiseScale); + _occlusionProgram->setUniformValue(_noiseScaleLocation, size.width() / (float)ROTATION_WIDTH, + size.height() / (float)ROTATION_HEIGHT); renderFullscreenQuad(); @@ -141,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); From 5b923bc6f27d63ae3ffc141a253e4362dacff29b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 13:46:13 -0700 Subject: [PATCH 4/4] More cleanup. --- interface/resources/shaders/ambient_occlusion.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/shaders/ambient_occlusion.frag b/interface/resources/shaders/ambient_occlusion.frag index b59c87d797..a62d1d3a71 100644 --- a/interface/resources/shaders/ambient_occlusion.frag +++ b/interface/resources/shaders/ambient_occlusion.frag @@ -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;