5-3阴影映射

59 阅读1分钟

从光源透视图中渲染场景,并对最近的深度值进行采样,决定片段是否在阴影中

首先需要一张深度贴图,来计算阴影,将结果存储在纹理中

GLuint depthMapFBO; 
glGenFramebuffers(1, &depthMapFBO);

然后创建一个2D纹理,作为帧缓冲的深度缓冲

使用正交投影矩阵

GLfloat near_plane = 1.0f, far_plane = 7.5f; 
glm::mat4 lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);

创建一个视图矩阵来变换物体,使用glm::lookAt

glm::mat4 lightView = glm::lookAt(glm::vec3(-2.0f, 4.0f, -1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

结合提供逛空间的变换矩阵

接着使用着色器将变换到光空间中,然后将深度贴图渲染到片段着色器上

片段着色器中,在阴影中时是1.0,在阴影外是0.0,然后用diffuse和specular乘以阴影元素,还要把逛空间片段位置转换为NDC空间,并进行透视除法,检查currentDepth是否高于closetDepth,判断片段是否在阴影中

当产生阴影偏移时,对表面的深度进行微小偏移

当产生悬浮时,进行正面剔除

glCullFace(GL_FRONT); 
RenderSceneToDepthMap(); 
glCullFace(GL_BACK);

当采样过多时,将所有超出深度贴图的范围设为1.0,并将环绕模式设置为GL_CLAMP_TO_BORDER,投影z坐标大于1.0时,将shadow值设为0.0

PCF:在深度贴图中多次采样,产生柔和阴影