OpenGL, 圖像座標系下z值轉深度值計算

翻譯:
Real depth in OpenGL / GLSL - Before I Forget…
有一個需求:用openGL做球形貼圖。需要前後移動相機觀測球體,當相機位置超出球體時看到的內容從球體內表面變成球體外表面。
方案一:超出時,計算哪些片段屬於前半球,不要渲染這些片段;
方案二:在片段着色器用深度值判斷;

首先看一下這個公式.

A   = -(zFar + zNear) / (zFar - zNear);
B   = -2*zFar*zNear / (zFar - zNear);

A 和B分別是視錐體透視投影(perspective)的投影矩陣的3行3列(3,3)和4列(3,4)。
通常線性照相機模型最後Project矩陣左乘頂點向量後gl_position值變成:

[...,..., Az+B, -z]

然後頂點shader跑完,openGL自動做透視劃分:
gl_position=vec4(x,y,z,w);out=(x/wy/wz/w) gl\_position =vec4(x,y,z,w); \\ out = \begin{pmatrix} x /w \\ y / w \\ z / w \end{pmatrix}
那麼zn=z/wz_n=z/w 就是點在vertex Shader最終輸出的gl_position 做透視劃分後的向量的z值.
所以znz_n的計算公式爲:

z_n = -(Az_e + B) / z_e; // z_n in [-1, 1]
z_b = 0.5
z_n + 0.5; // z_b in [0, 1]

z_b 是把透視劃分後的點從[-1,1]映射到[0,1](深度緩存值範圍).

以上是片段着色器每個點的深度值計算原理。在片段着色器clip一下透明值,就可以解決繪製一個物體時被遮擋的問題。例如我只要視野內球體內部.其截面法線垂直於我的視線:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章