glClipPlane - webGL中是否有等价物?

时间:2014-03-25 07:40:41

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

我有一个3D网格。是否有可能在OpenGL中呈现截面视图(剪切),如glClipPlane

我正在使用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; 
}

2 个答案:

答案 0 :(得分:10)

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

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

更新

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

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

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

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

(其中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 
     

位于飞机定义的半空间内;不满足这一条件的点   不要躺在半空间里。

所以你要做的是,你添加制服,你通过它传递剪裁平面参数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;
    }
    /* ... */
}

答案 1 :(得分:2)

THREE.WebGLRenderer中支持three.js剪辑的较新版本(&gt; r.76)。有is an array property called clippingPlanes,您可以在其中添加自定义剪裁平面( if(action > 0){ return true; }else{ return false; } 实例)。

对于three.js,您可以查看以下两个示例:

1) WebGL clipping (代码库here on GitHub

2) WebGL clipping advanced (代码库here on GitHub

一个简单的例子

要向THREE.Plane添加剪裁平面,您可以执行以下操作:

renderer

Here a fiddle 来证明这一点。

您还可以通过向对象材质添加剪裁平面来剪切对象级别。为此,您必须将渲染器var normal = new THREE.Vector3( -1, 0, 0 ); var constant = 0; var plane = new THREE.Plane( normal, constant ); renderer.clippingPlanes = [plane]; 属性设置为true。

localClippingEnabled

注意:在r.77中,// set renderer renderer.localClippingEnabled = true; // add clipping plane to material var normal = new THREE.Vector3( -1, 0, 0 ); var constant = 0; var color = 0xff0000; var plane = new THREE.Plane( normal, constant ); var material = new THREE.MeshBasicMaterial({ color: color }); material.clippingPlanes = [plane]; var mesh = new THREE.Mesh( geometry, material ); 中的某些剪切功能已移至单独的THREE.WebGLRenderer班级,请检查here for reference in the three.js master branch