最终的成果如左边所示(你能够应用鼠标、手指或者键盘来管制这个机器人的旋转):
本我的项目基于 image3D 实现。
在正式开始之前,咱们须要筹备好模型数据,你能够去这里下载:model.json
如果想疾速体验最终成果,能够点击此处查看。
着色器
首先,你须要筹备好两个着色器。
顶点着色器
<script type='x-shader/x-vertex' id='vs'>
attribute vec3 a_position; // 顶点坐标
uniform mat4 u_matrix; // 变换矩阵
uniform vec3 u_LPosition; // 光的地位
attribute vec3 a_normal;
varying vec3 v_LDirection;
varying vec3 v_normal;
void main(){
// 坐标新增齐次坐标,为了和矩阵对齐
gl_Position=u_matrix * vec4(a_position,1);
// 点光源方向计算:点光源方向 = 点光源坐标 - 顶点坐标
// 顶点的地位应该应用计算过的
v_LDirection=u_LPosition-gl_Position.xyz;
v_normal=a_normal;
}
</script>
片段着色器
<script type='x-shader/x-fragment' id='fs'>
precision mediump float;
uniform vec4 u_LColor; // 光色彩
uniform vec4 u_color; // 顶点色彩
varying vec3 v_LDirection; // 光线方向
varying vec3 v_normal; // 法线方向
void main(){
// 先对方向进行序列化,使得向量长度为 1
vec3 LDirection=normalize(v_LDirection);
vec3 normal=normalize(v_normal);
// 计算序列化后的光方向和法线方向的点乘
float dotValue=max(dot(LDirection,normal),0.2);
gl_FragColor=u_color*u_LColor*dotValue;
}
</script>
画布
也就是一个 canvas:
<canvas width='500' height='500'></canvas>
绘图对象
这个绘图对象上有很多办法,通过这个对象上的办法,就能够实现各种操作了:
import image3D from 'image3d'
// 创立 3D 对象并配置好画布和着色器
let image3d = new image3D(document.getElementsByTagName('canvas')[0], {"vertex-shader": document.getElementById("vs").innerText,
"fragment-shader": document.getElementById("fs").innerText,
depth: true
})
咱们后续须要应用到画笔等,在这里,咱们提前获取好:
let painter = image3d.Painter() // 画笔
let buffer = image3d.Buffer() // 数据传递对象 - 缓冲区
let camera = image3d.Camera() // 相机
设置好相机
相机 camera
上有很多的办法,具体的你能够点击此处,调用这些办法对相机等进行调整后,数据须要传递给 顶点着色器
:
image3d.setUniformMatrix("u_matrix", camera.value())
顶点数据
相机筹备好了当前,就是数据了,也就是 model.js
中的顶点数据:
不同格局的模型数据格式可能不一样,拿咱们这里的数据举例子,顶点的数据都蕴含在:model.geometries[index].data.attributes.position.array
中,因而,咱们只须要把 model.geometries
一个个绘制解决即可,咱们以第一个几何体为例(一个模型数据可能有一个或多个几何体拼接而成):
let position=model.geometries[0].data.attributes.position.array
buffer.write(new Float32Array(position))
.use('a_position', 3, 3, 0)
下面的作用就是把数据 position
写入 GPU 并调配给着色器中的变量a_position
。
绘制
此时,GPU 中曾经记录了好多的点,这些点 3 个连起来就是一个三角形,三角形拼接起来就是几何体了,如何把这些三角形拼接起来?应用画笔:
painter.drawTriangle(0, position.length / 3)
最终的成果你能够点击此处查看。
结束语
本例子的残缺代码寄存在 Github 上:https://github.com/clunch-con…。