简体   繁体   English

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

[英]How to cut an object using WebGL shaders?

I would like to cut an object (a box) in WebGL ( fragment shaders / vertex shaders ) without using Boolean operations (union, difference, etc..). 我想在不使用布尔运算(联合,差异等等)的情况下在WebGLfragment shaders / vertex shaders )中剪切对象(框)。

I want to use shaders to hide some part of the object (so it is therefore not really a "real cuts" since it simply hides the object). 我想使用着色器隐藏对象的某些部分(因此它实际上不是“真正的剪切”,因为它只是隐藏了对象)。

EDIT 编辑

First, make sure that the vertex shader passes through to the fragment shader the position in world space (or rather, whichever coordinate space you wish the clipping to be fixed relative to). 首先,确保顶点着色器通过片段着色器传递到世界空间中的位置(或者更确切地说,您希望裁剪相对于哪个坐标空间)。 Example (written from memory, not tested): 示例(从内存中写入,未经测试):

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;
}

And in your fragment shader, you can then discard based on an arbitrary plane, or any other kind of test you want: 在片段着色器中,您可以根据任意平面或任何其他类型的测试进行丢弃:

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 = ...;
}

Note that using discard may cause a performance reduction as the GPU cannot optimize based on knowing that all fragments will be written. 请注意,使用discard可能会导致性能下降,因为GPU无法在知道将写入所有片段的情况下进行优化。

Disclaimer: I haven't researched this myself, and only just wrote down a possible way to do it based on the 'obvious solution'. 免责声明:我自己没有对此进行过研究,只是根据“明显的解决方案”写下了一种可行的方法。 There may be better ways I haven't heard of. 可能有更好的方法我没有听说过。


Regarding your question about multiple objects: There are many different ways to handle this — it's all custom code in the end. 关于你关于多个对象的问题:有许多不同的方法可以解决这个问题 - 它最终都是自定义代码。 But you certainly can use a different shader for different objects in your scene, as long as they're in different vertex arrays. 但是你可以为场景中的不同对象使用不同的着色器,只要它们位于不同的顶点数组中即可。

    gl.useProgram(programWhichCuts);
    gl.drawArrays();
    gl.useProgram(programWhichDoesNotCut);
    gl.drawArrays();

If you're new to using multiple programs, it's pretty much just like using one program except that you do all the setup (compile, attach, link) once. 如果您不熟悉使用多个程序,那么就像使用一个程序一样,除了您执行所有设置(编译,附加,链接)之外。 The main thing to watch out for is each program has its own uniforms , so you have to initialize your uniforms for each program separately. 需要注意的是, 每个程序都有自己的制服 ,所以你必须分别为每个程序初始化你的制服。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM