安卓demo 下载
上面着色器的意思是,将片元与光源的距离计算出来并拆解成4个部分在压缩存储到RGBA 4个色彩通道中。
· 上述着色器最大的变化是首先要对距离纹理进行基于投影贴图技术的纹理采样,然后将采样出的颜色值恢复成距离值(ZA),接着计算出实际距离值(ZB),最后根据ZA与ZB的关系决定片元是否在阴影中。
· 比较ZA与ZB的大小时加入了一个修正值3.0,此值一股需要根据具体情况进行调整、如果不加入修正值,场景绘制出来可能导致产生很严重的“自身阴影”问题.
转载请声明出处:http://blog.csdn.NET/xiaoge132/article/details/51458489
阴影贴图(Shadow mapping)
是在三维计算机图形中加入阴影的过程。阴影贴图的概念最初是由 Lance Williams 于 1978年在“在曲面上投射阴影”这篇论文中提出的。从那时开始,这种方法就已经用于场景预渲染、实时甚至是许多游戏设备以及高端电脑游戏中。在Pixar 的RenderMan 中就使用了阴影贴图技术,同样,在 玩具总动员 这样的游戏中也使用了这项技术。
像素与以纹理形式保存的光照深度缓冲区或者深度图像比较,通过这种方式计算像素是否处于光源照射范围之内,从而生成阴影。(引自维基百科)
原理:
阴影贴图是一种使用深度纹理来为渲染阴影提供解决方案的多通道计算。它的关键是,就是用投射光源代替最终视口来观察场景。通过移动视口到光源位置,可以观察到这个位置每个东西都是明亮的,因为从光的角度来看是没有阴影的。
从光源的角度将场景的深度渲染到一张深度缓冲区中,我们可以在场景中获得一张阴影或者无阴影的贴图,一张阴影贴图。
上图很好的解释了Shadow Mapping的原理
一 首先将摄像机设置到光源所在的位置(观察方向面对场景,此时叫摄像机观察矩阵为观察矩阵1”,同时设置合理的投影矩阵(这里称此矩阵为投影矩阵1)。
二 然后对与景进行第二次绘制.此次绘制将每个可以看见的片元(可以观察到指的是片元到光源间无遮挡)到光源的距离记录到一幅纹理图中的对应像素中,供后面的步骤使用。
三 接着将摄像机恢复到实际摄像机所处的位置,绘制场景。此次绘制时将前面步骤产生的纹理采用投影贴图的方式应用到场景中,进行投影贴图时采用的投影矩阵为投影矩阵1、观察矩阵为观察矩阵1.
四 绘制每个片元时,根据投影贴图纹理采样的结果换算出光源与此片元连线中距光源最近的片元距离(ZA),再计算出此片元距光源的实际距离(ZB)。若ZB〉ZA,则需要绘制的片元处于阴影中,采用阴影的颜色着色,否则此片兀不在阴影中,进行既定的光照着色。
距离纹理的生成:
就是对上述步骤一 步骤二的实现,纹理图的内容是通过讲摄像机放置到光源位置观察场景绘制出来的
看看其中片元着色器的代码 见frag_shadow.sh
阴影场景的绘制:
现在要将摄像机恢复到实际原来的位置,将前面步骤产生的纹理贴图应用到场景中.
我们改一下位置就可以得到了这个场景了
同时看下列的片元着色器frag.sh
· 比较ZA与ZB的大小时加入了一个修正值3.0,此值一股需要根据具体情况进行调整、如果不加入修正值,场景绘制出来可能导致产生很严重的“自身阴影”问题.
参考书籍:
OpenGL es游戏开发下卷