1

我正在尝试在我的游戏中实现阴影映射。您在下面看到的着色器会为游戏地图正确绘制阴影,但在地图上四处走动的所有模型都是完全黑色的。

这是一个屏幕截图:

我怀疑问题出在世界位置的计算上。gl_Vertex 不会以任何方式进行转换。因为地图是使用绝对世界坐标生成的,所以使用光照矩阵的变换会产生正确的相对位置,可用于执行阴影映射。

但是,我的 3D 模型都非常接近原点。因此,如果它们的坐标使用光照矩阵进行了简单的转换,它们很可能永远不会被点亮。

我想知道是否会出现这种情况,如果是这样,我该如何解决。

这是我的顶点着色器:

#version 120
uniform mat4x4 LightMatrixValue;

varying vec4 shadowMapPosition;
varying vec3 worldPos;

void main(void)
{
    vec4 modelPos = gl_Vertex;
    worldPos=modelPos.xyz/modelPos.w;

    vec4 lightPos = LightMatrixValue*modelPos;

    shadowMapPosition = 0.5 * (lightPos.xyzw +lightPos.wwww);
    gl_Position = ftransform();
}

和片段着色器:可变vec4 shadowMapPosition;不同的 vec3 worldPos;

uniform sampler2D depthMap;
uniform vec4 LightPosition;

void main(void)
{
    vec4 textureColour = gl_Color;
    vec3 realShadowMapPosition = shadowMapPosition.xyz/shadowMapPosition.w;
    float depthSm = texture2D(depthMap, realShadowMapPosition.xy).r;

    if (depthSm < realShadowMapPosition.z-0.0001)
    {       
        textureColour = vec4(0, 0, 0, 1);
    }
    gl_FragColor= textureColour;
}
4

1 回答 1

2

我在这里写这个是因为它不适合上面,我希望它能解决你的问题。

对于渲染,一方面让您的模型与他们的模型矩阵来定位元素,另一方面,您拥有将模型转换为屏幕空间的视图投影矩阵。

为了创建阴影贴图(最简单的方法,我猜是您选择的方法),您从光源的视图渲染场景,因此您应用光源的视图投影矩阵,这将映射x,yz值到屏幕空间。xy值用于图像中的位置,用于z深度缓冲区测试和您在颜色缓冲区中写入的颜色(稍后用作阴影贴图)。

对于最终渲染,您将这个阴影贴图以及灯光的视图投影矩阵加载到着色器中。对于场景中的显示,您将相机的视图投影矩阵应用于顶点,对于阴影贴图查找,您将光的视图投影矩阵应用于顶点(就像您对阴影贴图的渲染所做的那样) . 当您将灯光视图投影矩阵应用于顶点时,您具有与阴影贴图通道中相同的映射,现在您只需将您的xy坐标转换为纹理坐标并查找存储的z值,您将其与计算的值进行比较。

将模型的世界位置转换为屏幕空间(从灯光的角度来看)

这部分通常在顶点或几何着色器中完成:

shadowMapPosition = matLightViewProjection * modelWoldPos;

这通常在片段着色器中完成:

shadowMapPosition = shadowMapPosition / shadowMapPosition.w ;

// Add an offset to prevent self-shadowing and moiré pattern
shadowMapPosition.z += 0.0005;

//lookup the stored z value
float distanceFromLight = texture2D(depthMap,shadowMapPosition.xz).z;

现在只需将 与 进行比较distanceFromLightshadowMapPosition.z 查看对象是否在阴影中。

因此,在您的第二遍中,您将再次执行阴影映射的步骤,只是您不绘制您计算的数据,而是将其与您在之前的遍中计算的数据进行比较。

于 2013-06-09T16:21:19.680 回答