在延迟着色框架中,我使用不同的帧缓冲区对象来执行各种渲染过程。在第一遍中,我将DEPTH_STENCIL_ATTACHMENT
整个场景的纹理写入纹理,我们称之为DepthStencilTexture
。DepthStencilTexture
要访问存储在不同渲染通道中的深度信息(为此我使用不同的帧缓冲区对象),我知道两种方法:
1)我将 绑定DepthStencilTexture
到着色器并在片段着色器中访问它,在片段着色器中手动执行深度,例如这个
uniform vec2 WinSize; //windows dimensions
vec2 uv=gl_FragCoord.st/WinSize;
float depth=texture(DepthStencilTexture ,uv).r;
if(gl_FragCoord.z>depth) discard;
我也设置glDisable(GL_DEPTH_TEST)
和glDepthMask(GL_FALSE)
2)我将 绑定DepthStencilTexture
到帧缓冲区对象DEPTH_STENCIL_ATTACHMENT
并设置glEnable(GL_DEPTH_TEST)
和glDepthMask(GL_FALSE)
(编辑:在这种情况下,我不会将 绑定DepthStencilTexture
到着色器,以避免循环反馈,请参阅 Nicol Bolas 的答案,如果我需要深度我将使用片段着色器gl_FragCorrd.z
)
在某些情况下,例如绘制光量,我需要模板测试并写入模板缓冲区,我将采用解决方案 2)。在其他情况下,我完全忽略 Stencil,只需要存储在 中的深度DepthStencilTexture
,选项 1) 是否比更“自然”的选项 2) 有任何优势?
例如,我对此有一个(我认为是愚蠢的)怀疑。有时在我的片段着色器中,我从深度计算 WorldPosition。在这种情况下 1) 它会是这样的
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;
在情况 2)它会是这样的(编辑:这是错误的,gl_FragCoord.z 是当前片段的深度,而不是存储在纹理中的实际深度)
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;
我假设gl_FragCoord.z
情况 2) 将与texture(DepthStencilTexture ,uv).r
情况 1) 相同,或者换句话说,存储在DepthStencilTexture
. 这是真的吗?是 gl_FragCoord.z
从当前绑定的DEPTH_STENCIL_ATTACHMENT
还用glDisable(GL_DEPTH_TEST)
and读取glDepthMask(GL_FALSE)
吗?