首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >glsl sampler2DShadow和shadow2D澄清

glsl sampler2DShadow和shadow2D澄清
EN

Stack Overflow用户
提问于 2014-03-15 04:49:50
回答 1查看 18.6K关注 0票数 14

快速了解我所处的位置(以确保我们在同一页,并检查我是否遗漏了/假设有什么愚蠢之处):

  • 目标:我想用阴影渲染我的场景,使用延迟照明和阴影地图。
  • 挣扎:找到关于如何使用shadow2D和sampler2DShadow的清晰和一致的文档。

以下是我目前正在做的事情:

在我的最后呈现通行证的片段着色器(实际计算最终帧值的那个)中,我从光线的角度获得了来自pass的MVP矩阵,来自所述pass的深度纹理(也称为“阴影映射”),以及来自我的几何缓冲区的位置/正常/颜色纹理。

据我所知,我需要找到阴影地图的UV --当前碎片的位置对应于什么。我这样做的方法如下:

代码语言:javascript
运行
复制
//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;

现在我有了这个紫外线,我就可以从光的角度得到“深度”了。

代码语言:javascript
运行
复制
float depFromLightPOV = texture2D(shadowMap, UVinShadowMap).r;

并将其与当前碎片的位置与光线之间的距离进行比较:

代码语言:javascript
运行
复制
float actualDistance = distance(texture2D(pos_tex, UV).xyz, lightPos);

问题在于“深度”存储在值0-1中,而实际距离是在世界坐标中。我试过手动完成转换,但没能让它正常工作。在网上搜索时,我应该用的方式是用sampler2DShadow.

,所以我的问题是:

我需要做哪些更改来代替使用shadow2D?shadow2D到底是做什么的?这只是一种从深度到世界的自动转换纹理吗?我能用同样的深度纹理吗?还是我需要用不同的方式渲染深度纹理?我应该把什么传递给shadow2D?我要检查的碎片的世界空间位置?还是和以前一样的紫外线?

如果所有这些问题都能在一个简单的文档页面中得到回答,我希望有人能把这些问题发出去。但我发誓,我已经搜索了几个小时,找不到任何简单地说出shadow2D到底是怎么回事的东西!

谢谢!

EN

Stack Overflow用户

回答已采纳

发布于 2014-03-15 16:28:56

首先,您使用的是什么版本的GLSL?

从GLSL1.30开始,没有特殊的纹理查找函数(无论如何都是名称)用于sampler2DShadow。GLSL 1.30+使用大量的texture (...)重载,这些重载是根据传递的sampler类型和坐标的尺寸选择的。

其次,如果您确实使用了sampler2DShadow,您需要做两件不同的事情:

  1. 必须启用纹理比较,否则将得到未定义的结果。

代码语言:javascript
运行
复制
- `GL_TEXTURE_COMPARE_MODE` = `GL_COMPARE_REF_TO_TEXTURE​`

  1. 传递给texture (...)的坐标是3D的,而不是2D的。新的第三坐标是你将要比较的深度值。

最后,您应该了解texture (...)在使用sampler2DShadow时返回的内容。

如果此比较通过,texture (...)将返回1.0,如果失败则返回0.0。如果在深度纹理上使用GL_LINEAR纹理筛选器,则texture (...)将使用深度纹理中最接近的4个深度值执行4个深度比较,并返回一个介于1.00.0之间的值,以了解通过/失败的样本数。

这是正确的方法来做硬件抗混叠阴影映射。如果您尝试在sampler2D中使用常规的GL_LINEAR并自己实现深度测试,那么您将得到一个平均深度返回和一个布尔传递/失败结果,而不是上面描述的sampler2DShadow的行为。

至于从一个世界空间位置获得一个深度值来测试,你是在正确的轨道上(尽管你忘记了透视部分)。

要从世界空间位置产生深度,必须做三件事:

  1. 将世界-空间位置乘以你的(光)投影和视图矩阵。
  2. 将结果坐标除以其W组件
  3. 将结果(将在-1,1)范围内的结果偏差到0,1

最后一步假设您使用的是默认深度范围..。如果您没有调用glDepthRange (...),那么这将有效。

步骤3的最终结果既是,也是深度值(R)和纹理坐标 (ST),用于查找深度地图。这样就可以将这个值直接传递给texture (...)。回想一下,纹理坐标的前两个分量和往常一样,第三个是要测试的深度值。

票数 57
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22419682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档