Creating-a-scene.html 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <base href="../../../" />
  6. <script src="list.js"></script>
  7. <script src="page.js"></script>
  8. <link type="text/css" rel="stylesheet" href="page.css" />
  9. </head>
  10. <body>
  11. <h1>[name]</h1><br />
  12. <p>这一部分的目标是对three.js来做一个简要的介绍。我们将建立一个包含有旋转立方体的场景来开始这一部分。为了防止你遇到麻烦或者需要帮助,一个已经完成的例子在可以在页面下方找到。</p>
  13. <h2>开始之前</h2>
  14. <p>
  15. 在你开始使用three.js之前,你需要一个地方来显示它;将下列HTML代码保存为你电脑上的一个HTML页面,同时将[link:https://threejs.org/build/three.js three.js]复制到js/目录下,然后在你的浏览器中打开这个页面。
  16. </p>
  17. <code>
  18. &lt;!DOCTYPE html&gt;
  19. &lt;html&gt;
  20. &lt;head&gt;
  21. &lt;meta charset=utf-8&gt;
  22. &lt;title&gt;My first three.js app&lt;/title&gt;
  23. &lt;style&gt;
  24. body { margin: 0; }
  25. canvas { width: 100%; height: 100% }
  26. &lt;/style&gt;
  27. &lt;/head&gt;
  28. &lt;body&gt;
  29. &lt;script src="js/three.js"&gt;&lt;/script&gt;
  30. &lt;script&gt;
  31. // Our Javascript will go here.
  32. &lt;/script&gt;
  33. &lt;/body&gt;
  34. &lt;/html&gt;
  35. </code>
  36. <p>好了,接下来的所有代码将会写入到空的&lt;script&gt;标签中。</p>
  37. <h2>创建一个场景</h2>
  38. <p>为了真正能够让你的场景借助three.js来进行显示,我们需要以下几个对象:场景、相机和渲染器,这样我们就能透过摄像机渲染出场景。</p>
  39. <code>
  40. var scene = new THREE.Scene();
  41. var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
  42. var renderer = new THREE.WebGLRenderer();
  43. renderer.setSize( window.innerWidth, window.innerHeight );
  44. document.body.appendChild( renderer.domElement );
  45. </code>
  46. <p>在这儿我们花一点点时间来解释一下这儿发生了什么。我们现在建立了场景、相机和渲染器。</p>
  47. <p>three.js里有几种不同的相机,在这里,我们使用的是<strong>PerspectiveCamera</strong>(透视摄像机)。</p>
  48. <p>第一个属性是<strong>视场角(FOV)</strong>。视场角就是无论在什么时候,你所能在显示器上看到的场景的范围,它的值是一个角度。</p>
  49. <p>第二个值是<strong>长宽比(aspect ratio)</strong>。 也就是你用一个物体的宽除以它的高的比值。比如说,当你在一个宽屏电视上播放老电影时,可以看到图像仿佛是被压扁的。</p>
  50. <p>接下来的两个值是<strong>远剪切面</strong>和<strong>近剪切面</strong>。 也就是说当物体所在的位置比摄像机的<strong>远剪切面</strong>远或者所在位置比<strong>近剪切面</strong>近的时候,该物体超出的部分将不会被渲染到场景中。现在你或许并不用担心这个值的影响,但未来为了获得更好的渲染性能,你将可以在你的应用程序里去设置它。</p>
  51. <p>接下来是渲染器。这里是施展魔法的地方。除了我们在这里用到的WebGLRenderer渲染器之外,Three.js同时提供了其他几种渲染器,当用户所使用的浏览器过于老旧,或者由于其他原因不支持WebGL时,可以使用这几种渲染器进行降级。</p>
  52. <p>除了创建一个渲染器的实例之外,我们还需要在我们的应用程序里设置一个渲染器的大小尺寸。比如说,我们可以使用所需要的这个渲染区域的宽高,来将渲染器渲染出的场景,使其填充满我们的应用程序。因此,我们可以将渲染器宽高设置为浏览器窗口宽高。 对于性能比较敏感的应用程序来说,你可以给<strong>setSize</strong>传入一个较小的值,例如<strong>window.innerWidth/2</strong>和<strong>window.innerHeight/2</strong>,这将使得app在渲染时以一半的长宽尺寸渲染场景。</p>
  53. <p>如果你希望保持你的应用程序的尺寸,但是以较低的分辨率来渲染,你可以在调用<strong>setSize</strong>时,给<strong>updateStyle</strong>(第三个参数)传入false。例如, 假设你的&lt;canvas&gt; 标签具有了100%的宽和高,<strong>setSize(window.innerWidth/2, window.innerHeight/2, false)</strong>将使得你的应用程序以一半的分辨率来进行渲染。</p>
  54. <p>最后,我们将<strong>renderer</strong>(渲染器)这个元素添加到我们的HTML文档中,这也就是渲染器使用&lt;canvas&gt;元素来将场景展现给我们。</p>
  55. <p><em>“嗯,看起来很不错,那你说的那个立方体在哪儿?”</em>我们接下来来对它继续进行添加吧。</p>
  56. <code>
  57. var geometry = new THREE.BoxGeometry( 1, 1, 1 );
  58. var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
  59. var cube = new THREE.Mesh( geometry, material );
  60. scene.add( cube );
  61. camera.position.z = 5;
  62. </code>
  63. <p>要创建一个立方体,我们需要一个<strong>BoxGeometry</strong>(立方体)对象. 这个对象包含了一个立方体中所有的顶点(<strong>vertices</strong>)和面<strong>faces</strong>。未来我们将在这方面进行更多的探索。</p>
  64. <p>接下来,对于这个立方体,我们需要给它一个材质来让它有颜色。Three.js自带了几种材质,但在这里我们使用的是<strong>MeshBasicMaterial</strong>。所有的材质是一个将应用于立方体的属性对象。 简单起见, 我们在这里只应用一个color属性,值为<strong>0x00ff00</strong>,也就是绿色。这里所做的事情就相当于在CSS或者Photoshop里使用十六进制(<strong>hex colors</strong>)的颜色格式来设置颜色。</p>
  65. <p>第三步,我们需要一个<strong>Mesh</strong>(网格)。 网格是包含有一个几何体以及应用在在此几何体上的材质的对,我们可以直接将网格对象插入到我们的场景中,并在其中自由移动。</p>
  66. <p>默认情况下,当我们调用<strong>scene.add()</strong>的时候,物体将会被添加到坐标为<strong>(0,0,0)</strong>的位置。可或许会使得摄像机的位置和立方体相互重叠(也就是摄像机位于立方体中)。为了防止这种情况的发生,我们只需要将摄像机稍微向外移动一些。</p>
  67. <h2>渲染场景</h2>
  68. <p>在此之前,如果你从上面复制了我们已经写好的代码到一个HTML文件中,你将不会在其中看到任何东西。这是因为我们还没有对它进行真正的渲染。为此,我们需要调用一个所谓“<strong>渲染</strong>”或者“<strong>动画循环</strong>”的东西。</p>
  69. <code>
  70. function animate() {
  71. requestAnimationFrame( animate );
  72. renderer.render( scene, camera );
  73. }
  74. animate();
  75. </code>
  76. <p>在这里我们创建了一个循环——这使得渲染器能够在每次屏幕刷新时对场景进行绘制(在大多数屏幕上,刷新率一般是60次/秒)。如果你正在浏览器里写一个游戏,你或许会说<em>“为什么我们不直接用setInterval来实现刷新的功能呢?”</em>当然啦,我们的确可以用setInterval,但是,<strong>requestAnimationFrame</strong>有很多的优点。最重要的一点或许是当用户切换到其它的标签页时,它会暂停,因此不会浪费用户宝贵的处理器资源以及损耗电池的寿命。</p>
  77. <h2>使立方体动起来</h2>
  78. <p>
  79. 在开始之前,如果你已经将上面的代码写入到了你所创建的文件中,你应当已经可以看到一个绿色的盒子。让我们来做一些更加有趣的事——让它旋转起来。</p>
  80. <p>Add the following right above the <strong>renderer.render</strong> call in your <strong>animate</strong> function:</p>
  81. <code>
  82. cube.rotation.x += 0.01;
  83. cube.rotation.y += 0.01;
  84. </code>
  85. <p>This will be run every frame (normally 60 times per second), and give the cube a nice rotation animation. Basically, anything you want to move or change while the app is running has to go through the animate loop. You can of course call other functions from there, so that you don't end up with a <strong>animate</strong> function that's hundreds of lines.</p>
  86. <h2>The result</h2>
  87. <p>Congratulations! You have now completed your first three.js application. It's simple, you have to start somewhere.</p>
  88. <p>The full code is available below. Play around with it to get a better understanding of how it works.</p>
  89. <code>
  90. &lt;html&gt;
  91. &lt;head&gt;
  92. &lt;title&gt;My first three.js app&lt;/title&gt;
  93. &lt;style&gt;
  94. body { margin: 0; }
  95. canvas { width: 100%; height: 100% }
  96. &lt;/style&gt;
  97. &lt;/head&gt;
  98. &lt;body&gt;
  99. &lt;script src="js/three.js"&gt;&lt;/script&gt;
  100. &lt;script&gt;
  101. var scene = new THREE.Scene();
  102. var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
  103. var renderer = new THREE.WebGLRenderer();
  104. renderer.setSize( window.innerWidth, window.innerHeight );
  105. document.body.appendChild( renderer.domElement );
  106. var geometry = new THREE.BoxGeometry( 1, 1, 1 );
  107. var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
  108. var cube = new THREE.Mesh( geometry, material );
  109. scene.add( cube );
  110. camera.position.z = 5;
  111. var animate = function () {
  112. requestAnimationFrame( animate );
  113. cube.rotation.x += 0.01;
  114. cube.rotation.y += 0.01;
  115. renderer.render( scene, camera );
  116. };
  117. animate();
  118. &lt;/script&gt;
  119. &lt;/body&gt;
  120. &lt;/html&gt;
  121. </code>
  122. </body>
  123. </html>