我想在不使用布爾操作(聯合,差異等)的情況下剪切WebGL
(fragment shaders
/vertex shaders
)中的對象(一個框)。如何使用WebGL着色器剪切對象?
我想使用着色器來隱藏對象的某些部分(所以它不是真正的「真正的切割」,因爲它只是隱藏對象)。
編輯
我想在不使用布爾操作(聯合,差異等)的情況下剪切WebGL
(fragment shaders
/vertex shaders
)中的對象(一個框)。如何使用WebGL着色器剪切對象?
我想使用着色器來隱藏對象的某些部分(所以它不是真正的「真正的切割」,因爲它只是隱藏對象)。
編輯
首先,確保頂點着色器經過對片段着色器在世界空間中的位置(或者說,兩者的座標您希望裁剪到相對於固定的空間)。例如(從內存中寫的,未測試):
varying vec3 positionForClip;
...
void main(void) {
...
vec4 worldPos = modelMatrix * vertexPosition;
positionForClip = worldPos.xyz/worldPos.w; // don't need homogeneous coordinates, so do the divide early
gl_Position = viewMatrix * worldPos;
}
而在你的片段着色器,你就可以放棄基於在任意平面,或任何其他類型的測試,你想:
varying vec3 positionForClip;
uniform vec3 planeNormal;
uniform float planeDistance;
...
void main(void) {
if (dot(positionForClip, planeNormal) > planeDistance) {
// or if (positionForClip.x > 10.0), or whatever
discard;
}
...
gl_FragColor = ...;
}
注那麼使用discard
可能會導致性能下降,因爲GPU無法在知道所有片段都將被寫入的情況下進行優化。
聲明:我自己沒有研究過這個,只是寫下了一個基於'明顯解決方案'的可能方法。可能有更好的方法,我沒有聽說過。
關於你提到的有關多個對象的問題:有很多不同的方式來處理這個問題 - 這是在結束時,所有的自定義代碼。但是當然,可以爲場景中的不同對象使用不同的着色器,只要它們位於不同的頂點數組中。
gl.useProgram(programWhichCuts);
gl.drawArrays();
gl.useProgram(programWhichDoesNotCut);
gl.drawArrays();
如果你是第一次使用多個程序,它幾乎就像使用一個程序除非你做所有的設置(編譯,連接,鏈路)一次。要注意的主要是每個程序都有自己的制服,所以你必須分別爲每個程序初始化你的制服。
性能下降是由丟棄還是由每個片段計算出來的dotProduct檢查引起的,儘管它們中的一部分是需要的?設置不透明度爲0是一種更有效的方式來實現這一點,或者它是相同的? (我對着色邏輯比較陌生) – 2014-03-03 23:54:47
@konpsych任何包含'discard'語句的着色器[可能不適合某些優化](http://www.opengl.org/wiki/Early_Fragment_Test)。您不能在混合中使用透明度,而是在此「切割」中使用透明度,因爲透明區域仍會寫入深度緩衝區,可能會導致以後的幾何圖形不能被繪製。 – 2014-03-04 00:03:07
通過查看[這個項目](http://open-3d-viewer.googlecode.com/svn/trunk/web/index.html)的透明度似乎工作得很好,我很確定它使用着色器,特別是第一個功能[這裏](https://code.google.com/p/open-3d-viewer/source/browse/trunk/web/scripts/shaders.txt) – 2014-03-05 20:06:28
我已回覆您的修改。 – 2013-05-25 14:26:23