ShadowMapping的技术原理

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

    第一步:git

    1. 建立camera:建立一个位于光源位置的camera,叫作lightCamera。github

    2. 建立shadowMap:建立一个有深度纹理的FBO,这个FBO只须要存储深度纹理,不须要颜色缓存区。深度纹理的长宽咱们能够根据不一样的应用场景自定义,不过在大多数状况下都是和viewPort的长宽一致。缓存

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

    第二步:url

    1. 建立camera: 建立一个用于正常场景渲染camera,叫作normalCamera。.net

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

    3. 顶点转换:顶点坐标在vertext shader须要作两次转换:get

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

        (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,有兴趣的同窗能够参考下,但愿对你有所帮助。

相关文章
相关标签/搜索