本文共 2117 字,大约阅读时间需要 7 分钟。
在第二趟渲染中,视点在摄像机的位置,所以我们会得到一个不同的深度缓冲。两个缓冲都是需要的,一个用来保证物体渲染顺序,一个用来判断顶点是否在阴影内。 我们可以通过在第二趟渲染的vertex shader中传入两个WVP矩阵来做到这个。
向量gl_Position用作通常的渲染,另一个向量在光栅化阶段也被差值,每个fragment也有自己相应的值。 该向量的z值即为光源到该点的距离。该z值可以和shadow map中的深度值比较,决定该fragment是否在阴影内。
lighting_technique.h
class LightingTechnique : public Technique { public: ... void SetLightWVP(const Matrix4f& LightWVP); void SetShadowMapTextureUnit(unsigned int TextureUnit); ... private: GLuint m_LightWVPLocation; GLuint m_shadowMapLocation; ...
增加一个新的属性,用来表示光源位置作为视点的WVP矩阵。我们用texture unit 0表示通常的纹理,texture unit 1表示shadow map。
lighting.vs
#version 400 layout (location = 0) in vec3 Position; layout (location = 1) in vec2 TexCoord; layout (location = 2) in vec3 Normal; uniform mat4 gWVP; uniform mat4 gLightWVP; uniform mat4 gWorld; out vec4 LightSpacePos; out vec2 TexCoord0; out vec3 Normal0; out vec3 WorldPos0; void main() { gl_Position = gWVP * vec4(Position, 1.0); LightSpacePos = gLightWVP * vec4(Position, 1.0); TexCoord0 = TexCoord; Normal0 = (gWorld * vec4(Normal, 0.0)).xyz; WorldPos0 = (gWorld * vec4(Position, 1.0)).xyz; }
lighting.fs:58
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(gShadowMap, UVCoords).x; if (Depth < (z + 0.00001)) return 0.5; else return 1.0; }
上面这个shader函数用来计算阴影因子。
转载地址:http://mxall.baihongyu.com/