diff --git a/doomsday/client/data/renderer.pack/shaders/lensflares.vsh b/doomsday/client/data/renderer.pack/shaders/lensflares.vsh index 65b79b69b0..6ddced648b 100644 --- a/doomsday/client/data/renderer.pack/shaders/lensflares.vsh +++ b/doomsday/client/data/renderer.pack/shaders/lensflares.vsh @@ -1,5 +1,6 @@ uniform highp mat4 uMvpMatrix; uniform highp vec2 uViewUnit; +uniform highp vec2 uPixelAsUv; uniform sampler2D uDepthBuf; attribute highp vec4 aVertex; @@ -11,40 +12,44 @@ attribute highp vec2 aUV3; varying highp vec4 vColor; varying highp vec2 vUV; +bool isOccluded(highp vec2 uv) { + float depth = texture2D(uDepthBuf, uv).r; + return (depth < (gl_Position.z/gl_Position.w + 1.0) / 2.0); +} + +float occlusionLevel() { + highp vec2 depthUv = gl_Position.xy / gl_Position.w / 2.0 + vec2(0.5, 0.5); + float occ = 0.0; + if(!isOccluded(depthUv)) occ += 0.2; + if(!isOccluded(depthUv + vec2(uPixelAsUv.x * 4.0, uPixelAsUv.y))) occ += 0.2; + if(!isOccluded(depthUv - vec2(uPixelAsUv.x * 4.0, uPixelAsUv.y))) occ += 0.2; + if(!isOccluded(depthUv + vec2(uPixelAsUv.x, uPixelAsUv.y * 4.0))) occ += 0.2; + if(!isOccluded(depthUv - vec2(uPixelAsUv.x, uPixelAsUv.y * 4.0))) occ += 0.2; + return occ; +} + void main(void) { vUV = aUV; vColor = aColor; gl_Position = uMvpMatrix * aVertex; - // Is this occluded in the depth buffer? - highp vec2 depthUv = gl_Position.xy / gl_Position.w / 2.0 + vec2(0.5, 0.5); - float depth = texture2D(uDepthBuf, depthUv).r; -/* if(depth < (gl_Position.z/gl_Position.w + 1.0)/2.0) { - // Occluded! + // Is the origin occluded in the depth buffer? + float ocl = occlusionLevel(); + if(ocl <= 0.0) { + // Occluded! Make it invisibile and leave the quad zero-sized. vUV = aUV; vColor = vec4(0.0, 0.0, 0.0, 0.0); - return; - } */ + return; + } + else { + vColor.a *= ocl; + } // Position on the axis that passes through the center of the view. highp float axisPos = aUV3.s; gl_Position.xy *= axisPos; + // Position the quad corners. gl_Position.xy += aUV2 * uViewUnit * vec2(gl_Position.w); - - /* - // Testing - vColor = vec4(1.0, 1.0, 1.0, 1.0); - vUV = (aUV2 + 1.0) / 2.0; - gl_Position.xy = aUV2; - gl_Position.z = 0.0; - gl_Position.w = 1.0; - */ - - if(depth < (gl_Position.z/gl_Position.w + 1.0)/2.0) { - // Occluded! - vColor = vec4(1.0, 0.0, 0.0, 1.0); - } - } diff --git a/doomsday/client/src/render/fx/lensflares.cpp b/doomsday/client/src/render/fx/lensflares.cpp index 277df0743b..7982df48e7 100644 --- a/doomsday/client/src/render/fx/lensflares.cpp +++ b/doomsday/client/src/render/fx/lensflares.cpp @@ -227,6 +227,7 @@ DENG2_PIMPL(LensFlares) Drawable drawable; GLUniform uMvpMatrix; GLUniform uViewUnit; + GLUniform uPixelAsUv; GLUniform uAtlas; GLUniform uDepthBuf; @@ -236,6 +237,7 @@ DENG2_PIMPL(LensFlares) , buffer(0) , uMvpMatrix("uMvpMatrix", GLUniform::Mat4) , uViewUnit ("uViewUnit", GLUniform::Vec2) + , uPixelAsUv("uPixelAsUv", GLUniform::Vec2) , uAtlas ("uTex", GLUniform::Sampler2D) , uDepthBuf ("uDepthBuf", GLUniform::Sampler2D) {} @@ -255,7 +257,7 @@ DENG2_PIMPL(LensFlares) buffer = new VBuf; drawable.addBuffer(buffer); self.shaders().build(drawable.program(), "fx.lensflares") - << uMvpMatrix << uViewUnit + << uMvpMatrix << uViewUnit << uPixelAsUv << uAtlas << uDepthBuf; uAtlas = res->atlas; @@ -485,9 +487,12 @@ void LensFlares::draw() Rectanglef const rect = viewRect(); float const aspect = rect.height() / rect.width(); + Canvas &canvas = ClientWindow::main().canvas(); + d->uViewUnit = Vector2f(aspect, 1.f); + d->uPixelAsUv = Vector2f(1.f / canvas.width(), 1.f / canvas.height()); d->uMvpMatrix = GL_GetProjectionMatrix() * Rend_GetModelViewMatrix(console()); - d->uDepthBuf = ClientWindow::main().canvas().depthBufferTexture(); + d->uDepthBuf = canvas.depthBufferTexture(); GLState::push() .setCull(gl::None) diff --git a/doomsday/libgui/include/de/gui/gltarget.h b/doomsday/libgui/include/de/gui/gltarget.h index 2bf3e61f31..903402135d 100644 --- a/doomsday/libgui/include/de/gui/gltarget.h +++ b/doomsday/libgui/include/de/gui/gltarget.h @@ -177,9 +177,9 @@ class LIBGUI_PUBLIC GLTarget : public Asset /** * Sets the subregion inside the render target where scissor and viewport - * will be constrained to. Scissor and viewport can still be defined as if - * the entire window was in use; the target window only applies an offset - * and scaling to both. + * will be scaled into. Scissor and viewport can still be defined as if the + * entire window was in use; this only applies an offset and scaling to + * both. * * @param rect Target window rectangle. Set a null rectangle to * use the entire window (like normally).