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