Skip to content

Commit

Permalink
Renderer|FX: Check 5 depth points for partial occlusion of a light
Browse files Browse the repository at this point in the history
Could be improved further with resolution independence, and/or
taking into account the radius of the light source.
  • Loading branch information
skyjake committed Nov 29, 2013
1 parent 4969d46 commit 2553dc2
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 27 deletions.
49 changes: 27 additions & 22 deletions 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;
Expand All @@ -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);
}

}
9 changes: 7 additions & 2 deletions doomsday/client/src/render/fx/lensflares.cpp
Expand Up @@ -227,6 +227,7 @@ DENG2_PIMPL(LensFlares)
Drawable drawable;
GLUniform uMvpMatrix;
GLUniform uViewUnit;
GLUniform uPixelAsUv;
GLUniform uAtlas;
GLUniform uDepthBuf;

Expand All @@ -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)
{}
Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions doomsday/libgui/include/de/gui/gltarget.h
Expand Up @@ -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).
Expand Down

0 comments on commit 2553dc2

Please sign in to comment.