OGL(教程24)——阴影映射2

原文地址:http://ogldev.atspace.co.uk/www/tutorial24/tutorial24.html

背景知识:
原文地址:http://ogldev.atspace.co.uk/www/tutorial24/tutorial24.html

背景知识:
前一小结学习阴影映射背后的基本原理。也学习了如何把深度缓冲渲染到一张纹理,然后紧接着从深度缓冲采样并绘制到屏幕。本节我们将学习如何使用阴影映射图绘制影子。

我们知道阴影映射是一个双通道技术。第一次渲染是从灯光位置渲场景,让我们回忆下第一次渲染时,位置向量z分量发生了什么。

  1. 传入到顶点着色器中的顶点数据是定义在本地空间的。
  2. 顶点着色器把顶本地空间的位置,转换到裁剪空间,然后传入到管线。
  3. 光栅化器执行透视除法(位置向量除以w分量)。这个把位置向量从裁剪空间转换到NDC空间。NDC空间下的坐标xyz分量映射到[-1,1]范围。超出这个范围的被裁剪掉。
  4. 光栅化器把xy坐标映射帧缓冲的维度(比如800600,或者是1024768)。这个坐标是屏幕空间坐标。
  5. 光栅化器接收三角形三个顶点的屏幕坐标,然后进行插值。对每个像素创建一个唯一的坐标。z值依然是[-1,1]区间,它也被插值,所有每个像素有自己的深度。
  6. 由于第一个通道我们关闭了颜色写入。深度测试依然执行。为了比较当前像素的z值,和之前深度缓冲中的z值。如果新的z值小于取出的深度值,那么深度值被更新。
    这上面的处理过程中,我们从光源的视角计算深度值,并存储起来。第二次渲染,我们从摄像机的角度渲染,得到另外一个深度。但是我们需要两个深度——一个是用于正确把三角形显示在屏幕上,另外一个是检测像素是否在阴影内。使用的技巧是,在阴影映射时候维护两个位置向量,连个wvp矩阵。一个wvp矩阵是从光源位置,另外一个是从摄像机位置。顶点着色器接收的是顶点本地位置,但是输出两个向量:
  7. gl_Position,是使用摄像机WVP矩阵变换得到的位置
    2.一个平的向量,是通过光源位置的WVP矩阵变换得到。
    第一个向量会传入上面的处理过程(得到NDC空间),这个会被正常的光栅化过程使用。第二个向量,会被光栅器插值,每个像素着色器调用会提供自己的值。所以现在,对于每个物体像素,我们同样有了从光源出看到的裁剪坐标。很有可能这从两个视角看到的物理像素是不同的,但是在三角形中的位置是相同的。所有剩下的就是根据裁剪坐标从阴影映射深度图中取出深度。取出之后,我们比较当前点的深度和取出的深度值,如果取出的深度值小于当前的深度,那么说明此点在阴影内。

那么如何在片段着色器中使用裁剪空间坐标取出深度值呢?我们分为两个步骤:

  1. 因为片段着色器接收的是裁剪空间坐标,光栅器没有执行透视除法。但是这个可以手动做下,就是每个分量处于w分量,就得到了NDC空间。
  2. 我们知道NDC空间的xy都在-1到1之间。在上面的第4步骤,光栅器把NDC空间映射到屏幕空间,然后使用它们存储深度。我们将要采样深度,所以我们需要贴图的坐标在[0,1]区间。如果把[-1,1]映射到[0,1],我们将会得到和纹理坐标,这个和阴影贴图有相同的位置。比如x在NDC中为0,贴图的宽度为800。0在NDC中需要映射到贴图的坐标为0.5(因为他是-1和1的中点)。所以纹理坐标为0.5的映射到400.
  3. 把x和y映射到NDC空间,如下:
u = 0.5 * X + 0.5
v = 0.5 * Y + 0.5

猜你喜欢

转载自blog.csdn.net/wodownload2/article/details/83072915
今日推荐