编程基础
本节的目标是为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(长宽比)。您应该始终使用元素的宽度除以高度作为屏幕高宽比,否则画面将会如同在宽屏电视上播放老电影一样——图像像是被压扁了。
接下来的两个属性是剪切屏幕的 near 和 far 。这代表着,对象离摄影机的距离比 far 远的或比 near 近的都不会渲染。暂时不必担心这些,但您可以用于应用设定以提升性能。
接下来是渲染器。这里是奇迹发生的地方。除了我们在这里使用的WebGLRenderer之外,Verge3D还附带了一些其他的渲染器,通常用作老式浏览器的用户或由于某种原因不支持WebGL的用户的后备措施。
除了创建渲染器实例之外,我们还需要设置应用中的渲染器尺寸。将应用填满需要显示区域的空间是个好主意——在本案例中,我们使用浏览器窗口的宽度和高度定义尺寸。对于性能敏感的应用,您还可以将 setSize 设置小一点,如 Window.InnerWidth/2 和 Window.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>