In a deferred shading framework, I am using different framebufer objects to perform various render passes. In the first pass I write the DEPTH_STENCIL_ATTACHMENT
for the whole scene to a texture, let's call it DepthStencilTexture
.
To access the depth information stored in DepthStencilTexture
from different render passes, for which I use different framebuffer objects, I know two ways:
1) I bind the DepthStencilTexture
to the shader and I access it in the fragment shader, where I do the depth manually, like this
uniform vec2 WinSize; //windows dimensions
vec2 uv=gl_FragCoord.st/WinSize;
float depth=texture(DepthStencilTexture ,uv).r;
if(gl_FragCoord.z>depth) discard;
I also set glDisable(GL_DEPTH_TEST)
and glDepthMask(GL_FALSE)
2) I bind the DepthStencilTexture
to the framebuffer object as DEPTH_STENCIL_ATTACHMENT
and set glEnable(GL_DEPTH_TEST)
and glDepthMask(GL_FALSE)
(edit: in this case I won't bind the DepthStencilTexture
to the shader, to avoid loop feedback, see the answer by Nicol Bolas, and I if I need the depth in the fragment shader I will use gl_FragCorrd.z
)
In certain situations, such as drawing light volumes, for which I need the Stencil Test and writing to the stencil buffer, I am going for the solution 2).
In other situations, in which I completely ignore the Stencil, and just need the depth stored in the DepthStencilTexture
, does option 1) gives any advantages over the more "natural" option 2) ?
For example I have a (silly, I think) doubt about it . Sometimes in my fragment shaders Icompute the WorldPosition from the depth. In the case 1) it would be like this
uniform mat4 invPV; //inverse PV matrix
vec2 uv=gl_FragCoord.st/WinSize;
vec4 WorldPosition=invPV*vec4(uv, texture(DepthStencilTexture ,uv).r ,1.0f );
WorldPosition=WorldPosition/WorldPosition.w;
In the case 2) it would be like this (edit: this is wrong, gl_FragCoord.z is the current fragment's depth, not the actual depth stored in the texture)
uniform mat4 invPV; //inverse PV matrix
vec2 uv=gl_FragCoord.st/WinSize;
vec4 WorldPosition=invPV*vec4(uv, gl_FragCoord.z, 1.0f );
WorldPosition=WorldPosition/WorldPosition.w;
I am assuming that gl_FragCoord.z
in case 2) will be the same as texture(DepthStencilTexture ,uv).r
in case 1), or, in other words, the depth stored in the the DepthStencilTexture
. Is it true? Is gl_FragCoord.z
read from the currently bound DEPTH_STENCIL_ATTACHMENT
also with glDisable(GL_DEPTH_TEST)
and glDepthMask(GL_FALSE)
?