初学three.js,跟着教程走都比较顺利,自己尝试写个demo的时候发现创建一个物体,在给材质颜色的时候出现了一个问题。
在three.js官网文档(https://www.techbrood.com/threejs/docs/)中,我们可以看到材料(材质)在不同的场景下被赋予很多种分类,而这里我将LineBasicMaterial和MeshLambertMaterial拿来做示例。
在这里,我们首先对两种材质进行概念上的区分:
MeshBasicMaterial:基础材质,给几何体赋予一种简单的颜色,只与初始化定义的颜色有关,不受光照的影响。
MeshLambertMaterial:Lambert材质,一种表面粗糙,比较暗淡的材质。它是一种高级材质,可以对光源产生反应创建不光亮的表面。
// 创建相机
const scene2 = new THREE.Scene();
// 创建物体及材质
const geom2 = new THREE.SphereGeometry(60, 40, 40);
const mater2 = new THREE.MeshLambertMaterial({ color: 0xce21bc });
// const mater2 = new THREE.MeshLambertMaterial({ color: 0xce21bc });
// 创建一个网格模型对象
const mesh4 = new THREE.Mesh(geom2, mater2)
mesh4.position.set(100, 0, 0);//设置mesh3模型对象的xyz坐标为120,0,0
scene2.add(mesh4);
// 创建一个相机
const width2 = 600; const height2 = 400
const camera2 = new THREE.PerspectiveCamera(45, width2 / height2, 0.1, 1000)
//设置相机位置
camera2.position.set(300, 300, 300);
//设置相机方向
camera2.lookAt(0, 0, 0);
//创建辅助坐标轴
const axesHelper2 = new THREE.AxesHelper(200);//参数200标示坐标系大小,可以根据场景大小去设置
scene2.add(axesHelper2);
// 创建一个渲染器
const renderer2 = new THREE.WebGLRenderer()
// renderer2.setClearColor('white'); //canvas画布颜色
renderer2.setSize(width2, height2)
renderer2.render(scene2, camera2)
const controls2 = new OrbitControls(camera2, renderer2.domElement)//创建控件对象
controls2.addEventListener('change', () => {
renderer2.render(scene2, camera2)//监听鼠标,键盘事件
})
onMounted(() => {
document.getElementById('my-three2')?.appendChild(renderer2.domElement)
})
在此基础上,我们得到了一个基础网孔材料(MeshBasicMaterial)下的物体,可以正常显示。此时我们将MeshBasicMaterial换成兰伯特网孔材料(MeshLambertMaterial)
// 创建物体及材质
const geom2 = new THREE.SphereGeometry(60, 40, 40);
// const mater2 = new THREE.MeshLambertMaterial({ color: 0xce21bc });
const mater2 = new THREE.MeshLambertMaterial({ color: 0xce21bc });
在这里我们仅展示部分代码,其余代码与上方贴出的一模一样。
可以看到在同样黑色背景的画布下,有一个黑色的物体存在,因背景颜色相同而被覆盖,我们将背景颜色换成其他颜色
renderer2.setClearColor('pink'); //canvas画布颜色
证实确实物体是存在的,只是材质颜色没起作用。
查看官网文档和网上的各种小贴士才找出问题所在,我们可以看到l对MeshLambertMateria的概念中写道:它是一种高级材质,可以对光源产生反应创建不光亮的表面。所以对其添加光源是必不可少的一步。
// 创建物体及材质
const geom2 = new THREE.SphereGeometry(60, 40, 40);
const mater2 = new THREE.MeshLambertMaterial({ color: 0xce21bc });
//添加光源
//会照亮场景里的全部物体(氛围灯),前提是物体是可以接受灯光的,这种灯是无方向的,即不会有阴影。
const ambient2 = new THREE.AmbientLight(0xffffff, 0.4);
const light2 = new THREE.PointLight(0xffffff, 1);//点光源,color:灯光颜色,intensity:光照强度
scene2.add(ambient2);
light2.position.set(200, 300, 400);
scene2.add(light2);
此刻我们可以看到物体的颜色发生了变化,并且和上方基础网孔材料相比是更加立体和形象的。光源(AmbientLight)在官网文档中也有相关API,可以自行了解。
因此问题特做记录,希望对小伙伴们有帮助!