three.js - glClipPlane - webGL 中有等效的吗?

标签 three.js opengl-es-2.0 webgl fragment-shader vertex-shader

我有一个 3D 网格。是否有可能像 OpenGL 中的 glClipPlane 一样渲染剖面 View (裁剪)?

我使用的是 Three.js r65。

我添加的最新着色器是:
片段着色器:

uniform float time;
uniform vec2 resolution; 
varying vec2 vUv; 
void main( void ) 
{ 
vec2 position = -1.0 + 2.0 * vUv; 
float red = abs( sin( position.x * position.y + time / 2.0 ) ); 
float green = abs( cos( position.x * position.y + time / 3.0 ) ); 
float blue = abs( cos( position.x * position.y + time / 4.0 ) ); 
if(position.x > 0.2  && position.y > 0.2 ) 
{  
discard; 
 } 
gl_FragColor = vec4( red, green, blue, 1.0 ); }


顶点着色器:

varying vec2 vUv;
void main() 
{ 
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); 
gl_Position = projectionMatrix * mvPosition; 
}

最佳答案

不幸的是,在指定 WebGL 的 OpenGL-ES 规范中,没有裁剪平面,并且顶点着色器阶段缺少 gl_ClipDistance 输出,而平面裁剪是在现代 OpenGL 中实现的。

但是,您可以使用片段着色器来实现逐片段裁剪。在片段着色器中,根据您的剪辑平面集测试传入片段的位置,如果片段未通过测试,则丢弃它。

更新

让我们看看OpenGL固定功能管线中如何定义裁剪平面:

void ClipPlane( enum p, double eqn[4] );

The value of the first argument, p, is a symbolic constant,CLIP PLANEi, where i is an integer between 0 and n − 1, indicating one of n client-defined clip planes. eqn is an array of four double-precision floating-point values. These are the coefficients of a plane equation in object coordinates: p1, p2, p3, and p4 (in that order). The inverse of the current model-view matrix is applied to these coefficients, at the time they are specified, yielding

p' = (p'1, p'2, p'3, p'4) = (p1, p2, p3, p4) inv(M)

(where M is the current model-view matrix; the resulting plane equation is unde- fined if M is singular and may be inaccurate if M is poorly-conditioned) to obtain the plane equation coefficients in eye coordinates. All points with eye coordinates transpose( (x_e, y_e,z_e, w_e) ) that satisfy

(p'1, p'2, p'3, p'4)   x_e  ≥ 0
                      y_e 
                      z_e 
                      w_e 

lie in the half-space defined by the plane; points that do not satisfy this condition do not lie in the half-space.

所以你要做的是,添加制服来传递剪辑平面参数 p' 并在顶点和片段着色器之间添加另一个出/入变量对以传递顶点眼空间位置。然后在片段着色器中,您要做的第一件事是执行剪辑平面方程测试,如果未通过,则丢弃该片段。

在顶点着色器中

in  vec3 vertex_position;
out vec4 eyespace_pos;

uniform mat4 modelview;

void main()
{
    /* ... */
    eyespace_pos = modelview * vec4(vertex_position, 1);
    /* ... */
}

在片段着色器中

in vec4 eyespace_pos;

uniform vec4 clipplane;

void main()
{
    if( dot( eyespace_pos, clipplane) < 0 ) {
        discard;
    }
    /* ... */
}

关于three.js - glClipPlane - webGL 中有等效的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22628186/

相关文章:

android - eglCreateWindowSurface 因 java.lang.IllegalArgumentException 而失败

performance - 如何减少浏览器中 Three.js CPU/GPU 使用率

javascript - Three.js 根据坐标定位对象

javascript - 将动画时序与数据同步(ThreeJS)

javascript - Three.js - 仅来自 THREE.FilmPass() 的噪声动画

javascript - Three.js color.setHex 在组中的所有网格上

OpenGL 相当于 OpenGL ES 2.0 的扩展 GL_EXT_shader_framebuffer_fetch

opengl-es - OpenGL ES 2.0 中的多 channel 着色器

javascript - webgl中的多个对象

three.js - A-Frame 中是否有最大视频纹理分辨率?