【Three.js 入门指南】第一章 概述

EngineBUS 发表于 2016-11-3 21:32:50 | 显示全部楼层 [复制链接]
2 477
第1章 概述
EngineBUS enginebus EngineBUS enginebus
本章将介绍WebGL与Three.js的背景知识,如何下载、使用Three.js。阅读完本章后,你将学会使用Three.js实现一个最简单的功能。

EngineBUS enginebus EngineBUS enginebus1.1 WebGL与Three.js本节介绍WebGL与Three.js的相关概念,并通过两者实现同样功能的代码表现Three.js的简洁性。
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus1.1.1 什么是WebGL
EngineBUS enginebus EngineBUS enginebus
WebGL是基于OpenGL ES 2.0的Web标准,可以通过HTML5 Canvas元素作为DOM接口访问。
听起来挺像回事儿的,但是这是什么意思呢?
如果你了解OpenGL,那么我解释起来就比较轻松了。WebGL可以看做是将OpenGL ES(OpenGL for Embedded Systems,OpenGL嵌入式版本,针对手机、游戏机等设备相对较轻量级的版本)移植到了网页平台,像Chrome、Firefox这些现代浏览器都实现了WebGL标准,使用JavaScript就可以用你熟悉的、类似OpenGL的代码编写了。
如果你不了解OpenGL,那也没关系,因为正如Three.js不需要你了解OpenGL或WebGL一样,本书也不需要你预先知道这些知识。你可以把WebGL简单地认为是一种网络标准,定义了一些较底层的图形接口,至于究竟多底层,稍后我们和Three.js代码对比来看。本书不会过多涉及WebGL的相关知识,如果读者想学习的话,市场上有不少相关书籍可供参考。
现在,我们知道了WebGL是一个底层的标准,在这些标准被定义之后,Chrome、Firefox之类的浏览器实现了这些标准。然后,程序员就能通过JavaScript代码,在网页上实现三维图形的渲染了。如果这对你来说还是太抽象,别着急,稍后我们会用具体的例子来说明。

EngineBUS enginebus EngineBUS enginebus1.1.2 什么是Three.js
Three.js是一个3D JavaScript库。
如此简介的描述背后,是作者对其强大功能的自信。
那么,Three.js究竟能用来干什么呢?
Three.js封装了底层的图形接口,使得程序员能够在无需掌握繁冗的图形学知识的情况下,也能用简单的代码实现三维场景的渲染。我们都知道,更高的封装程度往往意味着灵活性的牺牲,但是Three.js在这方面做得很好。几乎不会有WebGL支持而Three.js实现不了的情况,而且就算真的遇到这种情况,你还是能同时使用WebGL去实现,而不会有冲突。当然,除了WebGL之外,Three.js还提供了基于Canvas、SVG标签的渲染器,但由于通常WebGL能够实现更灵活的渲染效果,所以本书主要针对基于WebGL渲染器进行说明。
应用实例
使用Three.js可以实现很多酷炫的效果,比如这个minecraft风格的网页游戏工具库voxel.js

EngineBUS enginebus EngineBUS enginebus

EngineBUS enginebus EngineBUS enginebus精美绝伦的游戏效果
EngineBUS enginebus EngineBUS enginebus

EngineBUS enginebus EngineBUS enginebus或是绚丽的数据可视化效果
EngineBUS enginebus EngineBUS enginebus

EngineBUS enginebus EngineBUS enginebus更多应用可以在Three.js官网查看。
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebusThree.js作者
Mr. doob是Three.js项目发起人和主要贡献者之一,但由于Three.js是Github上一个开源项目,因此有非常多的贡献者,甚至有一天,你也可以在贡献者列表中看到自己的名字。
使用协议
Three.js是基于MIT协议进行发布的,因此使用和发布都非常自由。

EngineBUS enginebus EngineBUS enginebus
1.1.3 WebGL vs. Three.js为了比较说明Three.js能大大简化WebGL的开发,我们使用最简单的例子进行比较:渲染黑色背景下的白色正方形和三角形。效果如图:
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
Three.js需要30行左右的代码:
  1. var renderer = new THREE.WebGLRenderer({
    EngineBUS enginebus EngineBUS enginebus
  2.     canvas: document.getElementById('mainCanvas')
    EngineBUS enginebus EngineBUS enginebus
  3. });
    EngineBUS enginebus EngineBUS enginebus
  4. renderer.setClearColor(0x000000); // black
    EngineBUS enginebus EngineBUS enginebus

  5. EngineBUS enginebus EngineBUS enginebus
  6. var scene = new THREE.Scene();
    EngineBUS enginebus EngineBUS enginebus

  7. EngineBUS enginebus EngineBUS enginebus
  8. var camera = new THREE.PerspectiveCamera(45, 4 / 3, 1, 1000);
    EngineBUS enginebus EngineBUS enginebus
  9. camera.position.set(0, 0, 5);
    EngineBUS enginebus EngineBUS enginebus
  10. camera.lookAt(new THREE.Vector3(0, 0, 0));
    EngineBUS enginebus EngineBUS enginebus
  11. scene.add(camera);
    EngineBUS enginebus EngineBUS enginebus

  12. EngineBUS enginebus EngineBUS enginebus
  13. var material = new THREE.MeshBasicMaterial({
    EngineBUS enginebus EngineBUS enginebus
  14.         color: 0xffffff // white
    EngineBUS enginebus EngineBUS enginebus
  15. });
    EngineBUS enginebus EngineBUS enginebus
  16. // plane
    EngineBUS enginebus EngineBUS enginebus
  17. var planeGeo = new THREE.PlaneGeometry(1.5, 1.5);
    EngineBUS enginebus EngineBUS enginebus
  18. var plane = new THREE.Mesh(planeGeo, material);
    EngineBUS enginebus EngineBUS enginebus
  19. plane.position.x = 1;
    EngineBUS enginebus EngineBUS enginebus
  20. scene.add(plane);
    EngineBUS enginebus EngineBUS enginebus

  21. EngineBUS enginebus EngineBUS enginebus
  22. // triangle
    EngineBUS enginebus EngineBUS enginebus
  23. var triGeo = new THREE.Geometry();
    EngineBUS enginebus EngineBUS enginebus
  24. triGeo.vertices = [new THREE.Vector3(0, -0.8, 0),
    EngineBUS enginebus EngineBUS enginebus
  25.         new THREE.Vector3(-2, -0.8, 0), new THREE.Vector3(-1, 0.8, 0)];
    EngineBUS enginebus EngineBUS enginebus
  26. triGeo.faces.push(new THREE.Face3(0, 2, 1));
    EngineBUS enginebus EngineBUS enginebus
  27. var triangle = new THREE.Mesh(triGeo, material);
    EngineBUS enginebus EngineBUS enginebus
  28. scene.add(triangle);
    EngineBUS enginebus EngineBUS enginebus

  29. EngineBUS enginebus EngineBUS enginebus
  30. renderer.render(scene, camera);
