three.js是一个可使用javascript绘制3d图形的库,它对WebGL的api进行封装,使开发更加方便,就像jQuery对DOM的api进行封装同样。接下来就记录一下在小游戏中绘制一个 旋转的三角形的步骤:javascript
下载微信官方的开发者工具,而后新建项目html
appid选择测试号便可,项目路径自行指定java
用编辑器打开项目,获得以下目录:git
而后除了game.js,game.json, project.config.json所有删除,并把game.js中的内容清空。github
game.js是整个小游戏的入口,game.json是小游戏配置。具体参考文档。json
Adaptercanvas
小游戏的运行环境中是没有 BOM 和 DOM 的,使用 wx API 模拟 BOM 和 DOM 的代码组成的库称之为 Adapter。官方提供了一个Adapter,用它就好了。api
Adapter文档bash
three.js微信
复制three.min.js中的内容
新建目录libs,将three.js和Adapter的源码放在该目录下
在game.js中添加:
import './libs/weapp-adapter'
import * as THREE from './libs/three'
复制代码
根据adapter的文档只要引入了adapter就会建立一个上屏 Canvas,并暴露为一个全局变量 canvas。
使用three.js渲染一个图形必备的三个条件:渲染器,场景,相机
Renderer 渲染器
渲染器看名字就知道了,就是用于将图形渲染到屏幕上的方法。
Scene 场景
假如把绘制的图形看作是一个个物体的话,那么场景就是用来存放这些物体的地方。
Camera 相机
相机就好像人的眼睛同样,相机用于肯定在什么地方去看场景中的物体,就好像有一个东西,不一样的角度去看这个物体,看到的有多是不同的形状。
在game.js 中建立这三个东西
import './libs/weapp-adapter'
import * as THREE from './libs/three'
const width = window.innerWidth
const height = window.innerHeight
// 建立WebGL渲染器
const renderer = new THREE.WebGLRenderer({
// 因为weapp-adapter会自动建立一个全屏的canvas因此这里直接用
canvas
})
// 建立场景
const scene = new THREE.Scene()
/**
* OrthographicCamera是正交相机,
* 在这种投影模式下,不管物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。
*/
const camera = new THREE.OrthographicCamera(-width / 2, width / 2, height / 2, -height / 2, 0, 1000)
复制代码
new THREE.OrthographicCamera
的参数能够参考官方文档或者Three.js基础探寻二——正交投影照相机
如今必要的三个条件都有了,就要添加物体到场景中了。
物体在three.js中叫作mesh,它由几何体(geometry)和材料(material)组成。
个人理解就是几何体就是物体的基本形状,就像WebGL中的顶点着色器,材料就是几何体的颜色啊,光照等信息,就像WebGL中的片元着色器。
three.js中提供了不少几何体,可是好像没有基本的三角形,因此要本身画一个三角形。
在game.js 中添加:
// 画一个三角形
const triangleShape = new THREE.Shape()
triangleShape.moveTo(0, 100) // 三角形起始位置
triangleShape.lineTo(-100, -100)
triangleShape.lineTo(100, -100)
triangleShape.lineTo(0, 100)
复制代码
这里说一下three.js的坐标系
有了三角形的基本形状,经过three.js中提供的api,将这个三角形变成几何体
在game.js 中添加:
// 将三角形变成组成物体的几何体
const geometry = new THREE.ShapeGeometry(triangleShape)
复制代码
组成物体的几何体就搞定了。
而后就是材料了:
在game.js 中添加:
// 物体的材料
const material = new THREE.MeshBasicMaterial({
color: new THREE.Color('#7fffd4'), // 颜色信息
side: THREE.DoubleSide // 用于肯定渲染哪一面,由于是旋转的,因此须要正反面都渲染,也就是两面
})
复制代码
用几何体 + 材料组成物体,并添加到场景中:
// 组成物体并添加到场景中
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(0, 0, -200) // 设置物体在场景中的位置
scene.add(mesh)
复制代码
设置相机的位置以及看向的坐标
camera.position.set(0, 0, 0) // 相机位置
camera.lookAt(new THREE.Vector3(0, 0, -200)) // 让相机从0, 0, 0 看向 0, 0, -200
复制代码
最后一步就是渲染了:
renderer.setClearColor(new THREE.Color('#f84462')) // 设置背景色
renderer.setSize(width, height) // 设置最终渲染的尺寸
renderer.render(scene, camera)
复制代码
这时候去在开发者工具中就能够看到一个三角形了:
const render = () => {
mesh.rotateY(0.05) // three.js 中旋转角度是经过弧度计算的,公式:度=弧度×180°/π
renderer.render(scene, camera)
requestAnimationFrame(render)
}
render()
复制代码
效果:
完整代码:
import './libs/weapp-adapter'
import * as THREE from './libs/three'
const width = window.innerWidth
const height = window.innerHeight
// 建立WebGL渲染器
const renderer = new THREE.WebGLRenderer({
// 因为weapp-adapter会自动建立一个全屏的canvas因此这里直接用
canvas
})
// 建立场景
const scene = new THREE.Scene()
/**
* OrthographicCamera是正交相机,
* 在这种投影模式下,不管物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。
*/
const camera = new THREE.OrthographicCamera(-width / 2, width / 2, height / 2, -height / 2, 0, 1000)
// 画一个三角形
const triangleShape = new THREE.Shape()
triangleShape.moveTo(0, 100) // 三角形起始位置
triangleShape.lineTo(-100, -100)
triangleShape.lineTo(100, -100)
triangleShape.lineTo(0, 100)
// 将三角形变成组成物体的几何体
const geometry = new THREE.ShapeGeometry(triangleShape)
// 物体的材料
const material = new THREE.MeshBasicMaterial({
color: new THREE.Color('#7fffd4'), // 颜色信息
side: THREE.DoubleSide // 用于肯定渲染哪一面,由于是旋转的,因此须要正反面都渲染,也就是两面
})
// 组成物体并添加到场景中
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(0, 0, -200) // 设置物体在场景中的位置
scene.add(mesh)
camera.position.set(0, 0, 0) // 相机位置
camera.lookAt(new THREE.Vector3(0, 0, -200)) // 让相机从0, 0, 0 看向 0, 0, -200
renderer.setClearColor(new THREE.Color('#f84462')) // 设置背景色
renderer.setSize(width, height) // 设置最终渲染的尺寸
const render = () => {
mesh.rotateY(0.05) // three.js 中旋转角度是经过弧度计算的,公式:度=弧度×180°/π
renderer.render(scene, camera)
requestAnimationFrame(render)
}
render()
复制代码