【发布时间】:2013-08-16 16:23:59
【问题描述】:
在延迟着色框架中,我使用不同的帧缓冲区对象来执行各种渲染通道。在第一遍中,我将整个场景的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;
我假设情况 2) 中的 gl_FragCoord.z 与情况 1) 中的 texture(DepthStencilTexture ,uv).r 相同,或者换句话说,存储在 DepthStencilTexture 中的深度相同。这是真的吗? gl_FragCoord.z 是从当前绑定的DEPTH_STENCIL_ATTACHMENT 中读取的,还带有glDisable(GL_DEPTH_TEST) 和glDepthMask(GL_FALSE) 吗?
【问题讨论】:
标签: opengl fbo deferred-shading