阴影映射(Shadow Mapping):以光的位置为视角进行渲染,能看到的东西都将被点亮,看不见的一定是在阴影之中。
阴影映射
深度测试教程中,在深度缓冲里的一个值是摄像机视角下,对应于一个片段的一个0到1之间的深度值。从光源的透视图来渲染场景,并把深度值的结果储存到纹理中,储存在纹理中的所有这些深度值,叫做深度贴图(depth map)或阴影贴图。
第一步我们需要生成一张深度贴图(Depth Map)。深度贴图是从光的透视图里渲染的深度纹理,用它计算阴影。因为我们需要将场景的渲染结果储存到一个纹理中,我们将再次需要帧缓冲。
创建Shadow Mapping
首先为渲染的深度贴图创建一个帧缓冲对象:
GLuint depthMapFBO; |
然后,创建一个2D纹理,提供给帧缓冲的深度缓冲使用:
const GLuint SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024; |
生成深度贴图不太复杂。因为我们只关心深度值,我们要把纹理格式指定为GL_DEPTH_COMPONENT
。我们还要把纹理的高宽设置为1024
,这是深度贴图的分辨率。
把我们把生成的深度纹理作为帧缓冲的深度缓冲:
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); |
我们需要的只是在从光的透视图下渲染场景的时候深度信息,所以颜色缓冲没有用。然而,不包含颜色缓冲的帧缓冲对象是不完整的,所以我们需要显式告诉OpenGL我们不适用任何颜色数据进行渲染。我们通过将调用glDrawBuffer
和glReadBuffer
把读和绘制缓冲设置为GL_NONE
来做这件事。
合理配置将深度值渲染到纹理的帧缓冲后,我们就可以开始第一步了:生成深度贴图。两个步骤的完整的渲染阶段,看起来有点像这样:
// 1. 首选渲染深度贴图 |
这段代码隐去了一些细节,但它表达了阴影映射的基本思路。这里一定要记得调用glViewport。因为阴影贴图经常和我们原来渲染的场景(通常是窗口分辨率)有着不同的分辨率,我们需要改变视口(viewport)的参数以适应阴影贴图的尺寸。如果我们忘了更新视口参数,最后的深度贴图要么太小要么就不完整。
- 本文标题:OpenGL-4 阴影
- 创建时间:2023-08-23 09:57:01
- 本文链接:2023/08/23/note/Framework/OpenGL/opengl_shadow/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!