標籤:opengl shadow2dproj texture2d shadow2dprojext ios glsl
一.shadow2DProjEXT函數需要傳入一張深度紋理和一個點的座標(4維)
1.這裡首先注意的是這張紋理必須使用採樣器類型為sampler2DShadow才可以,直接使用sampler2D是不行的,會出錯。
2.深度紋理必須設定正確的格式GL_DEPTH_COMPONENT,另外要指定相應的比較函數,可以通過glTexParameteri來設定GL_TEXTURE_COMPARE_FUNC_EXT為GL_LEQUAL,GL_TEXTURE_COMPARE_MODE_EXT為GL_COMPARE_REF_TO_TEXTURE_EXT
3.傳入的座標是4維的(x,y,z,w),shadow2DProjEXT函數內部會這樣做
shadow2DProjEXT(depthTexture, shadowCoord);其實是分兩步,第一步會取出真正的紋理座標即shadowCoord.xy / shadowCoord.w並存depthTexture中對應位置取出相應的深度值,相當於執行float depth = texture2D(depthTexture,shadowCoord.xy/shadowCoord.w)。第二步則是對紋理中的深度值與座標中的深度值進行比較紋理中的深度值就是depth,而座標中的深度值要通過計算:float depth1 = shadowCoord.z / shadowCoord.w,然後將depth 與depth1做比較。
4.返回值問題,此函數的返回值為0或者1,若depth < depth1 則返回0表示深度測試未通過,反之為1表示深度測試通過。
二、上面計算時有一點需要注意,就是第三步的時候,在進行紋理座標計算和座標中的深度值計算時要注意shadowCoord是經過轉換後的座標,這裡的轉換後的意思是必須將shadowCoord的x,y,z由[-1,1]轉換到[0,1],所以通常在實現的時候直接在mvp矩陣的前面乘上一個位移矩陣,
bias = 0.5, 0.0, 0.0, 0.5
0.0,0.5, 0.0,0.5
0.0, 0.0,0.5,0.5
0.0, 0.0,0.0,1.0
這樣bias * (x,y,z,w),然後在除掉第四個分量之後就是(x +1)*0.5,(y+1)*0.5,(z+1)*0.5,這樣就實現了轉換。
但是由於opengl的矩陣是列優先的,所以我們在進行矩陣設定的時候要把矩陣進行轉置才可以,
bias =
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.5, 0.5,0.5,1.0
這樣就ok了。
在通常的過程中我們唔需要考慮行列主序的問題,因為我們計算得到的矩陣(比如通過lookAt,或者glm的相關函數得到的矩陣)與shader中需要的格式是一致的,所以我們傳入就可以使用,只有一種情況下我們需要考慮矩陣的列主序或者行主序關係,那就是將GLSL矩陣放入自訂的記憶體塊是,當將矩陣傳遞到uniform塊中式,就需要考慮這個問題,例如上面,我們自己寫了一個矩陣儲存在自訂的記憶體塊中,所以我們向shader中傳遞的時候就要進行行列轉置,這樣才能正確的使用矩陣。
ios平台中glsl中shadow2DProjEXT函數的簡單說明以及變換矩陣的小注意點