2016-12-27 67 views
0

我試圖在WebGL中模擬像glPolygonMode(GL_BACK, GL_LINE)這樣的東西。我可以使用模式LINES而不是TRIANGLES進行繪製,但我無法看到WebGL如何自動確定某個特定的細分是否朝後,因爲細分不會面向任何位置。根據「法線」剔除線條和點

爲了解決這個問題,我將原始三角形的法線傳遞給着色器。在通常的模型視圖變換(旋轉,縮放,平移)下計算變換很容易;那麼我只是通過逆的轉置來乘以法線。根據正常點進入屏幕還是外出,我可以決定是否剔除線段。

但是,這是不完全正確的。我還需要投影矩陣的逆矩陣來考慮透視失真。

我使用CanvasMatrix4.frustum()CanvasMatrix4.ortho()函數來獲得投影矩陣。是否有公式或函數可用於它們的反轉?

或者,有沒有更好的方法來模擬像glPolygonMode(GL_BACK, GL_LINE)這樣的東西?

+0

您可能喜歡[此解決方案](http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/) – gman

+0

我嘗試了一種類似於重心的解決方案,但在使用胖線時,我看不出它像'GL_LINE'多邊形模式。它看起來像部分滿臉,但很奇怪。 – user2554330

回答

1

的發送三角形的其他頂點作爲額外屬性的想法似乎工作。

這是頂點着色器的關鍵部分。屬性aPos是在線段中使用的頂點的位置; v1是繞着三角形的下一個頂點,v2是之後的那個頂點。

我編輯了代碼,省略了燈光相關的東西。這可能不是最有效的實現,但它似乎工作。

attribute vec3 aPos; 
uniform mat4 mvMatrix; 
uniform mat4 prMatrix; 
attribute vec3 v1; 
attribute vec3 v2; 
varying float normz; 

void main(void) { 
    gl_Position = prMatrix * (mvMatrix * vec4(aPos, 1.)); 
    vec4 v1p = (prMatrix*(mvMatrix*vec4(v1, 1.))); 
    v1p = v1p/v1p.w - gl_Position/gl_Position.w; 
    vec4 v2p = (prMatrix*(mvMatrix*vec4(v2, 1.))); 
    v2p = v2p/v2p.w - gl_Position/gl_Position.w; 
    normz = v1p.x*v2p.y - v1p.y*v2p.x; // z component of cross product 
} 

在片段着色器,丟棄基於的normz符號片段。我用

if ((normz <= 0.) != front) discard; 

其中frontbool表明我是否要顯示前面與否。

-1

取三角形的面積。如果它是積極的,如果它是負數,則將其抽出。

+0

我不能在着色器中做到這一點,因爲他們從來沒有看到任何三角形。所以我需要在Javascript中完成所有的轉換和計算,並且在渲染每一幀的時候更新'ELEMENT_ARRAY_BUFFER'。這聽起來很慢。 – user2554330

+0

我想我也可以通過其他兩個頂點,然後計算投影后的法線...... – user2554330

0

如果使用WebGl擴展是一個選項,您可能需要查看OES_standard_derivatives。這個擴展是爲了解決你的透視校正問題的具體目的而引入的。根據WebGL Stats支持是相當通用的。

在你的主代碼庫,啓用此擴展名:

gl.getExtension("OES_standard_derivatives"); 

延長介紹dFdx和dFdy功能,讓你做這樣的前/後測試:

vec3 dx = dFdx(position); 
vec3 dy = dFdy(position); 
vec3 faceNormal = normalize(cross(dx, dy)); 
if (dot(normal, faceNormal) > 0.0) { 
    // Front facing 
}