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,有興趣的同窗能夠參考下,但願對你有所幫助。

相關文章
相關標籤/搜索