复制代码
如果接触过图形学知识,这里的代码应该很容易理解,如果不懂也没关系,接下来几章会进行详细说明。所以在此就不花费篇章解释这几行代码了。
以下摘录实现相同功能的WebGL代码,来自博客http://learningwebgl.com/blog/?p=28
  1. var gl;
    EngineBUS enginebus EngineBUS enginebus
  2. function initGL(canvas) {
    EngineBUS enginebus EngineBUS enginebus
  3.     try {
    EngineBUS enginebus EngineBUS enginebus
  4.         gl = canvas.getContext("experimental-webgl");
    EngineBUS enginebus EngineBUS enginebus
  5.         gl.viewportWidth = canvas.width;
    EngineBUS enginebus EngineBUS enginebus
  6.         gl.viewportHeight = canvas.height;
    EngineBUS enginebus EngineBUS enginebus
  7.     } catch (e) {
    EngineBUS enginebus EngineBUS enginebus
  8.     }
    EngineBUS enginebus EngineBUS enginebus
  9.     if (!gl) {
    EngineBUS enginebus EngineBUS enginebus
  10.         alert("Could not initialise WebGL, sorry :-(");
    EngineBUS enginebus EngineBUS enginebus
  11.     }
    EngineBUS enginebus EngineBUS enginebus
  12. }
    EngineBUS enginebus EngineBUS enginebus

  13. EngineBUS enginebus EngineBUS enginebus
  14. function getShader(gl, id) {
    EngineBUS enginebus EngineBUS enginebus
  15.     var shaderScript = document.getElementById(id);
    EngineBUS enginebus EngineBUS enginebus
  16.     if (!shaderScript) {
    EngineBUS enginebus EngineBUS enginebus
  17.         return null;
    EngineBUS enginebus EngineBUS enginebus
  18.     }
    EngineBUS enginebus EngineBUS enginebus

  19. EngineBUS enginebus EngineBUS enginebus
  20.     var str = "";
    EngineBUS enginebus EngineBUS enginebus
  21.     var k = shaderScript.firstChild;
    EngineBUS enginebus EngineBUS enginebus
  22.     while (k) {
    EngineBUS enginebus EngineBUS enginebus
  23.         if (k.nodeType == 3) {
    EngineBUS enginebus EngineBUS enginebus
  24.             str += k.textContent;
    EngineBUS enginebus EngineBUS enginebus
  25.         }
    EngineBUS enginebus EngineBUS enginebus
  26.         k = k.nextSibling;
    EngineBUS enginebus EngineBUS enginebus
  27.     }
    EngineBUS enginebus EngineBUS enginebus

  28. EngineBUS enginebus EngineBUS enginebus
  29.     var shader;
    EngineBUS enginebus EngineBUS enginebus
  30.     if (shaderScript.type == "x-shader/x-fragment") {
    EngineBUS enginebus EngineBUS enginebus
  31.         shader = gl.createShader(gl.FRAGMENT_SHADER);
    EngineBUS enginebus EngineBUS enginebus
  32.     } else if (shaderScript.type == "x-shader/x-vertex") {
    EngineBUS enginebus EngineBUS enginebus
  33.         shader = gl.createShader(gl.VERTEX_SHADER);
    EngineBUS enginebus EngineBUS enginebus
  34.     } else {
    EngineBUS enginebus EngineBUS enginebus
  35.         return null;
    EngineBUS enginebus EngineBUS enginebus
  36.     }
    EngineBUS enginebus EngineBUS enginebus

  37. EngineBUS enginebus EngineBUS enginebus
  38.     gl.shaderSource(shader, str);
    EngineBUS enginebus EngineBUS enginebus
  39.     gl.compileShader(shader);
    EngineBUS enginebus EngineBUS enginebus

  40. EngineBUS enginebus EngineBUS enginebus
  41.     if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    EngineBUS enginebus EngineBUS enginebus
  42.         alert(gl.getShaderInfoLog(shader));
    EngineBUS enginebus EngineBUS enginebus
  43.         return null;
    EngineBUS enginebus EngineBUS enginebus
  44.     }
    EngineBUS enginebus EngineBUS enginebus

  45. EngineBUS enginebus EngineBUS enginebus
  46.     return shader;
    EngineBUS enginebus EngineBUS enginebus
  47. }
    EngineBUS enginebus EngineBUS enginebus

  48. EngineBUS enginebus EngineBUS enginebus
  49. var shaderProgram;
    EngineBUS enginebus EngineBUS enginebus

  50. EngineBUS enginebus EngineBUS enginebus
  51. function initShaders() {
    EngineBUS enginebus EngineBUS enginebus
  52.     var fragmentShader = getShader(gl, "shader-fs");
    EngineBUS enginebus EngineBUS enginebus
  53.     var vertexShader = getShader(gl, "shader-vs");
    EngineBUS enginebus EngineBUS enginebus

  54. EngineBUS enginebus EngineBUS enginebus
  55.     shaderProgram = gl.createProgram();
    EngineBUS enginebus EngineBUS enginebus
  56.     gl.attachShader(shaderProgram, vertexShader);
    EngineBUS enginebus EngineBUS enginebus
  57.     gl.attachShader(shaderProgram, fragmentShader);
    EngineBUS enginebus EngineBUS enginebus
  58.     gl.linkProgram(shaderProgram);
    EngineBUS enginebus EngineBUS enginebus

  59. EngineBUS enginebus EngineBUS enginebus
  60.     if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
    EngineBUS enginebus EngineBUS enginebus
  61.         alert("Could not initialise shaders");
    EngineBUS enginebus EngineBUS enginebus
  62.     }
    EngineBUS enginebus EngineBUS enginebus

  63. EngineBUS enginebus EngineBUS enginebus
  64.     gl.useProgram(shaderProgram);
    EngineBUS enginebus EngineBUS enginebus

  65. EngineBUS enginebus EngineBUS enginebus
  66.     shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
    EngineBUS enginebus EngineBUS enginebus
  67.     gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
    EngineBUS enginebus EngineBUS enginebus

  68. EngineBUS enginebus EngineBUS enginebus
  69.     shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
    EngineBUS enginebus EngineBUS enginebus
  70.     shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
    EngineBUS enginebus EngineBUS enginebus
  71. }
    EngineBUS enginebus EngineBUS enginebus

  72. EngineBUS enginebus EngineBUS enginebus
  73. var mvMatrix = mat4.create();
    EngineBUS enginebus EngineBUS enginebus
  74. var pMatrix = mat4.create();
    EngineBUS enginebus EngineBUS enginebus

  75. EngineBUS enginebus EngineBUS enginebus
  76. function setMatrixUniforms() {
    EngineBUS enginebus EngineBUS enginebus
  77.     gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
    EngineBUS enginebus EngineBUS enginebus
  78.     gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
    EngineBUS enginebus EngineBUS enginebus
  79. }
    EngineBUS enginebus EngineBUS enginebus

  80. EngineBUS enginebus EngineBUS enginebus
  81. var triangleVertexPositionBuffer;
    EngineBUS enginebus EngineBUS enginebus
  82. var squareVertexPositionBuffer;
    EngineBUS enginebus EngineBUS enginebus

  83. EngineBUS enginebus EngineBUS enginebus
  84. function initBuffers() {
    EngineBUS enginebus EngineBUS enginebus
  85.     triangleVertexPositionBuffer = gl.createBuffer();
    EngineBUS enginebus EngineBUS enginebus
  86.     gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
    EngineBUS enginebus EngineBUS enginebus
  87.     var vertices = [
    EngineBUS enginebus EngineBUS enginebus
  88.          0.0,  1.0,  0.0,
    EngineBUS enginebus EngineBUS enginebus
  89.         -1.0, -1.0,  0.0,
    EngineBUS enginebus EngineBUS enginebus
  90.          1.0, -1.0,  0.0
    EngineBUS enginebus EngineBUS enginebus
  91.     ];
    EngineBUS enginebus EngineBUS enginebus
  92.     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    EngineBUS enginebus EngineBUS enginebus
  93.     triangleVertexPositionBuffer.itemSize = 3;
    EngineBUS enginebus EngineBUS enginebus
  94.     triangleVertexPositionBuffer.numItems = 3;
    EngineBUS enginebus EngineBUS enginebus

  95. EngineBUS enginebus EngineBUS enginebus
  96.     squareVertexPositionBuffer = gl.createBuffer();
    EngineBUS enginebus EngineBUS enginebus
  97.     gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
    EngineBUS enginebus EngineBUS enginebus
  98.     vertices = [
    EngineBUS enginebus EngineBUS enginebus
  99.          1.0,  1.0,  0.0,
    EngineBUS enginebus EngineBUS enginebus
  100.         -1.0,  1.0,  0.0,
    EngineBUS enginebus EngineBUS enginebus
  101.          1.0, -1.0,  0.0,
    EngineBUS enginebus EngineBUS enginebus
  102.         -1.0, -1.0,  0.0
    EngineBUS enginebus EngineBUS enginebus
  103.     ];
    EngineBUS enginebus EngineBUS enginebus
  104.     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    EngineBUS enginebus EngineBUS enginebus
  105.     squareVertexPositionBuffer.itemSize = 3;
    EngineBUS enginebus EngineBUS enginebus
  106.     squareVertexPositionBuffer.numItems = 4;
    EngineBUS enginebus EngineBUS enginebus
  107. }
    EngineBUS enginebus EngineBUS enginebus

  108. EngineBUS enginebus EngineBUS enginebus
  109. function drawScene() {
    EngineBUS enginebus EngineBUS enginebus
  110.     gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    EngineBUS enginebus EngineBUS enginebus
  111.     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    EngineBUS enginebus EngineBUS enginebus

  112. EngineBUS enginebus EngineBUS enginebus
  113.     mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
    EngineBUS enginebus EngineBUS enginebus

  114. EngineBUS enginebus EngineBUS enginebus
  115.     mat4.identity(mvMatrix);
    EngineBUS enginebus EngineBUS enginebus

  116. EngineBUS enginebus EngineBUS enginebus
  117.     mat4.translate(mvMatrix, [-1.5, 0.0, -7.0]);
    EngineBUS enginebus EngineBUS enginebus
  118.     gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
    EngineBUS enginebus EngineBUS enginebus
  119.     gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
    EngineBUS enginebus EngineBUS enginebus
  120.     setMatrixUniforms();
    EngineBUS enginebus EngineBUS enginebus
  121.     gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);
    EngineBUS enginebus EngineBUS enginebus

  122. EngineBUS enginebus EngineBUS enginebus
  123.     mat4.translate(mvMatrix, [3.0, 0.0, 0.0]);
    EngineBUS enginebus EngineBUS enginebus
  124.     gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
    EngineBUS enginebus EngineBUS enginebus
  125.     gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
    EngineBUS enginebus EngineBUS enginebus
  126.     setMatrixUniforms();
    EngineBUS enginebus EngineBUS enginebus
  127.     gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);
    EngineBUS enginebus EngineBUS enginebus
  128. }
    EngineBUS enginebus EngineBUS enginebus

  129. EngineBUS enginebus EngineBUS enginebus
  130. function webGLStart() {
    EngineBUS enginebus EngineBUS enginebus
  131.     var canvas = document.getElementById("lesson01-canvas");
    EngineBUS enginebus EngineBUS enginebus
  132.     initGL(canvas);
    EngineBUS enginebus EngineBUS enginebus
  133.     initShaders();
    EngineBUS enginebus EngineBUS enginebus
  134.     initBuffers();
    EngineBUS enginebus EngineBUS enginebus

  135. EngineBUS enginebus EngineBUS enginebus
  136.     gl.clearColor(0.0, 0.0, 0.0, 1.0);
    EngineBUS enginebus EngineBUS enginebus
  137.     gl.enable(gl.DEPTH_TEST);
    EngineBUS enginebus EngineBUS enginebus

  138. EngineBUS enginebus EngineBUS enginebus
  139.     drawScene();
    EngineBUS enginebus EngineBUS enginebus
  140. }
