对 three.js webgl_clipping_stencil 例子的理解

three.js 中的官方例子 webgl_clipping_stencil 着实费解,我在不同的时间 看了有三次以上, 才逐渐理解。

概括的讲:这个例子是在说 如何使用webgl stencil 模板缓存来对 几何网格进行裁切。对几何网格进行裁切有三种方式了:

  1. 自己开发切割工具,对网格进行切割,对网格的顶点进行分割,在切割边缘处新增顶点 和三角面
  2. shader 中的片元着色器绘制几何体,在片元着色器中进行裁切,csg技术(Constructive Solid Geometry)
  3. 使用模板缓存,就是例子中的方法
    第三种是最取巧的一种办法,没有像第一种 实实在在的修改了几何网格,也没有像第二种 涉及到 片元着色器的编写。

这个例子中,有意思的一点是,隐藏网格还可以这样做:

baseMat.colorWrite = false;

就是修改材质,不让材质写入颜色缓存。

模板缓存位于屏幕空间,createPlaneStencilGroup 方法 使用纽结几何网格对模板缓存进行写入,朝向相机的像素 减去1, 被向相机的像素 加上1;

createPlaneStencilGroup 中的代码

mat0.clippingPlanes = [ plane ];

用平面切割 纽结几何网格 后,会有这样的像素,只背向当前相机,没有朝向相机,这时该像素对应的模板缓存的值为 1;另外,还有很多这样的像素,既朝向相机,又背对着相机,这时该像素对应的模板缓存是0;
想象一下,有很多光线,从相机位置发出,射向屏幕的各个像素,对于这些射线,有点穿过 纽结几何网格 两次,有的没有穿过 纽结几何网格 零次,有点正好只穿过 纽结几何网格 一次,只穿过一次这种,对应的屏幕像素 的模板值就是 1 或者 -1

init方法中调用了 createPlaneStencilGroup() 之后,紧接着创建了平面网格,也是对模板缓存进行修改

const planeMat =
	new THREE.MeshStandardMaterial( {

		color: '#E91E63',
		metalness: 0.1,
		roughness: 0.75,
		clippingPlanes: planes.filter( p => p !== plane ),

		stencilWrite: true,
		stencilRef: 0,
		stencilFunc: THREE.NotEqualStencilFunc,
		stencilFail: THREE.ReplaceStencilOp,
		stencilZFail: THREE.ReplaceStencilOp,
		stencilZPass: THREE.ReplaceStencilOp,

	} );

stencilRef 和 stencilFunc 两个属性很重要,表示模板值不为0的通过测试,渲染到屏幕;平面网格如果始终把 1 写入模板,那么通常情况下,屏幕上显示出一个四边形(矩形投影到地面一般也是四边形)

渲染顺序在这里 非常非常重要,一定要保证 纽结几何网格 先 绘制,先修改模板缓存,平面网格 后 绘制,后修改模板缓存,这样相机始终可以看到 纽结几何网格 的截断面

如果,把代码中的

createPlaneStencilGroup( geometry, plane, i + 1 )

修改为

createPlaneStencilGroup( geometry, plane, i + 2 )

po.renderOrder = i + 1.1;

保持不变。
这样平面网格 先修改模板缓存,纽结几何网格 后修改模板缓存,显示的画面就完全乱套了

const clippedColorFront = new THREE.Mesh( geometry, material );
				clippedColorFront.castShadow = true;
				clippedColorFront.renderOrder = 6;
				object.add( clippedColorFront );

以上代码,注释掉后,只显示 三个截断面

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值