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
相关产品推荐
相关产品推荐