复制代码
从上面的代码我们不难发现,使用原生WebGL接口实现同样功能需要5倍多的代码量,而且很多代码对于没有图形学基础的程序员是很难看懂的。由这个例子我们可以看出,使用Three.js开发要比WebGL更快更高效。尤其对图形学知识不熟悉的程序员而言,使用Three.js能够降低学习成本,提高三维图形程序开发的效率。

EngineBUS enginebus EngineBUS enginebus1.2 开始使用Three.js
本节介绍如何下载使用Three.js创建你的第一个程序。

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus1.2.1 准备工作开发环境
Three.js是一个JavaScript库,所以,你可以使用平时开发JavaScript应用的环境开发Three.js应用。如果你没什么偏好的话,我会推荐Komodo IDE
调试建议使用Chrome或者Firefox浏览器。如果你使用的是Firefox,那么Firebug会是你必不可少的插件;如果你使用的是Chrome,那么直接使用控制台调试即可。这些和JavaScript的调试是相同的,因此本书不作进一步展开。
下载
首先,我们需要在Github下载Three.js的代码。
https://github.com/mrdoob/three.js/tree/master/build可以看到three.js和three.min.js两个文件,前者是没有经过代码压缩的,因此适用于调试阶段;后者是经过代码压缩的,调试起来会不太方便,但文件较小,适用于最终的发布版。保存一个文件到本地,这里我们可以选择three.js。
引用
在使用Three.js之前,我们需要在HTML文件中引用该文件:
  1. <script type="text/javascript" src="three.js"></script>
