在計算機視覺中實現三維物體陰影比較出名的一種方案是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,有興趣的同窗能夠參考下,但願對你有所幫助。