1

我想在不使用布尔运算(联合、差异等)的情况下在WebGL( fragment shaders/ ) 中剪切一个对象(一个框)。vertex shaders

我想使用着色器来隐藏对象的某些部分(因此它不是真正的“真正的剪切”,因为它只是隐藏了对象)。

编辑

4

1 回答 1

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();

如果您不熟悉使用多个程序,这几乎就像使用一个程序一样,只是您只需执行一次所有设置(编译、附加、链接)。需要注意的主要是每个程序都有自己的制服,因此您必须分别为每个程序初始化制服。

于 2013-05-13T14:44:24.350 回答