Phi*_*ldo 9 opengl glsl shadow-mapping
我所在的快速背景(确保我们在同一页面上,如果我失踪/假设有些愚蠢的话,进行健全检查):
这是我目前正在做的事情:
在我最终渲染过程的片段着色器(实际计算最终碎片值的那个)中,我从光源的角度来看传递的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;
Run Code Online (Sandbox Code Playgroud)
现在我已经拥有了这个紫外线,我可以从光的pov中获得深刻的"深度"
float depFromLightPOV = texture2D(shadowMap, UVinShadowMap).r;
Run Code Online (Sandbox Code Playgroud)
并将其与当前片段的位置与光线之间的距离进行比较:
float actualDistance = distance(texture2D(pos_tex, UV).xyz, lightPos);
Run Code Online (Sandbox Code Playgroud)
问题来自于"深度"存储在值0-1中,实际距离是世界坐标.我试图手动进行转换,但无法让它工作.在网上搜索,看起来像我应该这样做的方式是使用sampler2DShadow ......
所以这是我的问题:
我需要做什么改变才能使用shadow2D?shadow2D甚至做了什么?它只是或多或少的自动转换 - 从深度到世界的纹理?我可以使用相同的深度纹理吗?或者我需要以不同的方式渲染深度纹理?我将什么传递给shadow2D?我想检查片段的世界空间位置?或者和以前一样的紫外线?
如果所有这些问题都可以在一个简单的文档页面中得到解答,我很乐意,如果有人可以发布这个问题.但我发誓,我一直在寻找几个小时,找不到任何简单的说什么与shadow2D发生了什么!
谢谢!
And*_*man 43
从GLSL 1.30开始,没有特殊的纹理查找功能(无论如何名称)可供使用sampler2DShadow.GLSL 1.30+使用一系列重载,texture (...)这些重载是根据sampler传递的类型和坐标的尺寸选择的.
sampler2DShadow你需要做两件事:必须启用纹理比较,否则将得到未定义的结果
GL_TEXTURE_COMPARE_MODE = GL_COMPARE_REF_TO_TEXTURE?传递给的坐标texture (...)是3D而不是2D.新的第3个坐标是您要比较的深度值.
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 (...).回想一下,纹理坐标的前2个分量与始终相同,第3个是要测试的深度值.