我想在不使用布尔操作(联合,差异等)的情况下剪切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