2

我正在尝试实现一种阴影映射技术,但我遇到了一些问题才能使其正常工作。

我在灯光的位置有一个相机,这是我得到的阴影贴图。所有的顶点都乘以 each modelViewProjectionMatrix

相机灯的视图

我还有一个带有顶点世界位置的纹理。这是一个GL_RGBA32F纹理,因为所有的点都被每个点相乘ModelMatrix以得到世界空间中的点。

在此处输入图像描述

和着色器:

layout(binding=5) uniform sampler2D shadowMap;
layout(binding=6) uniform sampler2D positionMap;

in vec2 texcoord;
uniform mat uViewProjectionMatrix;

out vec4 color;

void main() {

   vec4 pos = texture(positionMap, texcoord);

   vec4 ShadowCoord = uViewProjectionMatrix * pos;
   ShadowCoord.xy = ShadowCoord.xy * vec2(0.5,0.5) + vec2(0.5,0.5);

   float a = texture(shadowMap, ShadowCoord.xy).z;
   color = vec4(a, a, a, 1.0);
}

输出(摄像头几乎在灯光的同一位置):

在此处输入图像描述

我只是想看看每个顶点的投影是否正确地从相机的位置开始,但看起来不是。这一切的重点是比较:

if ( texture(shadowMap, ShadowCoord.xy).z <  ( ShadowCoord.z-bias ) )

但它也不起作用。

我将不胜感激任何帮助。谢谢你。

4

1 回答 1

4

你错过了视角的鸿沟,你似乎完全忽略了深度范围。

这里的总体思路是ShadowCoord.xyz进入范围 [ 0 , 1 ](用于纹理查找和深度比较)。uViewProjectionMatrix * pos您的代码在(剪辑空间坐标)在 [ -1 , 1 ] 范围内的假设下运行,但除非您除以w(NDC 坐标),否则这并不能真正保证。

我会考虑这样的事情:

void main() {
  vec4 pos = texture(positionMap, texcoord);

  vec4 ShadowCoord = uViewProjectionMatrix * pos;
  ShadowCoord /= ShadowCoord.w;

  ShadowCoord.xyz = ShadowCoord.xyz * vec3 (0.5f, 0.5f, 0.5f) + vec2 (0.5f, 0.5f, 0.5f);

  float a = texture(shadowMap, ShadowCoord.xy).z;
  color = vec4(a, a, a, 1.0);
}

在此之后,ShadowCoord.xy将是要在阴影贴图中查找的纹理坐标,并且ShadowCoord.z将是从灯光的角度来看当前片段的深度。您可以ShadowCoord.z用于与采样深度进行比较。

事实上,您甚至可以考虑使用 asampler2DShadow来更有效地执行此操作。有关示例,请参阅此相关问题和答案

于 2014-12-13T18:50:43.607 回答