diff --git a/interface/resources/shaders/diffuse.frag b/interface/resources/shaders/diffuse.frag index f8be7075db..ebf11dace2 100644 --- a/interface/resources/shaders/diffuse.frag +++ b/interface/resources/shaders/diffuse.frag @@ -14,15 +14,14 @@ uniform sampler2D originalTexture; // the texture containing the diffused color uniform sampler2D diffusedTexture; +// the scale of diffusion +uniform vec2 diffusionScale; + void main(void) { - float ds = dFdx(gl_TexCoord[0].s); - float dt = dFdy(gl_TexCoord[0].t); - gl_FragColor = (texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(-ds, -dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(0.0, -dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(ds, -dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(ds, 0.0)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(ds, dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(0.0, dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(-ds, dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(-ds, 0.0))) / 8.5 + texture2D(originalTexture, gl_TexCoord[0].st) * 0.1; + vec2 minExtents = gl_TexCoord[0].st + diffusionScale * vec2(-1.5, -1.5); + vec2 maxExtents = gl_TexCoord[0].st + diffusionScale * vec2(1.5, 1.5); + gl_FragColor = (texture2D(diffusedTexture, minExtents) + + texture2D(diffusedTexture, vec2(maxExtents.s, minExtents.t)) + + texture2D(diffusedTexture, vec2(minExtents.s, maxExtents.t)) + + texture2D(diffusedTexture, maxExtents)) * 0.235 + texture2D(originalTexture, gl_TexCoord[0].st) * 0.1; } diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index 368546a566..309816191b 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -97,9 +97,9 @@ void AmbientOcclusionEffect::render() { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, _rotationTextureID); - // render with the occlusion shader to the secondary buffer - QOpenGLFramebufferObject* secondaryFBO = Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); - secondaryFBO->bind(); + // render with the occlusion shader to the secondary/tertiary buffer + QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject(); + freeFBO->bind(); float left, right, bottom, top, nearVal, farVal; glm::vec4 nearClipPlane, farClipPlane; @@ -119,7 +119,7 @@ void AmbientOcclusionEffect::render() { _occlusionProgram->release(); - secondaryFBO->release(); + freeFBO->release(); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); @@ -130,7 +130,7 @@ void AmbientOcclusionEffect::render() { glEnable(GL_BLEND); glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE); - glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture()); + glBindTexture(GL_TEXTURE_2D, freeFBO->texture()); _blurProgram->bind(); _blurProgram->setUniformValue(_blurScaleLocation, 1.0f / size.width(), 1.0f / size.height()); diff --git a/interface/src/renderer/GlowEffect.cpp b/interface/src/renderer/GlowEffect.cpp index 85c4eb27b2..936364f8c0 100644 --- a/interface/src/renderer/GlowEffect.cpp +++ b/interface/src/renderer/GlowEffect.cpp @@ -15,7 +15,13 @@ #include "ProgramObject.h" #include "RenderUtil.h" -GlowEffect::GlowEffect() : _renderMode(BLUR_ADD_MODE) { +GlowEffect::GlowEffect() : _renderMode(DIFFUSE_ADD_MODE), _isOddFrame(false) { +} + +QOpenGLFramebufferObject* GlowEffect::getFreeFramebufferObject() const { + return (_renderMode == DIFFUSE_ADD_MODE && !_isOddFrame) ? + Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject() : + Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); } static ProgramObject* createProgram(const QString& name) { @@ -51,6 +57,8 @@ void GlowEffect::init() { _diffuseProgram->bind(); _diffuseProgram->setUniformValue("diffusedTexture", 1); _diffuseProgram->release(); + + _diffusionScaleLocation = _diffuseProgram->uniformLocation("diffusionScale"); } void GlowEffect::prepare() { @@ -58,6 +66,7 @@ void GlowEffect::prepare() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _isEmpty = true; + _isOddFrame = !_isOddFrame; } void GlowEffect::begin(float intensity) { @@ -109,7 +118,7 @@ void GlowEffect::render() { Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); QOpenGLFramebufferObject* newDiffusedFBO = Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject(); - if ((_isOddFrame = !_isOddFrame)) { + if (_isOddFrame) { qSwap(oldDiffusedFBO, newDiffusedFBO); } newDiffusedFBO->bind(); @@ -118,7 +127,11 @@ void GlowEffect::render() { glBindTexture(GL_TEXTURE_2D, oldDiffusedFBO->texture()); _diffuseProgram->bind(); + QSize size = Application::getInstance()->getGLWidget()->size(); + _diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / size.width(), 1.0f / size.height()); + renderFullscreenQuad(); + _diffuseProgram->release(); newDiffusedFBO->release(); @@ -204,5 +217,22 @@ void GlowEffect::render() { } void GlowEffect::cycleRenderMode() { - _renderMode = (RenderMode)((_renderMode + 1) % RENDER_MODE_COUNT); + switch(_renderMode = (RenderMode)((_renderMode + 1) % RENDER_MODE_COUNT)) { + case ADD_MODE: + qDebug() << "Glow mode: Add\n"; + break; + + case BLUR_ADD_MODE: + qDebug() << "Glow mode: Blur/add\n"; + break; + + case BLUR_PERSIST_ADD_MODE: + qDebug() << "Glow mode: Blur/persist/add\n"; + break; + + default: + case DIFFUSE_ADD_MODE: + qDebug() << "Glow mode: Diffuse/add\n"; + break; + } } diff --git a/interface/src/renderer/GlowEffect.h b/interface/src/renderer/GlowEffect.h index 0d6e83a7a6..73119365e8 100644 --- a/interface/src/renderer/GlowEffect.h +++ b/interface/src/renderer/GlowEffect.h @@ -11,6 +11,8 @@ #include +class QOpenGLFramebufferObject; + class ProgramObject; /// A generic full screen glow effect. @@ -21,6 +23,10 @@ public: GlowEffect(); + /// Returns a pointer to the framebuffer object that the glow effect is *not* using for persistent state + /// (either the secondary or the tertiary). + QOpenGLFramebufferObject* getFreeFramebufferObject() const; + void init(); /// Prepares the glow effect for rendering the current frame. To be called before rendering the scene. @@ -51,6 +57,7 @@ private: ProgramObject* _verticalBlurProgram; ProgramObject* _addSeparateProgram; ProgramObject* _diffuseProgram; + int _diffusionScaleLocation; bool _isEmpty; ///< set when nothing in the scene is currently glowing bool _isOddFrame; ///< controls the alternation between texture targets in diffuse add mode