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

Three.js加载OBJ、MTL模型时纹理不显示问题求助

解决Three.js OBJ+MTL模型纹理不显示的问题

我来帮你排查这个纹理不显示的问题,结合你的代码和MTL文件内容,几个常见的坑可以先逐一检查:

1. 显式设置MTLLoader的纹理路径

虽然你已经给MTLLoader设置了模型文件的路径,但有时候MTLLoader处理纹理时需要单独指定纹理的基础路径。可以在MTLLoader初始化后加上setTexturesPath方法,确保它能正确找到rock.png:

var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( '/examples/obj/rock/' );
// 新增:显式指定纹理文件的路径
mtlLoader.setTexturePath('/examples/obj/rock/');
mtlLoader.load( 'rock.mtl', function( materials ) {
    // ... 后续代码不变
});

2. 检查纹理是否成功加载

在材质预加载后,打印材质详情确认纹理是否正常加载:

materials.preload();
// 打印材质和纹理信息
console.log('加载的材质集合:', materials);
console.log('Rock-Texture的纹理:', materials.materials['Rock-Texture'].map);

如果输出的map为null或undefined,说明纹理没找到,要检查:

  • rock.png的文件名和MTL文件里的map_Kd rock.png大小写完全一致(服务器环境下大小写敏感)
  • 浏览器Network面板里rock.png的请求状态是否为200(打开F12→Network标签,刷新页面查看)

3. 确保渲染器和光源提前初始化

你的代码里渲染器是在模型加载代码之后初始化的,虽然不影响纹理加载,但建议把渲染器初始化放在最前面,同时必须给场景添加光源——没有光照的话,漫反射材质的纹理是无法显示的:

// 先初始化渲染器、场景、光源(假设scene和container已定义)
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );

// 添加必要的光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(5, 10, 7.5);
scene.add(directionalLight);

// 再加载模型...
var mtlLoader = new THREE.MTLLoader();
// ... 后续加载代码

4. 排查跨域或本地文件访问问题

如果是用file://协议直接打开本地HTML文件,浏览器会阻止加载本地纹理(跨域限制)。这时候需要用本地服务器运行项目,比如用http-server(npm安装后在项目根目录运行http-server),再通过http://localhost:8080访问页面。

修改后的完整示例代码

// 假设scene、container、camera、onProgress、onError已提前定义
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );

// 添加光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(5, 10, 7.5);
scene.add(directionalLight);

// 加载MTL和OBJ
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( '/examples/obj/rock/' );
mtlLoader.setTexturePath('/examples/obj/rock/');
mtlLoader.load( 'rock.mtl', function( materials ) {
    materials.preload();
    console.log('加载的材质集合:', materials);
    console.log('Rock-Texture的纹理:', materials.materials['Rock-Texture'].map);

    var objLoader = new THREE.OBJLoader();
    objLoader.setMaterials( materials );
    objLoader.setPath( '/examples/obj/rock/' );
    objLoader.load( 'rock.obj', function ( object ) {
        console.log(object);
        object.position.y = 0;
        scene.add( object );
        // 添加后立即渲染一次
        renderer.render(scene, camera);
    }, onProgress, onError );
});

先按上面的步骤排查,大概率能解决纹理不显示的问题~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:41:46