赞
踩
博客前述内容链接:Three.js 浅尝:基础3D渲染(一)
上回书说道…
承接着上一篇博客,我们手里头已经有了构建好的几何对象 cube,后续就该是依着 WebGL 的套路把几何对象给绘制出来。
再一次回顾前文中所抛出的那个 Three.js 的例子:
const canvas = document.querySelector('#canvas'); const renderer = new THREE.WebGLRenderer({ canvas}); const camera = new THREE.PerspectiveCamera(); camera.position.z = 2; const scene = new THREE.Scene(); const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshBasicMaterial({ color: 0xffffff}); const cube = new THREE.Mesh(geometry, material); cube.rotation.x = 2; cube.rotation.z = -1; scene.add(cube); renderer.render(scene, camera);
现在我们已经有了构建完毕的 cube,剩下的就是把 cube 放到 scene 里头去、添加一个 camera、通过 renderer 将 cube 渲染出来。(WebGL 的例子较长,这里就不再重复了,请参见上一篇博客内容)
Scene
类的声明相当简单:
/** * Scenes allow you to set up what and where is to be rendered by three.js. This is where you place objects, lights and cameras. */ export class Scene extends Object3D { constructor(); type: 'Scene'; /** * A fog instance defining the type of fog that affects everything rendered in the scene. Default is null. */ fog: IFog | null; /** * If not null, it will force everything in the scene to be rendered with that material. Default is null. */ overrideMaterial: Material | null; autoUpdate: boolean; background: null | Color | Texture; ...balabala }
作为 scene graph 的根节点,Scene
类同样继承自 Object3D
基类,提供 add
与 remove
方法,允许在其下的层级中添加需要渲染的物体(或者 camera、light)。Scene
所提供的更多的是根节点的存储功能,其新增的属性和方法较少,包含 fog
(影响该场景下所有物体渲染的雾)以及 overrideMaterial
(强制其中所有物体应用该材质渲染)等,其余的便是对 toJSON
等父类中通用方法的实现。
常见的 PerspectiveCamera
以及 OrthographicCamera
均继承自基类 Camera
,其定义如下所示:
/** * Abstract base class for cameras. This class should always be inherited when you build a new camera. */ export class Camera extends Object3D { /** * This constructor sets following properties to the correct type: matrixWorldInverse, projectionMatrix and projectionMatrixInverse. */ constructor(); /** * This is the inverse of matrixWorld. MatrixWorld contains the Matrix which has the world transform of the Camera. */ matrixWorldInverse: Matrix4; /** * This is the matrix which contains the projection. */ projectionMatrix: Matrix4; /** * This is the inverse of projectionMatrix. */ projectionMatrixInverse: Matrix4; isCamera: true; getWorldDirection( target: Vector3 ): Vector3; updateMatrixWorld( force?: boolean ): void; }
一如之前所提的,Camera
也同样继承自 Object3D
基类,这也就意味着 Camera
类也支持旋转、平移等操作,即包含了变换矩阵。该变换矩阵由 Object3D
类中的 matrixWorld
属性存储,也就是模型矩阵(Model Matrix)。除去模型矩阵,作为 camera 也必然需要提供投影矩阵(Projection Matrix),即 projectMatrix
属性。
在 Camera
基类的基础上,不同的 camera 为其添加了所需的属性,以程序中所使用的 PerspectiveCamera
为例:
export class PerspectiveCamera extends Camera { /** * @param fov Camera frustum vertical field of view. Default value is 50. * @param aspect Camera frustum aspect ratio. Default value is 1. * @param near Camera frustum near plane. Default value is 0.1. * @param far Camera frustum far plane. Default value is 2000. */ constructor( fov?: number, aspect?: number, near?: number, far?: number ); type: 'PerspectiveCamera'; isPerspectiveCamera: true; zoom: number; /** * Camera frustum vertical field of view, from bottom to top of view, in degrees. */ fov: number; /** * Camera frustum aspect ratio, window width divided by window height. */ aspect: number; /** * Camera frustum near plane. */ near: number; /** * Camera frustum far plane. */ far: number; ...balabala }
如果读者对于透视相机较为熟悉的话,PerspectiveCamera
类所添加的这些个属性便很好理解了,分别为 field of view(fov
)、视锥长宽比(aspect
)、视锥近平面(near
)、视锥远平面(far
)。
在介绍最核心的 WebGLRenderer
类之前,还有一些类需要我们关注。虽然承担了最为重要的 render
api,但是在 Three.js 的设计中 WebGLRenderer
并不大包大揽,其中 WebGLProgram
实例以及 WebGLShader
实例的管理就交给了 Three.js 中同名类(请注意区分 WebGL 与 Three.js 中的 WebGLProgram
类与 WebGLShader
类,后者是对前者的封装。后续如无特殊声明则指 Three.js 中的类)。
上一篇博客中给出了 WebGL 绘制 cube 的一个例子,其出于教学目的省略了一些初始化的步骤。例子首先会调用额外提供的 getWebGLContext
函数获取到 WebGL context,其中隐藏了创建并启用 WebGLProgram
实例的过程。
在简单的渲染应用中,单一的 WebGLProgram
或许已经足以满足需求,但是需要实现 Three.js 所提供的复杂功能,便要求多个 WebGLProgram
实例的存在,其中每个实例均关联着两个 WebGLShader
,分别为顶点着色器与片段着色器。
着色器的封装十分简单,只需要根据字符串创建 WebGL 的 WebGLShader
实例:
function WebGLShader
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。