复制代码
然后就能通过全局变量THREE访问到所有属性和方法了。

EngineBUS enginebus EngineBUS enginebus1.2.2 Hello, world!
EngineBUS enginebus EngineBUS enginebus
接下来,我们终于要真正使用Three.js了!
首先,在HTML的<head>部分,需要声明外部文件three.js。
  1. <head>
    EngineBUS enginebus EngineBUS enginebus
  2.     <script type="text/javascript" src="js/three.js"></script>
    EngineBUS enginebus EngineBUS enginebus
  3. </head>
    EngineBUS enginebus EngineBUS enginebus
复制代码
WebGL的渲染是需要HTML5 Canvas元素的,你可以手动在HTML的<body>部分中定义Canvas元素,或者让Three.js帮你生成。这两种选择一般没有多大差别,我们在此手动在HTML中定义:

EngineBUS enginebus EngineBUS enginebus
  1. <body onload="init()">
    EngineBUS enginebus EngineBUS enginebus
  2.     <canvas id="mainCanvas" width="400px" height="300px" ></canvas>
    EngineBUS enginebus EngineBUS enginebus
  3. </body>
复制代码
在JavaScript代码中定义一个init函数,在HTML加载完后执行:
EngineBUS enginebus EngineBUS enginebus
  1. function init() {
    EngineBUS enginebus EngineBUS enginebus
  2.     // ...
    EngineBUS enginebus EngineBUS enginebus
  3. }
复制代码

EngineBUS enginebus EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
一个典型的Three.js程序至少要包括渲染器(Renderer)、场景(Scene)、照相机(Camera),以及你在场景中创建的物体。这些话题将在后面几章中进一步展开,这里我们将介绍如何快速地使用这些东西。
渲染器(Renderer)
渲染器将和Canvas元素进行绑定,如果之前在HTML中手动定义了id为mainCanvas的Canvas元素,那么Renderer可以这样写:
  1. var renderer = new THREE.WebGLRenderer({
    EngineBUS enginebus EngineBUS enginebus
  2.     canvas: document.getElementById('mainCanvas')
    EngineBUS enginebus EngineBUS enginebus
  3. });
