我想在不使用布尔运算(联合、差异等)的情况下在WebGL
( fragment shaders
/ ) 中剪切一个对象(一个框)。vertex shaders
我想使用着色器来隐藏对象的某些部分(因此它不是真正的“真正的剪切”,因为它只是隐藏了对象)。
编辑
我想在不使用布尔运算(联合、差异等)的情况下在WebGL
( fragment shaders
/ ) 中剪切一个对象(一个框)。vertex shaders
我想使用着色器来隐藏对象的某些部分(因此它不是真正的“真正的剪切”,因为它只是隐藏了对象)。
编辑
首先,确保顶点着色器通过世界空间中的位置(或者更确切地说,您希望剪辑相对于哪个坐标空间进行固定)传递到片段着色器。示例(根据内存编写,未经测试):
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();
如果您不熟悉使用多个程序,这几乎就像使用一个程序一样,只是您只需执行一次所有设置(编译、附加、链接)。需要注意的主要是每个程序都有自己的制服,因此您必须分别为每个程序初始化制服。