创建第一个模型
我们在场景中添加一个立方体。
创建立方体需要用到babylonjs的MeshBuilder.CreateBox方法。注意,老版教程中会使用Mesh.CreateBox方法,这个方法官方已经不推荐使用了。
import { ArcRotateCamera, Color3, Engine, MeshBuilder, Scene, Vector3, Color4 } from 'babylonjs';/** 中间代码省略 */const createScene = (engine: Engine) => {/** 创建场景 */const scene = new Scene(engine);/** end *//** 创建相机 */const camera = new ArcRotateCamera('camera', 0, 0, 10, Vector3.Zero(), scene);camera.attachControl(true);/** end *//** 创建立方体 */const box = MeshBuilder.CreateBox('box', { width: 2, height: 3, depth: 4 }, scene);/** end */return scene;};
MeshBuild.CreateBox方法需要传入三个参数:
name:和camera的name含义一样,就是我们平时理解的id,需要全局唯一option:构建立方体的初始化配置,配置表如下: | 属性 | 值 | 默认值 | | —- | —- | —- | | size | (number) box每条边的长度 | 1 | | height | (number) 在Y轴上的边的长度,会覆盖size的值 | size | | width | (number) 在X轴上的边的长度,会覆盖size的值 | size | | depth | (number) 在Z轴上的边的长度,会覆盖size的值 | size | | faceColors | (Color4[]) 由Color4组成的长度为6的数组,代表每个面的颜色 | Color4(1, 1, 1, 1) for each side | | faceUV | (Vector4[]) 由Vector4组成的长度为6的数组,代表每个面的纹理贴图的应用范围 | UVs(0, 0, 1, 1) for each side | | updatable | (boolean) 指定Mesh的顶点数据是否可以被更新 | false | | sideOrientation | (number) 定义模型的每个面的可见方式。例如正方体有六个面,每个面都有正面和反面。默认相机只能看到一个面的正面,这样比较节省计算资源。
- Mesh.FRONTSIDE,表示正面可见
- Mesh.BACKSIDE,表示反面可见
- Mesh.DOUBLESIDE,表示正反面都可见
- Mesh.DEFAULT,目前这个值和FRONTSIDE相等
| Mesh.DEFAULTSIDE |scene:代表物体所处场景
现在场景中就多了一个234的立方体,但是我们发现,这个立方体浑身漆黑,这是为什么呢?
原因很简单,因为我们还没有设置灯光。和现实世界一样,如果没有光,所有的物体都会是黑的。那么接下来我们就给这个场景增加一个平行光DirectionalLight——也就是我们现实中的太阳。
创建灯光
import { ArcRotateCamera, Color3, Engine, MeshBuilder, Scene, Vector3, Color4, DirectionalLight } from 'babylonjs';/** 中间代码省略 */const createScene = (engine: Engine) => {/** 创建场景 */const scene = new Scene(engine);scene.clearColor = Color4.FromColor3(Color3.Gray());/** end *//** 创建相机 */const camera = new ArcRotateCamera('camera', 0, 0, 10, Vector3.Zero(), scene);camera.attachControl(true);/** end *//** 创建立方体 */const box = MeshBuilder.CreateBox('box', { width: 2, height: 3, depth: 4 }, scene);/** end *//** 创建灯光 */const light = new DirectionalLight('light', Vector3.Down(), scene);light.diffuse = Color3.Red();light.specular = Color3.Green();/** end */return scene;};
DirectionalLight构造函数需要传入三个参数:
name:名称,全局唯一direction:光线照射的方向。Vector3.Down()即{ x: 0, y: -1, z: 0 },表示光线垂直向下scene:光线所处场景
diffuse这个属性代表光线的漫反射光色,所谓漫反射色表示光线照射到物体上时物体所反射出的颜色,我们这里设置为了红色。现在我们先注释掉light.specular这段代码,可以看到光线从上而下照射到物体上时,物体的顶面呈现出了红色,而其他五个面由于没有被光照到,所以仍然是黑色:
specular这个属性代表镜面光色(也叫高光色),即光源在物体上反射出的颜色,就好像从镜子中看灯泡一样。我们这里设置成了绿色,理论上物体表面应该会有一个绿色的高光,但是实际效果却呈现出了黄色!
这是为什么呢?
原因很简单,物体表面现在有一个红色的漫反射色和绿色的高光色,着色器会把两种颜色混合,所以呈现出了黄色。当我们把相机旋转到一定角度,可以看到光源在物体上确实还是显示绿色:
由此可见,物体最终呈现出的颜色并不一定是我们设置的某种颜色,而是由多种情况下的颜色的混合结果。这个在开发中要特别注意。
更多的模型和灯光
当然,babylonjs还内置了很多其他的创建模型的方法,包括不规则几何图形和线。灯光除了平行光DirectionalLight,还有点光PointLight、聚光灯SpotLight、半球光HemisphericLight。您可以在babylonjs官方网站找到更多的信息,或者查看镜像中文网站https://doc.cnbabylon.com/babylon101/。我们这里就不再赘述了,后面有机会再展开讲解。
现在有一个问题了,我们能不能在没有灯光照射的情况下,让物体产生颜色呢?答案当然是可以,这就需要引入一个新的概念——材质。下面我们就聊聊如何创建材质,以及设置它的相关属性。
