我有一个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;
}
答案 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。