我在哪里的快速背景(以确保我们在同一页上,并且在我缺少/假设有些愚蠢的情况下进行健全检查):
这是我目前正在做的事情:
在我最终渲染过程的片段着色器(实际计算最终碎片值的那个)中,我从光的角度来看传递的MVP矩阵,来自所述传递的深度纹理(又名) "阴影贴"),以及几何缓冲区中的位置/法线/颜色纹理。
据我所知,我需要找到当前片段位置对应的阴影贴图的UV。我通过以下方式做到这一点:
//Bring position value at fragment (in world space) to screen space from lights POV
vec4 UVinShadowMap = (lightProjMat * lightViewMat * vec4(texture(pos_tex, UV).xyz,1.0)).xy;
//Convert screen space to 'texture space' (from -1to1 to 0to1)
UVinShadowMap = (UVinShadowMap+1)/2;
现在,我已经拥有了这种紫外线,我可以获得深刻的感受'来自光明的pov
float depFromLightPOV = texture2D(shadowMap, UVinShadowMap).r;
并将其与当前片段的位置与光线之间的距离进行比较:
float actualDistance = distance(texture2D(pos_tex, UV).xyz, lightPos);
问题来自于这种深度'存储在值0-1中,实际距离在世界坐标中。我已尝试手动进行转换,但无法使其正常工作。在网上搜索,看起来像我应该这样做的方式是使用sampler2DShadow ......
所以这是我的问题:
我需要做哪些更改才能使用shadow2D? shadow2D甚至做了什么?它只是或多或少的自动转换 - 从深度到世界的纹理?我可以使用相同的深度纹理吗?或者我需要以不同的方式渲染深度纹理?我将什么传递给shadow2D?我想检查片段的世界空间位置?或者和以前一样的紫外线?
如果所有这些问题都可以在一个简单的文档页面中得到解答,那么如果有人能够发布这些问题,我会很高兴。但是我发誓我已经找了好几个小时,找不到任何简单说出shadow2D发生了什么的事情!
谢谢!
答案 0 :(得分:41)
从GLSL 1.30开始,没有特殊的纹理查找功能(无论如何名称)与sampler2DShadow
一起使用。 GLSL 1.30+使用texture (...)
的一堆重载,这些重载是根据传递的sampler
类型和坐标的尺寸选择的。
sampler2DShadow
,你需要做两件事:必须启用纹理比较,否则您将获得未定义的结果
GL_TEXTURE_COMPARE_MODE
= GL_COMPARE_REF_TO_TEXTURE
您传递给texture (...)
的坐标是3D而不是2D。新的第3个坐标是您要比较的深度值。
texture (...)
时<{1}}返回的内容:如果此比较过去,sampler2DShadow
将返回 1.0 ,如果失败则会返回 0.0 。如果您在深度纹理上使用texture (...)
纹理滤镜,那么GL_LINEAR
将使用深度纹理中最近的4个深度值执行4次深度比较,并在之间的某处返回值 1.0 和 0.0 ,以了解通过/失败的样本数量。
这是对阴影贴图进行硬件消除锯齿的正确方法。如果您尝试使用常规texture (...)
和sampler2D
并自己实施深度测试,则会获得单个平均深度回归和布尔通过/失败结果,而不是上面针对{{1}所述的行为}。
至于从世界空间位置获取深度值进行测试,你走在正确的轨道上(虽然你忘了透视师)。
GL_LINEAR
组件 最后一步假设您使用的是默认深度范围...如果您尚未调用sampler2DShadow
,那么这将有效。
步骤3的最终结果用作 深度值(W
)和纹理坐标< / strong>(glDepthRange (...)
)用于查找深度图。这样就可以将此值 直接 传递给R
。回想一下,纹理坐标的前2个分量与始终相同,第3个是要测试的深度值。