threejs加载模型材质失效解决方案

问题

当我们在threejs中使用loader方法,加载已经绘制好的三维模型,当我们在三维建模软件中,我们可以看到三维模型有材质贴图,但当使用threejs加载时,材质呈现黑色或者与原有材质相差很大。

<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js webgl - exporter - gltf</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
    <script type="importmap">
			{
				"imports": {
					"three": "../build/three.module.js",
					"three/addons/": "./jsm/"
				}
			}
		</script>
    <script type="module">
        import * as THREE from 'three';
        import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer();
        renderer.setClearColor('pink')
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 设置相机控件轨道控制器OrbitControls
        let controls = new OrbitControls(camera, renderer.domElement);
        controls.listenToKeyEvents(window);
        controls.enableDamping = true;
        controls.dampingFactor = 0.05;
        controls.screenSpacePanning = true;
        controls.minDistance = 1;
        controls.maxDistance = 500;
        controls.maxPolarAngle = Math.PI / 2;

        const loader = new GLTFLoader();
        loader.load(
            // 模型文件的路径
            'models/xxx.gltf',
            // 加载完成后的回调函数
            function (gltf) {
                scene.add(gltf.scene);
                gltf.scene.position.set(0, 0, 0);
                // 可以对每个mesh进行单独的设置
                gltf.scene.traverse(function (obj) {
                    if (obj.isMesh) {//判断是否是网格模型
                        
                    }
                });
            }
        );
        renderer.outputEncoding = THREE.sRGBEncoding;

        const animate = function () {
            requestAnimationFrame(animate);
            controls.update();
            renderer.render(scene, camera);
        };
        animate();
    </script>
</body>
</html>

解决方案

1.如果材质呈现黑色,添加物体自发光

gltf.scene.traverse(function (obj) {
    if (obj.isMesh) {//判断是否是网格模型
        obj.material.emissive =  obj.material.color;
        obj.material.emissiveMap = obj.material.map ;
    }
});

2.如果模型材质受光源影响(除了MeshBasicMaterial),添加光源

解决方案第一步:如果模型的材质是MeshLambertMaterial、MeshPhongMaterial、MeshStandardMaterial以及MeshPhysicalMaterial,如下图,需要在三维场景中添加光源

在这里插入图片描述

const light = new THREE.AmbientLight(0xffffff, 10);
scene.add(light);

添加光源后,可视化效果可以看出模型的材质颜色,但缺失一些细节信息,例如金属度、粗糙度、物理材质透光率等物理属性,则可能是光源设置强度过大,或者光源位置不正确

在这里插入图片描述

// 合适的光源强度及位置,可以让三维模型材质正确显示
const light = new THREE.AmbientLight(0xffffff, 0.3);
scene.add(light);

const dirLight1 = new THREE.DirectionalLight('rgb(253,253,253)', 5);
scene.add(dirLight1);

在这里插入图片描述

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值