当前位置:   article > 正文

Three.js 浅尝:基础3D渲染(二)_three.js如何渲染蛋白质

three.js如何渲染蛋白质

博客前述内容链接:Three.js 浅尝:基础3D渲染(一)

引言

上回书说道…
承接着上一篇博客,我们手里头已经有了构建好的几何对象 cube,后续就该是依着 WebGL 的套路把几何对象给绘制出来。

Three.js 渲染

再一次回顾前文中所抛出的那个 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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

现在我们已经有了构建完毕的 cube,剩下的就是把 cube 放到 scene 里头去、添加一个 camera、通过 renderer 将 cube 渲染出来。(WebGL 的例子较长,这里就不再重复了,请参见上一篇博客内容)

Scene

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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

作为 scene graph 的根节点,Scene 类同样继承自 Object3D 基类,提供 addremove 方法,允许在其下的层级中添加需要渲染的物体(或者 camera、light)。Scene 所提供的更多的是根节点的存储功能,其新增的属性和方法较少,包含 fog(影响该场景下所有物体渲染的雾)以及 overrideMaterial (强制其中所有物体应用该材质渲染)等,其余的便是对 toJSON 等父类中通用方法的实现。

Camera

常见的 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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

一如之前所提的,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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

如果读者对于透视相机较为熟悉的话,PerspectiveCamera 类所添加的这些个属性便很好理解了,分别为 field of view(fov)、视锥长宽比(aspect)、视锥近平面(near)、视锥远平面(far)。

Program & Shader

在介绍最核心的 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
    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/911673
    推荐阅读
    相关标签
      

    闽ICP备14008679号