我想在WebGL
(fragment shaders
/ vertex shaders
)中剪切一个对象(一个框)而不使用布尔运算(并集,差异等等)。
我想使用着色器来隐藏对象的某些部分(因此它实际上不是“真正的剪切”,因为它只是隐藏了对象)。
修改
答案 0 :(得分:3)
首先,确保顶点着色器通过片段着色器传递到世界空间中的位置(或者更确切地说,您希望相对于剪辑固定的坐标空间)。示例(从内存中写入,未经测试):
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();
如果您不习惯使用多个程序,那么除了您完成所有设置(编译,附加,链接)之外,它几乎就像使用一个程序一样。需要注意的是每个程序都有自己的制服,所以你必须分别为每个程序初始化你的制服。