You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Three.js中如何动态调整已加载3D模型的透明度?

如何动态调整Three.js中加载模型的透明度?

嘿,这个问题我之前也踩过坑!你找不到透明度属性是因为skull作为加载进来的Object3D对象,本身并没有直接的透明度属性——透明度是定义在模型的**材质(Material)**上的,而不是模型对象本身。下面给你几种实用的解决方案:

1. 通用方案:递归遍历模型所有子对象设置透明度

大部分导出的3D模型都会是带有层级结构的Object3D,里面包含多个网格(Mesh)对象,每个网格对应自己的材质。所以我们需要递归遍历所有子对象,找到带材质的部分来设置:

// 定义一个递归函数,遍历模型所有子对象设置透明度
function setModelOpacity(object, opacityValue) {
  // 检查当前对象是否是Mesh且拥有材质
  if (object.isMesh && object.material) {
    // 必须先开启透明属性,否则opacity设置无效
    object.material.transparent = true;
    // 设置透明度,取值范围0(完全透明)到1(完全不透明)
    object.material.opacity = opacityValue;

    // 处理多材质情况(有些模型会给同一个Mesh设置多个材质)
    if (Array.isArray(object.material)) {
      object.material.forEach(mat => {
        mat.transparent = true;
        mat.opacity = opacityValue;
      });
    }
  }
  // 递归处理所有子对象
  object.children.forEach(child => setModelOpacity(child, opacityValue));
}

// 在模型加载完成后调用函数设置初始透明度
loader2.load('skull.json', function(object) {
  skull = object;
  scene.add(skull);
  // 比如设置为半透明(0.5)
  setModelOpacity(skull, 0.5);
});

2. 简化方案:如果模型是单一网格直接设置

如果你确定加载的头骨模型只有一个网格对象,可以直接访问子对象的材质,省去递归步骤:

loader2.load('skull.json', function(object) {
  skull = object;
  scene.add(skull);
  const skullMesh = skull.children[0];
  if (skullMesh.isMesh) {
    skullMesh.material.transparent = true;
    skullMesh.material.opacity = 0.3;
  }
});

不过这种方式局限性大,一旦模型有层级结构就会失效,还是递归遍历的通用方案更靠谱。

3. 动态调整透明度

之后如果要做动态调整(比如用滑块控制透明度),只需要再次调用setModelOpacity函数,传入新的数值就行:

// 假设你有一个id为opacitySlider的滑块控件
const opacitySlider = document.getElementById('opacitySlider');
opacitySlider.addEventListener('input', function(e) {
  // 把滑块的字符串值转为浮点数
  const newOpacity = parseFloat(e.target.value);
  setModelOpacity(skull, newOpacity);
});

小提醒

  • 一定要先设置material.transparent = true,否则opacity属性不会生效,这是Three.js的渲染规则决定的。
  • 如果模型使用了自定义材质,要确保材质本身支持透明渲染(大部分内置材质比如MeshStandardMaterialMeshBasicMaterial都支持)。

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

火山引擎 最新活动