You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ThreeJS中如何隐藏/融合透明相邻网格的重叠部分?

实现透明立方体重叠区域与绿色融合的方法

针对你的需求,有两种可行的实现方案,都能保证非透明物体不受影响:


方案一:自定义混合模式(简单快速)

通过修改橙黄色立方体的材质混合参数,让重叠区域仅保留绿色立方体的颜色,非重叠区域保持橙黄色半透明效果。

修改你的材质生成代码:

getTransparentMesh(color = 0x990000, isGreen = false) {
  const geo = new THREE.BoxGeometry(100, 100, 100);
  const matParams = {
    color: color,
    transparent: true,
    opacity: 0.5,
    depthWrite: false // 确保透明物体不干扰非透明物体的深度缓冲
  };

  // 为橙黄色立方体设置自定义混合规则
  if (!isGreen) {
    matParams.blending = THREE.CustomBlending;
    matParams.blendEquation = THREE.AddEquation;
    // 重叠区域:橙黄颜色权重为0,绿色颜色权重为1,仅显示绿色
    matParams.blendSrc = THREE.ZeroFactor;
    matParams.blendDst = THREE.OneFactor;
    // 保持alpha通道的正常透明混合
    matParams.blendSrcAlpha = THREE.SrcAlphaFactor;
    matParams.blendDstAlpha = THREE.OneMinusSrcAlphaFactor;
  }

  const mat = new THREE.MeshBasicMaterial(matParams);
  return new THREE.Mesh(geo, mat);
}

addTransparentMeshes() {
  this.meshB = this.getTransparentMesh(0x88ff00, true); // 绿色立方体
  this.meshA = this.getTransparentMesh(0xee8800, false); // 橙黄色立方体

  this.meshA.position.set(20, 0, -50);
  this.meshB.position.set(-30, 0, 50);

  const scene = this.engine.scene;
  scene.add(this.meshB); // 先渲染绿色立方体,确保它先写入帧缓冲
  scene.add(this.meshA);
}

核心逻辑:先渲染绿色立方体,再渲染橙黄色立方体时,通过混合规则让重叠区域只保留已渲染的绿色,非重叠区域正常显示橙黄色半透明。


方案二:模板缓冲(灵活可控)

如果需要更精细的控制(比如重叠区域用绿色与橙黄的融合色,而非单纯绿色),可以使用模板缓冲标记绿色立方体的区域,单独处理重叠部分的颜色。

步骤1:启用模板缓冲

先确保你的渲染器开启了模板缓冲:

this.engine.renderer.stencilBuffer = true;

步骤2:分阶段渲染

修改渲染逻辑,分三步处理:

// 渲染前准备
this.engine.renderer.clear();

// 1. 渲染绿色立方体,并用模板缓冲标记其区域(模板值设为1)
this.meshB.material.stencilWrite = true;
this.meshB.material.stencilFunc = THREE.AlwaysStencilFunc;
this.meshB.material.stencilZPass = THREE.ReplaceStencilOp;
this.meshB.material.stencilRef = 1;
this.engine.renderer.render(this.engine.scene, this.engine.camera);

// 2. 渲染橙黄色立方体的非重叠区域(仅渲染模板值≠1的区域)
this.meshA.material.stencilWrite = false;
this.meshA.material.stencilFunc = THREE.NotEqualStencilFunc;
this.meshA.material.stencilRef = 1;
this.engine.renderer.render(this.engine.scene, this.engine.camera);

// 3. 渲染重叠区域,使用融合后的材质(这里用偏绿的融合色示例)
const blendedMaterial = new THREE.MeshBasicMaterial({
  color: 0xaaee00, // 绿色与橙黄的融合色
  transparent: true,
  opacity: 0.5,
  depthWrite: false
});
this.meshA.material = blendedMaterial;
this.meshA.material.stencilFunc = THREE.EqualStencilFunc;
this.meshA.material.stencilRef = 1;
this.engine.renderer.render(this.engine.scene, this.engine.camera);

// 恢复原材质,避免影响后续渲染
this.meshA.material = this.getTransparentMesh(0xee8800, false).material;
this.meshB.material.stencilWrite = false;

这种方式可以自由定义重叠区域的颜色,完全满足你对融合效果的定制需求。


关键注意点

  • 透明物体的depthWrite需设为false(默认MeshBasicMaterial在transparent: true时已自动设置),确保非透明物体的深度缓冲不受干扰,正常渲染。
  • 渲染顺序对混合效果影响很大,务必遵循“从后往前”或按逻辑顺序渲染透明物体。

内容的提问来源于stack exchange,提问作者SoundOfWinder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 03:24:50