编程基础

本节的目标是为Verge3D做一个简要的介绍。我们将首先设置一个场景,其中包含了一个旋转的立方体。在本页结尾提供了一个完成了的示例,以防您遇到瓶颈或需要帮助。

开始之前

Verge3D之前,您需要在某个地方展示它。将以下HTML保存到计算机上的一个文件中,同时将Verge3D的复制到应用目录中,然后在浏览器中打开。

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>My first Verge3D app</title> <style> body { margin: 0; } canvas { width: 100%; height: 100% } </style> </head> <body> <script src="v3d.js"></script> <script> // Our Javascript will go here. </script> </body> </html>

好了,接下来的所有代码将会写入到空的<script>标签中。

创建场景

为了真正能够用Verge3D显示内容,我们需要三样对象:场景、摄影机和渲染器,这样我们就可以通过摄影机来渲染场景。

const scene = new v3d.Scene(); const camera = new v3d.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new v3d.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement);

让我们花点时间来解释一下其基本原理。我们现在已经建立了场景,摄影机和渲染器。

在Verge3D中有几种不同类型的摄影机。我们先来使用 PerspectiveCamera(透视摄影机)

第一个属性是field of view(视场).FOV是指在任何特定时刻在显示器上看到的场景的范围。该值以角度为单位。

第二个属性是 aspect ratio(长宽比)。您应该始终使用元素的宽度除以高度作为屏幕高宽比,否则画面将会如同在宽屏电视上播放老电影一样——图像像是被压扁了。

接下来的两个属性是剪切屏幕的 nearfar 。这代表着,对象离摄影机的距离比 far 远的或比 near 近的都不会渲染。暂时不必担心这些,但您可以用于应用设定以提升性能。

接下来是渲染器。这里是奇迹发生的地方。除了我们在这里使用的WebGLRenderer之外,Verge3D还附带了一些其他的渲染器,通常用作老式浏览器的用户或由于某种原因不支持WebGL的用户的后备措施。

除了创建渲染器实例之外,我们还需要设置应用中的渲染器尺寸。将应用填满需要显示区域的空间是个好主意——在本案例中,我们使用浏览器窗口的宽度和高度定义尺寸。对于性能敏感的应用,您还可以将 setSize 设置小一点,如 Window.InnerWidth/2Window.InnerHeight/2,这将使应用渲染尺寸长宽都是窗口的四分之一。

如果您希望保持应用的尺寸,但以较低的分辨率渲染,您可以在调用 setSize 时,将 updateStyle (第三个参数)设为false。例如,假设您的<canvas> 标签现在已经具有了100%的宽和高,调用 setSize(window.innerWidth/2, window.innerHeight/2, false) 将使得您的应用程序以一半的分辨率来进行渲染。

最后一步很重要,我们将 renderer(渲染器) 的dom元素(renderer.domElement)添加到我们的HTML文档中。这就是渲染器用来显示场景给我们看的<canvas>元素。

“嗯,看起来很不错,那您说的那个立方体在哪儿?”接下来,我们就来添加立方体。

const geometry = new v3d.BoxGeometry(); const material = new v3d.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new v3d.Mesh(geometry, material); scene.add(cube); camera.position.z = 5;

要创建一个立方体,我们需要一个 BoxGeometry(立方体)对象。这个对象包含了一个立方体中所有的顶点 (vertices) 和面(faces) 。未来我们将在这方面进行更多的探索。

除了几何形状,我们还需要一个材质来给它上色。Verge3D自带了几种材质,在这里我们暂时使用 MeshBasicMaterial 。所有的材质都存有应用于他们的属性的对象。在这里为了简单起见,我们只设置一个color属性,值为 0x00ff00,也就是绿色。这与CSS或Photoshop中的颜色工作方式相同(十六进制颜色)。

第三布,我们需要一个 Mesh(网格)。网格包含一个几何体以及作用在此几何体上的材质,我们可以直接将网格对象放入到我们的场景中,并让它在场景中自由移动。

默认情况下,当我们调用 scene.add()时,我们添加的东西会添加到坐标上 (0,0,0)。这将导致摄影机和立方体进入彼此内部。为避免这种情况,我们只需要将摄影机稍微向外移动一些即可。

渲染场景

如果您把上面的代码复制到我们先前创建的HTML文件中,您将不会看到任何东西。这是因为我们还没开始真正的渲染。为此,我们需要 render or animate loop(渲染或动画循环)

function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate();

这将创建一个循环,使渲染器在每次刷新屏幕时都绘制场景(在典型的屏幕上,这意味着每秒 60 次)。如果您刚开始在浏览器中编写游戏,您也许会问:“为什么我们不直接创建一个setInterval呢?”当然可以,但 requestAnimationFrame 有许多优点。也许这是最重要的一个原因:当用户导航到另一个浏览器标签时,渲染器会暂停工作,因此不会浪费宝贵的CPU性能和电池功耗。

为立方体做动画

如果您将上面的所有代码插入到我们开始之前创建的文件中,应该会看到一个绿色的盒子。让我们来做一些更加有趣的事 —— 让它旋转起来。

renderer.render 中调用 animate 功能:

cube.rotation.x += 0.01; cube.rotation.y += 0.01;

这会将每帧运行一次(通常为每秒60次),并给立方体一个漂亮的旋转动画。基本上,当应用运行时,任何您想要移动或改变的东西都必须经过动画循环。当然,您可以从那里调用其他函数,这样就不至于最后出现一个几百行的 animate 函数。

结果

恭喜您!您现在完成了您的第一个Verge3D应用。虽然很简单,但您现在有了一个起点。

完整的代码如下所示。试玩一下,以便更好地理解工作原理。

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>My first Verge3D app</title> <style> body { margin: 0; } canvas { width: 100%; height: 100% } </style> </head> <body> <script src="v3d.js"></script> <script> const scene = new v3d.Scene(); const camera = new v3d.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new v3d.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); const geometry = new v3d.BoxGeometry(); const material = new v3d.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new v3d.Mesh(geometry, material); scene.add(cube); camera.position.z = 5; function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); }; animate(); </script> </body> </html>