Three.JS
WebGL本质是一个光栅化API,基于它可以实现更加上层的三维库(Three.JS、Babylon等),这些库通常会抽象出场景、相机、光照、模型等概念,学习这些三维库的使用的同时也能够帮助我们更好的理解WebGL。
几何体(Geometry)
Three.JS的几何体(Geometry)相当于一组顶点坐标、面索引(face indices)、顶点颜色、顶点UV信息、法向量的集合。
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
这里有个新的概念face indices,我们为了绘制一个矩形也需要六个顶点坐标,而且其中还有两个坐标是完全重复的,因此我们可以去除重复的顶点坐标,并通过顶点的索引来表示一个三角面由哪些顶点构成。
材质(Material)
Three.JS的材质(Material)可以理解成一个WebGL的Program,包含一组内置的顶点着色器和片段着色器,并且它会把着色器中用到的Uniform暴露出来给我们修改。
在我们前面的章节中一个WebGL上下文只持有一个Program程序,这比较方便我们的日常使用,我们可以通过一次gl.drawArrays()
来绘制场景中的若干个几何体,这只会对应同一个顶点/片段着色器的执行。而在Three.JS中,每个Material都可以理解成一个Program,这样带来的好处是对于不同的几何体我们可以使用不同的着色器进行渲染来实现不同的视觉效果;
这也意味着我们需要多次gl.drawArrays()
来给GPU发送绘制指令,我们也可以通过合批处理实现性能优化,把相同材质/Program的绘制调用都合并成一个。
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
网格模型(Mesh)
我们通过Mesh来把几何体和材质绑定在一起,这样绘制这个几何体的时候就会应用对应的材质了。模型除了Mesh外还有Line和Point,分别用来绘制线段和点。
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
相机Camera
Three.JS提供了几种不同类型的相机,这对应了不同的投影方式(正交投影、透视投影),也意味着对应着不同的视锥体。
正交投影相机 OrthographicCamera
const camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 ); // left、right、top、bottom、near、far
scene.add( camera );
透视投影相机 PerspectiveCamera
const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); // fov、apsect、zNear、zFar
scene.add( camera );