「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」
示例代码采用three.js-r73版本: cdnjs.cloudflare.com/ajax/libs/t…
上一节我们已经成功地加载了模型,但是对加载模型过程使用的材质和loader方法没有做太多介绍。下面我们来看一下。
Lambert网格材质
- 我们加载模型时使用
MeshLambertMaterial材质
var material = new THREE.MeshLambertMaterial({ color: 0xffffff, side: THREE.DoubleSide });
side属性解析
- 这里我们创建了一个基础材质(粗糙的平面),使用了side属性,这个属性有三个值
THREE.FrontSide = 0; // 绘制前面
THREE.BackSide = 1; // 绘制后面
THREE.DoubleSide = 2; // 两面绘制
- 我们展示模型的时候,是有正面后面之分的,如果只绘制一面,当我们旋转的时候,可能就看不到另一个面了,所以我们这里使用了两面绘制。
- 比如我们有一个三角形,它有正反两面,我们只绘制正面,那么能看到的就只有正面,只绘制反面同理。
- 放到我们的模型上,我们把摄像机位置设置小一些,就可以进入到兔子的肚子中
camera.position.z = 0.001;
- 现在我们看到的其实是兔子里面
- 当我们设置side为
THREE.FrontSide时,我们就看不到里面了,只能通过缩放看到兔子外面
- 当我们把摄像机拉远,设置side为
THREE.BackSide时,只能看到兔子的里面
camera.position.z = 0.2;
- 所以我们既想看到里面又想看到外面,就要设置side为
THREE.DoubleSide,这个还是比较神奇的,只有自己操作过才能体会出来
材质问题
- 我们现在使用的是
MeshLambertMaterial材质,这种材质可以均匀的反射光,所以要有灯光 - 如果我们使用
MeshBasicMaterial材质的话,就不需要光了,但是只能进行简单的着色,我们的模型会展示称如下样子
- 所以材质的选择也很重要
VTKLoader
- 我们加载vtk模型文件,使用了
VTKLoader,目前使用了url和onLoad回调函数,其实它还有两个参数- url: 资源路径
- onLoad: 加载完成回调函数,返回
geometry - onProgress:加载进度
- onError:加载错误提示
不同版本可能也有些许差别,目前使用的是r73版本。
geometry法线
loader.load("../../static/models/vtk/bunny.vtk", function (geometry) {
geometry.computeVertexNormals();
var mesh = new THREE.Mesh(geometry, material);
mesh.position.setY(- 0.09);
scene.add(mesh);
});
- 我们获取到了模型资源的
geometry,需要通过geometry.computeVertexNormals()来计算每个顶点的法线
- 因为
MeshLambertMaterial是有光照的材质,当光照射到geometry上要有法线才能反射光照。如果不计算法向量,就看不到物体了。
模型位置问题
- 我们加载完模型,创建网格,给网格设置了一个位置
mesh.position.setY(- 0.09);
- 如果不设置这个位置,我们的模型会展示在场景上方
- 这是因为,建模时,模型位置并没有在(0,0,0)点,而是选择了往上一点,所以有的时候我们拿到的模型并不一定是在原点,也有可能在别的地方或者被旋转过等等
总结
这一节我们主要讲了以下内容:
- Lambert网格材质
- side属性解析
- 材质问题
- VTKLoader属性方法介绍
- 模型位置问题