最近在捣鼓
Three.js
相关知识,同时觉得微信小游戏是个不错的试错场呢。不错,本项目就是为了试错而存在。
这个格局是不是很眼熟,就是网页游戏2048的变版呢。乍一看,2D的呀,与Three.js
没半毛线关系。请仔细看,有阴影,有透明度, 有立体感,一切都在细节中...
这里吐槽一哈, 微信 7.0.15
版本,及相近版本进游戏可能会闪退, 具体原因不详。
概述 Three.js
来构建一个小游戏场景, 过程是比较简单的,三步走。
- 新建场景,打好灯光,设置摄像机位置;
- 将几何图形和材质的组合,构建出不同的模型
- 在场景中将模型渲染出来。一个 3D 界面就出来了
前置条件
- 浏览器方面,用谷歌准没错, 具体兼容性, 请查看
https://caniuse.com
- 假定你一定程度上掌握了 JavaScript,最好有一定三维图形学知识。
基本概念
场景:提供一个带三维坐标轴的空间
相机: 相当于人的眼睛,就是视角。相机分两种,正投影相机 OrthographicCamera
和透视投影相机 PerspectiveCamera
。 针对不同应用的三维场景需要使用不同的投影方式,比如机械、工业设计领域常常采用正投影(平行投影), 大型游戏场景往往采用透视投影(中心投影)。
光源: Threejs 虚拟光源是对自然界光照的模拟。光源分环境光(AmbientLight
), 平行光(DirectionalLight
), 半球光(HemisphereLight
),点光源(PointLight
),平面光光源(RectAreaLight
),聚光灯(SpotLight
)。threejs 搭建虚拟场景的时候,为了更好的渲染场景,往往需要设置不同的光源,设置不同的光照强度,就像摄影师给你拍照要设置各种辅助灯光一样。
几何体:模型的几何形状,如:立方体,圆柱体,或是 自定义几何体之类。three.js 封装了一些几何模型 立方几何体(BoxGeometry
),圆柱几何体(CylinderGeometry
)等。
材质:几何体的外观。three.js 封装了一些材质,如 具有镜面高光的光泽表面的材质(MeshPhongMaterial
),没有镜面高光的网格材质(MeshLambertMaterial
)等等;
纹理:材质表面的贴图, 可以是图片,也可以是canvas
绘制出来的图形
渲染器 就是将场景相机光照以及模型以某方式结合并呈现出来
了解上面的概念,足够用了。
代码实例
- 先
new
场景,我这里是new
了两个场景,游戏界面需要立体感,采用中心投影; 得分描述文字等模型对象,只需要平铺在界面上,采用平行投影。 中心投影场景中添加辅助线,灯光和背景色。
createScene() {
this.scene = new THREE.Scene();
this.hudScene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(1000);
const lights = this.createLight();
Object.keys(lights).forEach((value) => {
this.scene.add(lights[value]);
});
this.scene.add(axesHelper);
this.scene.background = new THREE.Color(0x3498db);
}
- 在
new
相机,也是两个,一个正投影相机, 一个透视相机。需要设置朝向,相机位置,以及聚焦位置。
createCamera() {
this.camera = new THREE.PerspectiveCamera(
45,
screenWidth / screenHeight,
0.1,
5000
);
this.camera.up.set(0, 1, 0);
this.camera.position.set(0,0,2000);
this.camera.lookAt(this.scene.position);
}
createHudCamera() {
this.hudCamera = new THREE.OrthographicCamera(
-screenWidth / 2,
screenWidth / 2,
screenHeight / 2,
-screenHeight / 2,
-1000,
1000
);
this.hudCamera.up.set(0, 1, 0);
this.hudCamera.position.set(0, 0, 1000);
this.hudCamera.lookAt(new THREE.Vector3(0, 0, 0));
}
- 光源设置,这里根据实际场景设置,我这里设置了环境光和平行光。其中平行光可以设置阴影。
createLight() {
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.3);
directionalLight.position.set(400, 100, 500);
directionalLight.castShadow = true;
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 1000;
directionalLight.shadow.camera.left = -500;
directionalLight.shadow.camera.right = 500;
directionalLight.shadow.camera.top = 500;
directionalLight.shadow.camera.bottom = -500;
directionalLight.shadow.mapSize.width = 3024;
directionalLight.shadow.mapSize.height = 3024;
return {
ambientLight: new THREE.AmbientLight(0xffffff, 0.7),
directionalLight,
};
}
- 渲染器
createRenderer() {
let { devicePixelRatio, innerWidth, innerHeight } = window;
this.renderer = new THREE.WebGLRenderer({
canvas,
antialias: true,
precision: "highp",
});
this.renderer.setClearColor(0xffffff, 1);
this.renderer.setPixelRatio(devicePixelRatio);
this.renderer.setSize(innerWidth, innerHeight);
this.renderer.shadowMap.enabled = true;
this.renderer.autoClear = false;
}
- 渲染动作
animate() {
this.renderer.render(this.scene, this.camera);
this.renderer.render(this.hudScene, this.hudCamera);
requestAnimationFrame(() => {
this.animate();
});
}
自此,前置条件全部设置完成,可以开心的开始建立模型了。
第二篇,简述怎么怎么建立模型。
下期见...