◰GL-阴影贴图核心步骤
Posted itzyjr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了◰GL-阴影贴图核心步骤相关的知识,希望对你有一定的参考价值。
第一轮:在光源视角渲染场景
1.创建自定义帧缓冲区
glGenFramebuffers(1, &shadowBuffer);
2.创建并绑定阴影纹理,设置阴影贴图及参数
glGenTextures(1, &shadowTex);
glBindTexture(GL_TEXTURE_2D, shadowTex);
// specify a two-dimensional texture image
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,
screenW, screenH, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
// may reduce shadow border artifacts
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3.绑定帧缓冲区
glBindFramebuffer(GL_FRAMEBUFFER, shadowBuffer);
4.将深度信息附加到帧缓冲区的阴影纹理附件上
如果纹理对象的图像被附加到帧缓冲区,OpenGL将执行“渲染到纹理”,即深度信息都在阴影纹理中了,这样就可用纹理中的深度信息来判断点是否在阴影里。
// attach a level of a texture object as a logical buffer of a framebuffer object
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowTex, 0);
5.禁用颜色缓冲(即禁用颜色输出)
// GL_NONE:No color buffers are written
glDrawBuffer(GL_NONE);
6.启用深度测试
glEnable(GL_DEPTH_TEST);
7.在光照空间绘制两物体(一个遮挡另一个)
glDrawArrays(..one.);
glDrawArrays(..two.);
8.顶点着色器Ⅰ:正常输出经光照空间MVP矩阵变换后的坐标。
片段着色器Ⅰ:什么也不做。
因为深度测试是在片段着色器之后进行,Alpha测试->模板测试->深度测试。所以必须正常输出经MVP矩阵变换后的坐标。因为不需要上色,所以片段着色器1什么也不用做。
// 顶点着色器Ⅰ
gl_Position = shadowMVP * vec4(vertPos, 1.0);
// 片段着色器Ⅰ
void main(void)
第二轮:在相机视角渲染场景
1.中断帧缓冲
由于我们的帧缓冲不是默认帧缓冲,渲染指令将不会对窗口的视觉输出有任何影响。出于这个原因,渲染到一个不同的帧缓冲被叫做离屏渲染(Off-screen Rendering)。要保证所有的渲染操作在主窗口中有视觉效果,我们需要再次激活[默认帧缓冲],将它绑定到0。
// 切换回默认帧缓冲
glBindFramebuffer(GL_FRAMEBUFFER, 0);
2.激活#0纹理单元并绑定阴影纹理
此时就将带有深度信息的纹理复制到阴影纹理单元了。
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, shadowTex);
3.启用颜色缓冲区(即启用颜色输出)
// GL_FRONT:Only the front left and front right color buffers are written
glDrawBuffer(GL_FRONT);
4.构建两个MVP矩阵作为统一变量:一个是相机空间MVP矩阵,一个光照空间BMVP矩阵。
5.在相机空间绘制两物体(一个遮挡另一个)
6.顶点着色器Ⅱ:
[out] shadow_coord = shadowBMVP * vec4(vertPos, 1.0);
[out] gl_Position = proj_matrix * mv_matrix * vec4(vertPos, 1.0);
片段着色器Ⅱ:
in vec4 shadow_coord;
layout(binding = 0) uniform sampler2DShadow shadowTex;
main()
// 0:在阴影里,1:不在阴影里
float inShadow = textureProj(shadowTex, shadow_coord);
以上是关于◰GL-阴影贴图核心步骤的主要内容,如果未能解决你的问题,请参考以下文章