复制代码
而如果想要Three.js生成Canvas元素,在HTML中就不需要定义Canvas元素,在JavaScript代码中可以这样写:
  1. var renderer = new THREE.WebGLRenderer();
    EngineBUS enginebus EngineBUS enginebus
  2. renderer.setSize(400, 300);
    EngineBUS enginebus EngineBUS enginebus
  3. document.getElementsByTagName('body')[0].appendChild(renderer.domElement);
    EngineBUS enginebus EngineBUS enginebus
复制代码
上面代码的第二行表示设置Canvas的宽400像素,高300像素。第三行将渲染器对应的Canvas元素添加到<body>中。
我们可以使用下面的代码将背景色(用于清除画面的颜色)设置为黑色:
  1. renderer.setClearColor(0x000000);
    EngineBUS enginebus EngineBUS enginebus
复制代码
场景(Scene)
在Three.js中添加的物体都是添加到场景中的,因此它相当于一个大容器。一般说,场景里没有很复杂的操作,在程序最开始的时候进行实例化,然后将物体添加到场景中即可。

EngineBUS enginebus EngineBUS enginebus
  1. var scene = new THREE.Scene();
复制代码
照相机(Camera)
在介绍照相机设置前,我们先来简单了解下坐标系。WebGL和Three.js使用的坐标系是右手坐标系,看起来就是这样的:
这里,我们定义了一个透视投影的照相机,具体原理将在下一章中展开。
  1. var camera = new THREE.PerspectiveCamera(45, 4 / 3, 1, 1000);
    EngineBUS enginebus EngineBUS enginebus
  2. camera.position.set(0, 0, 5);
    EngineBUS enginebus EngineBUS enginebus
  3. scene.add(camera);
复制代码
值得注意的是,照相机也需要被添加到场景中。
长方体
我们要创建一个x、y、z方向长度分别为1、2、3的长方体,并将其设置为红色。
  1. var cube = new THREE.Mesh(new THREE.CubeGeometry(1, 2, 3),
    EngineBUS enginebus EngineBUS enginebus
  2.         new THREE.MeshBasicMaterial({
    EngineBUS enginebus EngineBUS enginebus
  3.             color: 0xff0000
    EngineBUS enginebus EngineBUS enginebus
  4.         })
    EngineBUS enginebus EngineBUS enginebus
  5. );
    EngineBUS enginebus EngineBUS enginebus
  6. scene.add(cube);
复制代码
这段代码也是比较容易理解的,虽然你现在可能还不知道MeshBasicMaterial是什么,但是大致可以猜测出这是一种材质,可以用来设置物体的颜色。还是要提醒下,一定要记得把创建好的长方体添加到场景中。
那么这里长度为1的单位是什么呢?这里的长度是在物体坐标系中的,其单位与屏幕分辨率等无关,简单地说,它就是一个虚拟空间的坐标系,1代表多少并没有实际的意义,而重要的是相对长度。
渲染
在定义了场景中的物体,设置好的照相机之后,渲染器就知道如何渲染出二维的结果了。这时候,我们只需要调用渲染器的渲染函数,就能使其渲染一次了。
  1. renderer.render(scene, camera);
复制代码

EngineBUS enginebus EngineBUS enginebus完整代码
最终,这是我们得到的完整的init函数:
例1.2.1 <= 点此查看完整源代码,下略
  1. function init() {
    EngineBUS enginebus EngineBUS enginebus
  2.     // renderer
    EngineBUS enginebus EngineBUS enginebus
  3.     var renderer = new THREE.WebGLRenderer({
    EngineBUS enginebus EngineBUS enginebus
  4.         canvas: document.getElementById('mainCanvas')
    EngineBUS enginebus EngineBUS enginebus
  5.     });
    EngineBUS enginebus EngineBUS enginebus
  6.     renderer.setClearColor(0x000000); // black
    EngineBUS enginebus EngineBUS enginebus

  7. EngineBUS enginebus EngineBUS enginebus
  8.     // scene
    EngineBUS enginebus EngineBUS enginebus
  9.     var scene = new THREE.Scene();
    EngineBUS enginebus EngineBUS enginebus

  10. EngineBUS enginebus EngineBUS enginebus
  11.     // camera
    EngineBUS enginebus EngineBUS enginebus
  12.     var camera = new THREE.PerspectiveCamera(45, 4 / 3, 1, 1000);
    EngineBUS enginebus EngineBUS enginebus
  13.     camera.position.set(0, 0, 5);
    EngineBUS enginebus EngineBUS enginebus
  14.     scene.add(camera);
    EngineBUS enginebus EngineBUS enginebus

  15. EngineBUS enginebus EngineBUS enginebus
  16.     // a cube in the scene
    EngineBUS enginebus EngineBUS enginebus
  17.     var cube = new THREE.Mesh(new THREE.CubeGeometry(1, 2, 3),
    EngineBUS enginebus EngineBUS enginebus
  18.             new THREE.MeshBasicMaterial({
    EngineBUS enginebus EngineBUS enginebus
  19.                 color: 0xff0000
    EngineBUS enginebus EngineBUS enginebus
  20.             })
    EngineBUS enginebus EngineBUS enginebus
  21.     );
    EngineBUS enginebus EngineBUS enginebus
  22.     scene.add(cube);
    EngineBUS enginebus EngineBUS enginebus

  23. EngineBUS enginebus EngineBUS enginebus
  24.     // render
    EngineBUS enginebus EngineBUS enginebus
  25.     renderer.render(scene, camera);
    EngineBUS enginebus EngineBUS enginebus
  26. }
