Files
apt-nl-map/static/Magic4/js/three.js-dev/docs/manual/zh/introduction/Creating-a-scene.html
2024-12-04 10:21:04 +08:00

164 lines
9.5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<base href="../../../" />
<script src="page.js"></script>
<link type="text/css" rel="stylesheet" href="page.css" />
</head>
<body>
<h1>创建一个场景([name]</h1>
<p>这一部分将对three.js来做一个简要的介绍我们将开始搭建一个场景其中包含一个正在旋转的立方体。页面下方有一个已经完成的例子当你遇到麻烦或者需要帮助的时候可以看一看。</p>
<h2>开始之前</h2>
<p>
在开始使用three.js之前你需要一个地方来显示它。将下列HTML代码保存为你电脑上的一个HTML文件同时将[link:https://threejs.org/build/three.js three.js]复制到该HTML文件所在的目录下的js/目录下然后在你的浏览器中打开这个HTML文件。
</p>
<code>
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;title&gt;My first three.js app&lt;/title&gt;
&lt;style&gt;
body { margin: 0; }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script src="js/three.js"&gt;&lt;/script&gt;
&lt;script&gt;
// Our Javascript will go here.
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>
<p>好了,接下来的所有代码将会写入到空的&lt;script&gt;标签中。</p>
<h2>创建一个场景</h2>
<p>为了真正能够让你的场景借助three.js来进行显示我们需要以下几个对象场景、相机和渲染器这样我们就能透过摄像机渲染出场景。</p>
<code>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
</code>
<p>我们花一点点时间来解释一下这里发生了什么。我们现在建立了场景、相机和渲染器。</p>
<p>three.js里有几种不同的相机在这里我们使用的是<strong>PerspectiveCamera</strong>(透视摄像机)。</p>
<p>第一个参数是<strong>视野角度FOV</strong>。视野角度就是无论在什么时候,你所能在显示器上看到的场景的范围,它的单位是角度(与弧度区分开)。</p>
<p>第二个参数是<strong>长宽比aspect ratio</strong>。 也就是你用一个物体的宽除以它的高的值。比如说,当你在一个宽屏电视上播放老电影时,可以看到图像仿佛是被压扁的。</p>
<p>接下来的两个参数是<strong>近截面</strong>near<strong>远截面</strong>far。 当物体某些部分比摄像机的<strong>远截面</strong>远或者比<strong>近截面</strong>近的时候,该这些部分将不会被渲染到场景中。或许现在你不用担心这个值的影响,但未来为了获得更好的渲染性能,你将可以在你的应用程序里去设置它。</p>
<p>接下来是渲染器。这里是施展魔法的地方。除了我们在这里用到的WebGLRenderer渲染器之外Three.js同时提供了其他几种渲染器当用户所使用的浏览器过于老旧或者由于其他原因不支持WebGL时可以使用这几种渲染器进行降级。</p>
<p>除了创建一个渲染器的实例之外,我们还需要在我们的应用程序里设置一个渲染器的尺寸。比如说,我们可以使用所需要的渲染区域的宽高,来让渲染器渲染出的场景填充满我们的应用程序。因此,我们可以将渲染器宽高设置为浏览器窗口宽高。对于性能比较敏感的应用程序来说,你可以使用<strong>setSize</strong>传入一个较小的值,例如<strong>window.innerWidth/2</strong><strong>window.innerHeight/2</strong>,这将使得应用程序在渲染时,以一半的长宽尺寸渲染场景。</p>
<p>如果你希望保持你的应用程序的尺寸,但是以较低的分辨率来渲染,你可以在调用<strong>setSize</strong>时,将<strong>updateStyle</strong>第三个参数设为false。例如假设你的&lt;canvas&gt; 标签现在已经具有了100%的宽和高,调用<strong>setSize(window.innerWidth/2, window.innerHeight/2, false)</strong>将使得你的应用程序以一半的分辨率来进行渲染。</p>
<p>最后一步很重要,我们将<strong>renderer</strong>渲染器的dom元素renderer.domElement添加到我们的HTML文档中。这就是渲染器用来显示场景给我们看的&lt;canvas&gt;元素。</p>
<p><em>“嗯,看起来很不错,那你说的那个立方体在哪儿?”</em>接下来,我们就来添加立方体。</p>
<code>
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
</code>
<p>要创建一个立方体,我们需要一个<strong>BoxGeometry</strong>(立方体)对象. 这个对象包含了一个立方体中所有的顶点(<strong>vertices</strong>)和面(<strong>faces</strong>)。未来我们将在这方面进行更多的探索。</p>
<p>接下来对于这个立方体我们需要给它一个材质来让它有颜色。Three.js自带了几种材质在这里我们使用的是<strong>MeshBasicMaterial</strong>。所有的材质都存有应用于他们的属性的对象。在这里为了简单起见我们只设置一个color属性值为<strong>0x00ff00</strong>也就是绿色。这里所做的事情和在CSS或者Photoshop中使用十六进制(<strong>hex colors</strong>)颜色格式来设置颜色的方式一致。</p>
<p>第三步,我们需要一个<strong>Mesh</strong>(网格)。 网格包含一个几何体以及作用在此几何体上的材质,我们可以直接将网格对象放入到我们的场景中,并让它在场景中自由移动。</p>
<p>默认情况下,当我们调用<strong>scene.add()</strong>的时候,物体将会被添加到<strong>(0,0,0)</strong>坐标。但将使得摄像机和立方体彼此在一起。为了防止这种情况的发生,我们只需要将摄像机稍微向外移动一些即可。</p>
<h2>渲染场景</h2>
<p>现在如果将之前写好的代码复制到HTML文件中你不会在页面中看到任何东西。这是因为我们还没有对它进行真正的渲染。为此我们需要使用一个被叫做“<strong>渲染循环</strong>render loop或者“<strong>动画循环</strong>animate loop的东西。</p>
<code>
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
animate();
</code>
<p>在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环在大多数屏幕上刷新率一般是60次/秒)。如果你是一个浏览器游戏开发的新手,你或许会说<em>“为什么我们不直接用setInterval来实现刷新的功能呢</em>当然啦我们的确可以用setInterval但是<strong>requestAnimationFrame</strong>有很多的优点。最重要的一点或许就是当用户切换到其它的标签页时,它会暂停,因此不会浪费用户宝贵的处理器资源,也不会损耗电池的使用寿命。</p>
<h2>使立方体动起来</h2>
<p>
在开始之前,如果你已经将上面的代码写入到了你所创建的文件中,你可以看到一个绿色的方块。让我们来做一些更加有趣的事 —— 让它旋转起来。</p>
<p>将下列代码添加到animate()函数中<strong>renderer.render</strong>调用的上方:</p>
<code>
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
</code>
<p>这段代码每帧都会执行正常情况下是60次/秒),这就让立方体有了一个看起来很不错的旋转动画。基本上来说,当应用程序运行时,如果你想要移动或者改变任何场景中的东西,都必须要经过这个动画循环。当然,你可以在这个动画循环里调用别的函数,这样你就不会写出有上百行代码的<strong>animate</strong>函数。</p>
<h2>结果</h2>
<p>祝贺你你现在已经成功完成了你的第一个Three.js应用程序。虽然它很简单但现在你已经有了一个入门的起点。</p>
<p>下面是完整的代码,可在[link:https://jsfiddle.net/fxurzeb4/ live example]运行、编辑;运行或者修改代码有助于你更好的理解它是如何工作的。</p>
<code>
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;title&gt;My first three.js app&lt;/title&gt;
&lt;style&gt;
body { margin: 0; }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script src="js/three.js"&gt;&lt;/script&gt;
&lt;script&gt;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
const animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>
</body>
</html>