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

如何让OBJ+MTL加载的模型实现双面显示?已尝试setMaterialOptions无效

解决Three.js OBJ+MTL加载后设置材质双面显示的问题

嗨,我之前也踩过这个坑!Three.js的MTLLoader在版本迭代里已经移除了setMaterialOptions这个方法,所以VSCode没代码提示、调用后无效都是正常的~下面给你两种靠谱的解决方案:

方案一:加载MTL后直接修改材质属性

在MTL加载完成的回调里,遍历所有材质并设置双面属性,再传给OBJLoader使用:

import * as THREE from 'three';
import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';

const mtlLoader = new MTLLoader();
mtlLoader.load('你的模型路径/model.mtl', (materials) => {
  // 遍历所有材质,设置双面显示
  for (const key in materials.materials) {
    const material = materials.materials[key];
    material.side = THREE.DoubleSide; // 核心设置
    material.needsUpdate = true; // 确保材质属性更新生效
  }
  materials.preload(); // 预加载材质资源
  
  // 加载OBJ模型并绑定修改后的材质
  const objLoader = new OBJLoader();
  objLoader.setMaterials(materials);
  objLoader.load('你的模型路径/model.obj', (object) => {
    scene.add(object);
  });
});

方案二:加载OBJ模型后遍历子对象修改

这种方法更通用,不管材质是怎么加载的,直接处理最终的模型对象:

const objLoader = new OBJLoader();
// 先加载MTL并绑定(如果需要)
mtlLoader.load('model.mtl', (materials) => {
  materials.preload();
  objLoader.setMaterials(materials);
  // 加载OBJ
  objLoader.load('model.obj', (object) => {
    // 遍历模型所有子网格
    object.traverse((child) => {
      if (child.isMesh) {
        child.material.side = THREE.DoubleSide;
        child.material.needsUpdate = true;
        // 可选:如果模型面法线有问题,可以强制更新法线
        // child.geometry.computeVertexNormals();
      }
    });
    scene.add(object);
  });
});

注意事项

  • 确保你使用的是最新版的Three.js,旧版的Loader API差异很大;
  • needsUpdate = true是必须的,否则材质属性的修改可能不会实时生效;
  • 如果模型部分面还是显示异常,可以检查模型本身的法线是否正确,必要时调用child.geometry.computeVertexNormals()重新计算法线。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:16:54