复制代码
渲染的效果是:
出问题了?
第一件事就是打开浏览器的控制台,查看报错信息。如果错误信息是ReferenceError: THREE is not defined,那么就是页面没有成功加载Three.js库,很有可能的原因是文件的路径写错了,一定要小心检查。
如果存在其他问题,请参见前言中“寻求帮助”部分。

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus1.3 Three.js功能概览
EngineBUS enginebus EngineBUS enginebus上一节,我们了解了如何建立一个简单的Three.js应用,可能有读者会对各种概念表示困惑,那么下面就让我们看下Three.js官网文档中的一些重要的对象,在你需要寻求帮助时,就能够知道关键词是什么。
EngineBUS enginebus EngineBUS enginebus

EngineBUS enginebus EngineBUS enginebus
  1. Cameras(照相机,控制投影方式)
    EngineBUS enginebus EngineBUS enginebus

  2. EngineBUS enginebus EngineBUS enginebus
  3.     Camera
    EngineBUS enginebus EngineBUS enginebus
  4.     OrthographicCamera
    EngineBUS enginebus EngineBUS enginebus
  5.     PerspectiveCamera
    EngineBUS enginebus EngineBUS enginebus

  6. EngineBUS enginebus EngineBUS enginebus
  7. Core(核心对象)
    EngineBUS enginebus EngineBUS enginebus

  8. EngineBUS enginebus EngineBUS enginebus
  9.     BufferGeometry
    EngineBUS enginebus EngineBUS enginebus
  10.     Clock(用来记录时间)
    EngineBUS enginebus EngineBUS enginebus
  11.     EventDispatcher
    EngineBUS enginebus EngineBUS enginebus
  12.     Face3
    EngineBUS enginebus EngineBUS enginebus
  13.     Face4
    EngineBUS enginebus EngineBUS enginebus
  14.     Geometry
    EngineBUS enginebus EngineBUS enginebus
  15.     Object3D
    EngineBUS enginebus EngineBUS enginebus
  16.     Projector
    EngineBUS enginebus EngineBUS enginebus
  17.     Raycaster(计算鼠标拾取物体时很有用的对象)
    EngineBUS enginebus EngineBUS enginebus

  18. EngineBUS enginebus EngineBUS enginebus
  19. Lights(光照)
    EngineBUS enginebus EngineBUS enginebus
  20.     Light
    EngineBUS enginebus EngineBUS enginebus
  21.     AmbientLight
    EngineBUS enginebus EngineBUS enginebus
  22.     AreaLight
    EngineBUS enginebus EngineBUS enginebus
  23.     DirectionalLight
    EngineBUS enginebus EngineBUS enginebus
  24.     HemisphereLight
    EngineBUS enginebus EngineBUS enginebus
  25.     PointLight
    EngineBUS enginebus EngineBUS enginebus
  26.     SpotLight
    EngineBUS enginebus EngineBUS enginebus

  27. EngineBUS enginebus EngineBUS enginebus
  28. Loaders(加载器,用来加载特定文件)
    EngineBUS enginebus EngineBUS enginebus
  29.     Loader
    EngineBUS enginebus EngineBUS enginebus
  30.     BinaryLoader
    EngineBUS enginebus EngineBUS enginebus
  31.     GeometryLoader
    EngineBUS enginebus EngineBUS enginebus
  32.     ImageLoader
    EngineBUS enginebus EngineBUS enginebus
  33.     JSONLoader
    EngineBUS enginebus EngineBUS enginebus
  34.     LoadingMonitor
    EngineBUS enginebus EngineBUS enginebus
  35.     SceneLoader
    EngineBUS enginebus EngineBUS enginebus
  36.     TextureLoader
    EngineBUS enginebus EngineBUS enginebus

  37. EngineBUS enginebus EngineBUS enginebus
  38. Materials(材质,控制物体的颜色、纹理等)
    EngineBUS enginebus EngineBUS enginebus
  39.     Material
    EngineBUS enginebus EngineBUS enginebus
  40.     LineBasicMaterial
    EngineBUS enginebus EngineBUS enginebus
  41.     LineDashedMaterial
    EngineBUS enginebus EngineBUS enginebus
  42.     MeshBasicMaterial
    EngineBUS enginebus EngineBUS enginebus
  43.     MeshDepthMaterial
    EngineBUS enginebus EngineBUS enginebus
  44.     MeshFaceMaterial
    EngineBUS enginebus EngineBUS enginebus
  45.     MeshLambertMaterial
    EngineBUS enginebus EngineBUS enginebus
  46.     MeshNormalMaterial
    EngineBUS enginebus EngineBUS enginebus
  47.     MeshPhongMaterial
    EngineBUS enginebus EngineBUS enginebus
  48.     ParticleBasicMaterial
    EngineBUS enginebus EngineBUS enginebus
  49.     ParticleCanvasMaterial
    EngineBUS enginebus EngineBUS enginebus
  50.     ParticleDOMMaterial
    EngineBUS enginebus EngineBUS enginebus
  51.     ShaderMaterial
    EngineBUS enginebus EngineBUS enginebus
  52.     SpriteMaterial
    EngineBUS enginebus EngineBUS enginebus

  53. EngineBUS enginebus EngineBUS enginebus
  54. Math(和数学相关的对象)
    EngineBUS enginebus EngineBUS enginebus

  55. EngineBUS enginebus EngineBUS enginebus
  56.     Box2
    EngineBUS enginebus EngineBUS enginebus
  57.     Box3
    EngineBUS enginebus EngineBUS enginebus
  58.     Color
    EngineBUS enginebus EngineBUS enginebus
  59.     Frustum
    EngineBUS enginebus EngineBUS enginebus
  60.     Math
    EngineBUS enginebus EngineBUS enginebus
  61.     Matrix3
    EngineBUS enginebus EngineBUS enginebus
  62.     Matrix4
    EngineBUS enginebus EngineBUS enginebus
  63.     Plane
    EngineBUS enginebus EngineBUS enginebus
  64.     Quaternion
    EngineBUS enginebus EngineBUS enginebus
  65.     Ray
    EngineBUS enginebus EngineBUS enginebus
  66.     Sphere
    EngineBUS enginebus EngineBUS enginebus
  67.     Spline
    EngineBUS enginebus EngineBUS enginebus
  68.     Triangle
    EngineBUS enginebus EngineBUS enginebus
  69.     Vector2
    EngineBUS enginebus EngineBUS enginebus
  70.     Vector3
    EngineBUS enginebus EngineBUS enginebus
  71.     Vector4
    EngineBUS enginebus EngineBUS enginebus

  72. EngineBUS enginebus EngineBUS enginebus
  73. Objects(物体)
    EngineBUS enginebus EngineBUS enginebus

  74. EngineBUS enginebus EngineBUS enginebus
  75.     Bone
    EngineBUS enginebus EngineBUS enginebus
  76.     Line
    EngineBUS enginebus EngineBUS enginebus
  77.     LOD
    EngineBUS enginebus EngineBUS enginebus
  78.     Mesh(网格,最常用的物体)
    EngineBUS enginebus EngineBUS enginebus
  79.     MorphAnimMesh
    EngineBUS enginebus EngineBUS enginebus
  80.     Particle
    EngineBUS enginebus EngineBUS enginebus
  81.     ParticleSystem
    EngineBUS enginebus EngineBUS enginebus
  82.     Ribbon
    EngineBUS enginebus EngineBUS enginebus
  83.     SkinnedMesh
    EngineBUS enginebus EngineBUS enginebus
  84.     Sprite
    EngineBUS enginebus EngineBUS enginebus

  85. EngineBUS enginebus EngineBUS enginebus
  86. Renderers(渲染器,可以渲染到不同对象上)
    EngineBUS enginebus EngineBUS enginebus

  87. EngineBUS enginebus EngineBUS enginebus
  88.     CanvasRenderer
    EngineBUS enginebus EngineBUS enginebus
  89.     WebGLRenderer(使用WebGL渲染,这是本书中最常用的方式)
    EngineBUS enginebus EngineBUS enginebus
  90.     WebGLRenderTarget
    EngineBUS enginebus EngineBUS enginebus
  91.     WebGLRenderTargetCube
    EngineBUS enginebus EngineBUS enginebus
  92.     WebGLShaders(着色器,在最后一章作介绍)
    EngineBUS enginebus EngineBUS enginebus

  93. EngineBUS enginebus EngineBUS enginebus
  94. Renderers / Renderables
    EngineBUS enginebus EngineBUS enginebus

  95. EngineBUS enginebus EngineBUS enginebus
  96.     RenderableFace3
    EngineBUS enginebus EngineBUS enginebus
  97.     RenderableFace4
    EngineBUS enginebus EngineBUS enginebus
  98.     RenderableLine
    EngineBUS enginebus EngineBUS enginebus
  99.     RenderableObject
    EngineBUS enginebus EngineBUS enginebus
  100.     RenderableParticle
    EngineBUS enginebus EngineBUS enginebus
  101.     RenderableVertex
    EngineBUS enginebus EngineBUS enginebus

  102. EngineBUS enginebus EngineBUS enginebus
  103. Scenes(场景)
    EngineBUS enginebus EngineBUS enginebus

  104. EngineBUS enginebus EngineBUS enginebus
  105.     Fog
    EngineBUS enginebus EngineBUS enginebus
  106.     FogExp2
    EngineBUS enginebus EngineBUS enginebus
  107.     Scene
    EngineBUS enginebus EngineBUS enginebus

  108. EngineBUS enginebus EngineBUS enginebus
  109. Textures(纹理)
    EngineBUS enginebus EngineBUS enginebus

  110. EngineBUS enginebus EngineBUS enginebus
  111.     CompressedTexture
    EngineBUS enginebus EngineBUS enginebus
  112.     DataTexture
    EngineBUS enginebus EngineBUS enginebus
  113.     Texture
    EngineBUS enginebus EngineBUS enginebus

  114. EngineBUS enginebus EngineBUS enginebus
  115. Extras
    EngineBUS enginebus EngineBUS enginebus

  116. EngineBUS enginebus EngineBUS enginebus
  117.     FontUtils
    EngineBUS enginebus EngineBUS enginebus
  118.     GeometryUtils
    EngineBUS enginebus EngineBUS enginebus
  119.     ImageUtils
    EngineBUS enginebus EngineBUS enginebus
  120.     SceneUtils
    EngineBUS enginebus EngineBUS enginebus

  121. EngineBUS enginebus EngineBUS enginebus
  122. Extras / Animation
    EngineBUS enginebus EngineBUS enginebus

  123. EngineBUS enginebus EngineBUS enginebus
  124.     Animation
    EngineBUS enginebus EngineBUS enginebus
  125.     AnimationHandler
    EngineBUS enginebus EngineBUS enginebus
  126.     AnimationMorphTarget
    EngineBUS enginebus EngineBUS enginebus
  127.     KeyFrameAnimation
    EngineBUS enginebus EngineBUS enginebus

  128. EngineBUS enginebus EngineBUS enginebus
  129. Extras / Cameras
    EngineBUS enginebus EngineBUS enginebus

  130. EngineBUS enginebus EngineBUS enginebus
  131.     CombinedCamera
    EngineBUS enginebus EngineBUS enginebus
  132.     CubeCamera
    EngineBUS enginebus EngineBUS enginebus

  133. EngineBUS enginebus EngineBUS enginebus
  134. Extras / Core
    EngineBUS enginebus EngineBUS enginebus

  135. EngineBUS enginebus EngineBUS enginebus
  136.     Curve
    EngineBUS enginebus EngineBUS enginebus
  137.     CurvePath
    EngineBUS enginebus EngineBUS enginebus
  138.     Gyroscope
    EngineBUS enginebus EngineBUS enginebus
  139.     Path
    EngineBUS enginebus EngineBUS enginebus
  140.     Shape
    EngineBUS enginebus EngineBUS enginebus

  141. EngineBUS enginebus EngineBUS enginebus
  142. Extras / Geometries(几何形状)
    EngineBUS enginebus EngineBUS enginebus

  143. EngineBUS enginebus EngineBUS enginebus
  144.     CircleGeometry
    EngineBUS enginebus EngineBUS enginebus
  145.     ConvexGeometry
    EngineBUS enginebus EngineBUS enginebus
  146.     CubeGeometry
    EngineBUS enginebus EngineBUS enginebus
  147.     CylinderGeometry
    EngineBUS enginebus EngineBUS enginebus
  148.     ExtrudeGeometry
    EngineBUS enginebus EngineBUS enginebus
  149.     IcosahedronGeometry
    EngineBUS enginebus EngineBUS enginebus
  150.     LatheGeometry
    EngineBUS enginebus EngineBUS enginebus
  151.     OctahedronGeometry
    EngineBUS enginebus EngineBUS enginebus
  152.     ParametricGeometry
    EngineBUS enginebus EngineBUS enginebus
  153.     PlaneGeometry
    EngineBUS enginebus EngineBUS enginebus
  154.     PolyhedronGeometry
    EngineBUS enginebus EngineBUS enginebus
  155.     ShapeGeometry
    EngineBUS enginebus EngineBUS enginebus
  156.     SphereGeometry
    EngineBUS enginebus EngineBUS enginebus
  157.     TetrahedronGeometry
    EngineBUS enginebus EngineBUS enginebus
  158.     TextGeometry
    EngineBUS enginebus EngineBUS enginebus
  159.     TorusGeometry
    EngineBUS enginebus EngineBUS enginebus
  160.     TorusKnotGeometry
    EngineBUS enginebus EngineBUS enginebus
  161.     TubeGeometry
    EngineBUS enginebus EngineBUS enginebus

  162. EngineBUS enginebus EngineBUS enginebus
  163. Extras / Helpers
    EngineBUS enginebus EngineBUS enginebus

  164. EngineBUS enginebus EngineBUS enginebus
  165.     ArrowHelper
    EngineBUS enginebus EngineBUS enginebus
  166.     AxisHelper
    EngineBUS enginebus EngineBUS enginebus
  167.     CameraHelper
    EngineBUS enginebus EngineBUS enginebus
  168.     DirectionalLightHelper
    EngineBUS enginebus EngineBUS enginebus
  169.     HemisphereLightHelper
    EngineBUS enginebus EngineBUS enginebus
  170.     PointLightHelper
    EngineBUS enginebus EngineBUS enginebus
  171.     SpotLightHelper
    EngineBUS enginebus EngineBUS enginebus

  172. EngineBUS enginebus EngineBUS enginebus
  173. Extras / Objects
    EngineBUS enginebus EngineBUS enginebus

  174. EngineBUS enginebus EngineBUS enginebus
  175.     ImmediateRenderObject
    EngineBUS enginebus EngineBUS enginebus
  176.     LensFlare
    EngineBUS enginebus EngineBUS enginebus
  177.     MorphBlendMesh
    EngineBUS enginebus EngineBUS enginebus

  178. EngineBUS enginebus EngineBUS enginebus
  179. Extras / Renderers / Plugins
    EngineBUS enginebus EngineBUS enginebus

  180. EngineBUS enginebus EngineBUS enginebus
  181.     DepthPassPlugin
    EngineBUS enginebus EngineBUS enginebus
  182.     LensFlarePlugin
    EngineBUS enginebus EngineBUS enginebus
  183.     ShadowMapPlugin
    EngineBUS enginebus EngineBUS enginebus
  184.     SpritePlugin
    EngineBUS enginebus EngineBUS enginebus

  185. EngineBUS enginebus EngineBUS enginebus
  186. Extras / Shaders
    EngineBUS enginebus EngineBUS enginebus

  187. EngineBUS enginebus EngineBUS enginebus
  188.     ShaderFlares
    EngineBUS enginebus EngineBUS enginebus
  189.     ShaderSprite
复制代码

EngineBUS enginebus EngineBUS enginebus
我们看到,Three.js功能是十分丰富的,一时间想全部掌握有些困难。本书将从Three.js程序常用的功能着手,带领大家入门Three.js。
在接下来的章节中,我们将会先详细介绍照相机、几何形状、材质、物体等入门级知识;然后介绍使用动画、模型导入、加入光照等功能;最后,对于学有余力的读者,我们将介绍着色器,用于更高级的图形渲染。

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?Sign Up

x
发表于 2016-11-4 11:52:09 | 显示全部楼层
优质好文,入门three.js的简单教程
发表于 2016-11-3 21:32:50 | 显示全部楼层
这个教程居然是一个研究生妹子写的,作为入门指引非常不错。大家一起学习
Nothing seek, nothing find.
您需要登录后才可以回帖 登录 | Sign Up

本版积分规则

推荐阅读

QQ| Archiver|手机版|小黑屋| 引擎巴士 EngineBUS  

Powered by Discuz! X3.2© 2001-2013 Comsenz Inc.  

返回顶部 返回列表