ShadowMapping的技术原理

浪子不回头ぞ 提交于 2019-12-04 06:46:03

    在计算机视觉中实现三维物体阴影比较出名的一种方案是ShadowMapping,它的基本思路如下:

    第一步:

    1. 创建camera:创建一个位于光源位置的camera,叫做lightCamera。

    2. 创建shadowMap:创建一个有深度纹理的FBO,这个FBO只需要存储深度纹理,不需要颜色缓存区。深度纹理的长宽我们可以根据不同的应用场景自定义,不过在大多数情况下都是和viewPort的长宽一致。

    3. 渲染场景深度到shadowMap: 将上一步创建的FBO设置为当前的FrameBuffer,然后从lightCamera渲染场景。

    第二步:

    1. 创建camera: 创建一个用于正常场景渲染camera,叫做normalCamera。

    2. 正常渲染场景:从normalCamera渲染场景,并且把shadowMap传递到fragment shader。

    3. 顶点转换:顶点坐标在vertext shader需要做两次转换:

        (1): 使用正常渲染场景中的MVP矩阵对顶点做一次转换,然后将新的顶点通过gl_position输出。

        (2): 使用光源位置渲染场景的MVP矩阵对顶点做一次转换,将这个新的顶点命名为lightCoordinate,然后将lightCoordinate通过varying输出。

    4. 将lightCoordinate转换为纹理坐标:在fragment shader中lightCoordinate的坐标范围为[-1, 1],但是纹理坐标的范围在[0,1]之间。把lightCoordinate坐标转换为纹理坐标空间需要用一个特别的矩阵乘以lightCoordinate,然后得到新的[x,y,z,w],将x,y视为纹理坐标。这个特别的矩阵如下: 

                                                        0.5,0.0,0.0,0.0,

                                                        0.0,0.5,0.0,0.0,

                                                        0.0,0.0,0.5,0.0,

                                                        0.0,0.0,0.0,1.0

     5. 深度比较:根据上一步得到的纹理坐标从shadowMap中取得深度值shadowZ,把shadowZ和lightCoordinate的Z值做比较,如果shadowZ比较小,就可以认为当前的位置处于阴影中。

     以上只是原理介绍,在我的github中有专门的demo实现,地址如下:shadowMapping,有兴趣的同学可以参考下,希望对你有所帮助。

 

 

   

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!