最近碰到一个需求,在进行整页滚屏时,需要从一个大场景转场到一个小场景,于是了解到 Three.js 中的剪裁
setScissor
函数原型:setScissor(x, y, width, height),这四个参数定义了一个矩形区域,称为裁剪区域或剪裁框
- x:剪裁框相对 canvas 画布左侧像素。默认值:0
- y:剪裁框相对 canvas 画布顶部像素。默认值:0
- width:剪裁框区域宽度。默认值:canvas 画布的宽度。
- height:剪裁框区域高度。默认值:canvas 画布的高度。
开启裁剪功能,必须在 renderer 进行如下设置,否则 setScissor 不起作用。于此同时,如果不使用 setScissor,也必须将其关闭,否则渲染会不符合预期
renderer.setScissorTest(true)
setScissor 定义了一个裁剪区域,在执行 render 的时候,剪裁框内的像素数据会被清除掉,剪裁框范围外的像素不受影响
实现场景切换
我们可以定义一个 sliderPos 变量记录场景切换时分屏位置。竖屏情况下,sliderPos 值等于 canvas 高度,简单代码如下
this.renderer.setScissor(0, this.height - this.sliderPos, this.width, this.sliderPos);
this.renderer.render(this.sceneGlobal, this.camera);
this.renderer.setScissor(0, 0, this.width, this.height - this.sliderPos);
this.renderer.render(this.sceneBlock, this.camera);
注意:在实践时,发现效果总是不对,这里 setScissor 的理解容易产生误区,不是表示需要绘制的区域,而是需要裁减掉的区域。
setViewport
与 setScissor 类似的有一个 setViewport 函数,那它们的区别是什么呢
- setScissor 只是将一部分裁减掉,并不影响场景中模型的平移缩放变换
- setViewport 会影响场景中模型的平移缩放变换