快速了解我所处的位置(以确保我们在同一页,并检查我是否遗漏了/假设有什么愚蠢之处):
以下是我目前正在做的事情:
在我的最后呈现通行证的片段着色器(实际计算最终帧值的那个)中,我从光线的角度获得了来自pass的MVP矩阵,来自所述pass的深度纹理(也称为“阴影映射”),以及来自我的几何缓冲区的位置/正常/颜色纹理。
据我所知,我需要找到阴影地图的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;
现在我有了这个紫外线,我就可以从光的角度得到“深度”了。
float depFromLightPOV = texture2D(shadowMap, UVinShadowMap).r;
并将其与当前碎片的位置与光线之间的距离进行比较:
float actualDistance = distance(texture2D(pos_tex, UV).xyz, lightPos);
问题在于“深度”存储在值0-1中,而实际距离是在世界坐标中。我试过手动完成转换,但没能让它正常工作。在网上搜索时,我应该用的方式是用sampler2DShadow.
,所以我的问题是:
我需要做哪些更改来代替使用shadow2D?shadow2D到底是做什么的?这只是一种从深度到世界的自动转换纹理吗?我能用同样的深度纹理吗?还是我需要用不同的方式渲染深度纹理?我应该把什么传递给shadow2D?我要检查的碎片的世界空间位置?还是和以前一样的紫外线?
如果所有这些问题都能在一个简单的文档页面中得到回答,我希望有人能把这些问题发出去。但我发誓,我已经搜索了几个小时,找不到任何简单地说出shadow2D到底是怎么回事的东西!
谢谢!
发布于 2014-03-15 16:28:56
首先,您使用的是什么版本的GLSL?
从GLSL1.30开始,没有特殊的纹理查找函数(无论如何都是名称)用于sampler2DShadow
。GLSL 1.30+使用大量的texture (...)
重载,这些重载是根据传递的sampler
类型和坐标的尺寸选择的。
其次,如果您确实使用了sampler2DShadow
,您需要做两件不同的事情:
- `GL_TEXTURE_COMPARE_MODE` = `GL_COMPARE_REF_TO_TEXTURE`
texture (...)
的坐标是3D的,而不是2D的。新的第三坐标是你将要比较的深度值。最后,您应该了解texture (...)
在使用sampler2DShadow
时返回的内容。
如果此比较通过,texture (...)
将返回1.0,如果失败则返回0.0。如果在深度纹理上使用GL_LINEAR
纹理筛选器,则texture (...)
将使用深度纹理中最接近的4个深度值执行4个深度比较,并返回一个介于1.0和0.0之间的值,以了解通过/失败的样本数。
这是正确的方法来做硬件抗混叠阴影映射。如果您尝试在sampler2D
中使用常规的GL_LINEAR
并自己实现深度测试,那么您将得到一个平均深度返回和一个布尔传递/失败结果,而不是上面描述的sampler2DShadow
的行为。
至于从一个世界空间位置获得一个深度值来测试,你是在正确的轨道上(尽管你忘记了透视部分)。
要从世界空间位置产生深度,必须做三件事:
W
组件最后一步假设您使用的是默认深度范围..。如果您没有调用glDepthRange (...)
,那么这将有效。
步骤3的最终结果既是,也是、深度值(R
)和纹理坐标 (ST
),用于查找深度地图。这样就可以将这个值直接传递给texture (...)
。回想一下,纹理坐标的前两个分量和往常一样,第三个是要测试的深度值。
https://stackoverflow.com/questions/22419682
复制相似问题