阴影贴图 – 无法获得正确的纹理坐标

我试图为Spotlight实现阴影贴图,但是我无法让它们工作。 我已经validation了我的片段着色器正在获取阴影贴图纹理 。 我可以从传统的意义上对其进行抽样并将其显示在屏幕上,所以我知道它在那里。

我的问题

  • 实际上得到正确的坐标,并将该样本与当前深度值进行比较(不出现阴影)

如果我正确地理解了这个过程,那么当阴影贴图被创建时,我必须将相对于相机的空间中的碎片转换成光所占据的空间。

我正在使用延迟着色系统,所以我可以通过从位图贴图取样来轻松获取当前片段在空间中的位置。

以下是我如何确定一个像素是否在阴影中:

片段着色器:

in vec3 EyePos; in mat4 LightMVP; out vec4 fragColor; uniform SpotLight spotLight; uniform vec2 ScreenSize; uniform sampler2D PositionMap; uniform sampler2D ColorMap; uniform sampler2D NormalMap; uniform sampler2D SpecularMap; uniform sampler2D ShadowMap; // Takes in transformed position, samples shadow map, outputs shadow factor float float CalcShadowFactor(vec4 LightSpacePos) { vec3 ProjCoords = LightSpacePos.xyz / LightSpacePos.w; vec2 UVCoords; UVCoords.x = 0.5 * ProjCoords.x + 0.5; UVCoords.y = 0.5 * ProjCoords.y + 0.5; float z = 0.5 * ProjCoords.z + 0.5; float Depth = texture(ShadowMap, UVCoords).x; if (Depth < z + 0.00001) return 0.0; else return 1.0; } // Returns the texture coordinate vec2 CalcTexCoord() { return gl_FragCoord.xy / ScreenSize; } void main(void) { vec2 TexCoord = CalcTexCoord(); // Used for sampling from input texture maps vec4 WorldPos = texture2D(PositionMap, TexCoord); // Position in space // ... omitted texture sampling for diffuse, normals, specular, etc ... // vec4 LightSpace = (LightMVP) * WorldPos4; float ShadowFactor = CalcShadowFactor(LightSpace); fragColor = vec4(Color, 1.0) * CalcSpotLight(WorldPos.xyz, Normal, Specular, ShadowFactor); } 

matrixlightV和lightP是从场景的阴影贴图通过场景时光线使用的视图和投影matrix。

顶点着色器:

 #version 330 in vec4 vertex; uniform mat4 mMatrix; uniform mat4 pMatrix; uniform mat4 vMatrix; uniform mat4 lightV; uniform mat4 lightP; uniform vec3 eye; out vec3 EyePos; out mat4 LightMVP; void main() { EyePos = eye; mat4 worldMVP = pMatrix * vMatrix * mMatrix; LightMVP = lightP * lightV * mMatrix; gl_Position = worldMVP * vertex; } 

阴影贴图纹理(可视化)

在这里输入图像描述

渲染的场景

在这里输入图像描述


问题

我究竟做错了什么? 这个math看起来不对吗?

如果阴影贴图纹理的分辨率和宽高比与相机不同,是否重要? 在这种情况下,它是完全一样的。

如果没有什么不对,那么我该怎么debugging呢? 我试过只输出一个带阴影因子的vec4,但我得到的只是亮白色(因为它不是正确的采样)

如果有帮助,我一直在关注OGLDev的教程,所以我的延期着色系统和他们的类似,我的阴影贴图也是他们的(但是他们从来没有做过同时使用两者的教程)


更新

我设法强制一个解决scheme,但我不明白为什么它的工作,我不知道,如果它甚至是正确的解决scheme。

为了计算我的LightMVP mat4,我用相反的光视图matrix来多摄像机的投影matrix,然后将其传递到我的片段着色器中并乘以世界位置,世界位置从纹理位置图导出。

 LightMVP = (pMatrix) * inverse(lightV); vec4 LightSpace = (LightMVP) * WorldPos; 

这种方法有什么问题吗?