Three.js如何将指定视口设置为圆形?
实现局部圆形裁剪视口的方案
因为Canvas的setScissor()仅支持矩形区域裁剪,CSS border-radius又会影响整个画布,所以要实现指定视口的圆形裁剪,得用Canvas自身的路径裁剪(2D场景)或模板缓冲(WebGL场景)方案:
一、2D Canvas场景(使用clip()方法)
直接通过绘制圆形路径并设置裁剪区域,限制后续绘制仅在圆形范围内生效:
// 保存当前绘图状态,避免影响其他绘制 ctx.save(); // 计算圆形裁剪区域的参数(假设view1是正方形区域) const centerX = left + width / 2; const centerY = positiveYUpBottom + height / 2; const radius = width / 2; // 宽高相等时取宽的一半,若为椭圆则分别设置x/y半径 // 创建圆形路径 ctx.beginPath(); ctx.arc(centerX, centerY, radius, 0, Math.PI * 2); ctx.closePath(); // 设置裁剪区域 ctx.clip(); // 绘制view1的内容(保留原视口设置,绘制逻辑不变) ctx.setViewport(left, positiveYUpBottom, width, height); // 此处替换为你绘制view1的代码... // 恢复绘图状态,取消圆形裁剪 ctx.restore();
二、WebGL场景(使用模板缓冲)
WebGL没有直接的clip()方法,需借助模板缓冲标记圆形区域,再限制绘制范围:
const gl = renderer.getContext('webgl'); // 保存当前WebGL状态 gl.save(); // 启用模板测试 gl.enable(gl.STENCIL_TEST); // 配置模板操作:绘制圆形时将模板值设为1 gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); gl.stencilFunc(gl.ALWAYS, 1, 0xFF); // 临时关闭颜色和深度写入,仅更新模板缓冲 gl.colorMask(false, false, false, false); gl.depthMask(false); // 绘制圆形到模板缓冲(需用shader绘制圆或三角形扇形,此处假设已有drawCircle工具函数) drawCircle(left + width/2, positiveYUpBottom + height/2, width/2); // 恢复颜色和深度写入 gl.colorMask(true, true, true, true); gl.depthMask(true); // 配置模板测试:仅绘制模板值为1的区域 gl.stencilFunc(gl.EQUAL, 1, 0xFF); gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); // 绘制view1的内容 gl.viewport(left, positiveYUpBottom, width, height); // 此处替换为你绘制view1的WebGL代码... // 关闭模板测试,恢复状态 gl.disable(gl.STENCIL_TEST); gl.restore();
关键说明
- 两种方案都只会对
save()和restore()之间的绘制生效,不会影响画布其他区域 - 若view1区域不是正方形,调整
arc()参数可实现椭圆形裁剪
内容的提问来源于stack exchange,提问作者javrro
相关产品推荐
相关产品推荐

