我正在尝试使用 Webgl2 实现点光源的阴影贴图。为此,我使用深度缓冲区的立方体贴图,从灯光位置渲染 6 轴对齐的视图。
在我用于渲染光照的片段着色器中,我使用以下行查询此立方体贴图:
vec3 lightToPos = lightPos-fragPos;
float closestDepth = texture(shadowMap, lightToPos).r;
请注意,lightPos 和 fragPos 在"视图"中是引用的,即:viewMat * worldMat * objPos
。在我遵循的教程中,这应该是世界位置(http://ogldev.atspace.co.uk/www/tutorial43/tutorial43.html(。现在,我看不出为什么我这样做的方式不起作用,因为无论它们的坐标以何种观点表示,两个位置的差异都应该相同,对吧?我得到的结果不是我所期望的,一切都在阴影中。我可能在其他地方犯了一个错误,但我想确保我理解它是如何工作的,并且错误不是来自这里。
它们的坐标以何种观点表示,两个位置的差异都应该相同,对吧?
不,他们不是。
考虑一个世界,其中光直接位于世界原点上方,"上方"表示在 +Y 方向上。这就是生成阴影贴图的方向。它是从世界空间产生的。
现在,考虑一下世界原点的相机。它向下看 -Z 轴,+Y 指向正上方。在这种情况下,相机空间和世界空间之间没有方向差异。因此,在这两种情况下,光照方向都是 (0, 1, 0(。
但是,如果将相机绕其观察轴旋转 90 度会发生什么?好吧,相对于世界,相机侧躺着。这意味着光线方向是 (1, 0, 0( 或 (-1, 0, 0(,具体取决于您旋转的方式。而且这个方向与世界空间方向不同,世界空间方向仍然是(0,1,0(。
是的,相对于世界,光没有移动。但相机做到了。因此,相机空间光方向的值不同于其世界空间光方向的值。
如果灯光位置和片段位置确实都在相机空间中,则减去它们将给出相机空间中光线的方向。如果影子地图真的是建在世界空间的,这个方向就完全没用了。