使用Three.js导入obj+mtl带纹理模型后渲染偏色该如何解决?
问题:OBJ+MTL带纹理模型导入Three.js后渲染偏色

导入obj+mtl格式附带纹理的模型后,渲染结果出现异常偏色问题。
模型正常显示效果如下:
当前场景配置代码
loadModel() scene.current.background = new THREE.Color( 'transparent' ); scene.current.add(new THREE.AxesHelper( 5 )); const mesh = new THREE.Mesh( new THREE.PlaneGeometry( 100, 100 ), new THREE.MeshPhongMaterial( { color: 0xffffff, depthWrite: false } ) ); mesh.rotation.x = - Math.PI / 2; mesh.receiveShadow = true; scene.current.add( mesh ); controls.current.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled controls.current.dampingFactor = 0.2; controls.current.screenSpacePanning = false; controls.current.maxPolarAngle = Math.PI / 2; controls.current.maxDistance = 200 controls.current.minDistance = 20 controls.current.target = new THREE.Vector3(0, 16, 0) camera.current.position.set( -3, 17, 8 ); camera.current.lookAt(new THREE.Vector3( 0, 15, 0 )); controls.current.update(); scene.current.background = new THREE.Color( 0xFFFFFF ); const ambilentLight = new THREE.AmbientLight( 0xffffff, 0.5) scene.current.add(ambilentLight) const hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff ); hemiLight.position.set( 0, 500, 30 ); hemiLight.castShadow = true scene.current.add( hemiLight ); scene.current.add(new THREE.HemisphereLightHelper( hemiLight, 5 )); const dirLight = new THREE.DirectionalLight( 0xffffff, 0.5 ); dirLight.position.set( -10, 50, 50 ); dirLight.castShadow = true; scene.current.add( dirLight ); scene.current.add(new THREE.DirectionalLightHelper( dirLight, 5 )); renderer.current.shadowMap.enabled = true; renderer.current.setPixelRatio( window.devicePixelRatio ); renderer.current.setSize( window.innerWidth, window.innerHeight ); renderer.current.outputEncoding = THREE.sRGBEncoding; renderer.current.toneMapping = THREE.ACESFilmicToneMapping; renderer.current.toneMappingExposure = 1; renderer.current.physicallyCorrectLights = true; container.current.appendChild(renderer.current.domElement); window.addEventListener( 'resize', onWindowResize ); animate();
解决方案
按照以下优先级依次排查修改即可解决偏色问题:
- 纹理编码适配:你开启了渲染器的sRGB输出编码,但OBJ/MTL加载器默认导入的漫反射纹理编码为LinearEncoding,和输出编码不匹配会导致偏灰偏色。在模型加载完成的回调中添加如下代码调整纹理编码:
// model为OBJLoader加载返回的模型实例 model.traverse(child => { if (child.isMesh && child.material?.map) { child.material.map.encoding = THREE.sRGBEncoding child.material.map.needsUpdate = true } })
- 色调映射调整:ACESFilmicToneMapping会对画面做电影级色彩映射,若你的模型纹理已经是预调色的成品,可先关闭色调映射验证是否是该配置导致的偏色:
// 修改渲染器配置 renderer.current.toneMapping = THREE.NoToneMapping
若关闭后颜色恢复正常,可保留色调映射,调整toneMappingExposure参数(建议范围0.6~1.5)适配你需要的色彩效果即可。
- 光照配置优化:你同时叠加了环境光、半球光、平行光三类白光,且开启了物理光照模式,全局光照强度过高会导致颜色饱和度降低、整体偏白。可先移除AmbientLight,将HemisphereLight强度设置为0.3,DirectionalLight强度设置为0.8,再根据实际显示效果微调参数。
- 材质校验:检查MTL文件中
Kd(漫反射基础色)参数是否正常,加载过程中有没有纹理加载失败的控制台报错,排除材质本身配置错误的问题。
内容的提问来源于stack exchange,提问作者Adri HM
相关产品推荐
相关产品推荐

