Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用WebGL着色器剪切对象?_Javascript_3d_Webgl_Shader - Fatal编程技术网

Javascript 如何使用WebGL着色器剪切对象?

Javascript 如何使用WebGL着色器剪切对象?,javascript,3d,webgl,shader,Javascript,3d,Webgl,Shader,我想在WebGL(片段着色器/顶点着色器)中剪切一个对象(一个框),而不使用布尔运算(并集、差分等) 我想使用着色器隐藏对象的某些部分(因此它不是真正的“真正的切割”,因为它只是隐藏对象) 编辑首先,确保顶点着色器将世界空间中的位置(或者更确切地说,希望剪辑相对于哪个坐标空间固定)传递给片段着色器。示例(从内存写入,未测试): 在片段着色器中,可以基于任意平面或任何其他类型的测试放弃: varying vec3 positionForClip; uniform vec3 planeNormal;

我想在
WebGL
片段着色器
/
顶点着色器
)中剪切一个对象(一个框),而不使用布尔运算(并集、差分等)

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


编辑

首先,确保顶点着色器将世界空间中的位置(或者更确切地说,希望剪辑相对于哪个坐标空间固定)传递给片段着色器。示例(从内存写入,未测试):

在片段着色器中,可以基于任意平面或任何其他类型的测试放弃:

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检查造成的,该检查是为每个片段计算的,尽管部分片段需要?将“不透明度”(opacity)设置为0是实现这一点的更有效方法还是相同的方法?(我对着色器逻辑相对较新)@konsych任何包含
discard
语句的着色器。您不能在混合中使用透明度来代替此“剪切”,因为透明区域仍将写入深度缓冲区,可能会导致以后的几何体无法绘制。通过查看透明度,它似乎工作得很好,我非常确定它使用了着色器,特别是我刚才注意到的第一个功能,你为谷歌工作,因此你可能对这个项目更了解,但我发现,透明度较高的图层是首先绘制的,这就是考虑到structure@konpsychWebGL按原语在缓冲区中的显示顺序绘制原语。如果正在进行任何此类排序,则必须在应用程序中进行;这使得从透明表面获得一致的结果成为可能。
    gl.useProgram(programWhichCuts);
    gl.drawArrays();
    gl.useProgram(programWhichDoesNotCut);
    gl.drawArrays();