glClipPlane - webGL中是否有等价物?

use*_*784 2 webgl vertex-shader fragment-shader opengl-es-2.0 three.js

我有一个3D网格.是否有可能像glClipPlaneOpenGL 一样渲染截面视图(剪切)?

我正在使用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 ); }
Run Code Online (Sandbox Code Playgroud)


顶点着色器:

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

dat*_*olf 10

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

但是,您可以使用片段着色器来实现每片段剪辑.在片段着色器中测试传入片段相对于剪辑平面集的位置,以及片段是否未通过测试discard.

更新

让我们看一下如何在固定功能管道OpenGL中定义剪裁平面:

void ClipPlane( enum p, double eqn[4] );
Run Code Online (Sandbox Code Playgroud)

第一个参数p的值是符号常量CLIP PLANEi,其中i是0到n-1之间的整数,表示n个客户端定义的剪裁平面之一.eqn 是一个包含四个双精度浮点值的数组.这些是对象坐标中的平面方程的系数:p1,p2,p3和p4(按此顺序).当前模型 - 视图矩阵的逆矩阵在它们被指定时应用于这些系数,从而产生

p' = (p'1, p'2, p'3, p'4) = (p1, p2, p3, p4) inv(M)
Run Code Online (Sandbox Code Playgroud)

(其中M是当前的模型 - 视图矩阵;如果M是奇异的,则得到的平面方程是未定义的,如果M条件很差,则可能是不准确的)以获得眼睛坐标中的平面方程系数.具有眼睛坐标的所有点转置((x_e,y_e,z_e,w_e))满足

(p'1, p'2, p'3, p'4)  ? x_e ? ? 0
                     ? y_e ?
                     ? z_e ?
                     ? w_e ?
Run Code Online (Sandbox Code Playgroud)

位于飞机所定的半空间内; 不满足这种条件的点不在半空间中.

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

在顶点着色器中

in  vec3 vertex_position;
out vec4 eyespace_pos;

uniform mat4 modelview;

void main()
{
    /* ... */
    eyespace_pos = modelview * vec4(vertex_position, 1);
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

在片段着色器中

in vec4 eyespace_pos;

uniform vec4 clipplane;

void main()
{
    if( dot( eyespace_pos, clipplane) < 0 ) {
        discard;
    }
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)