betsey

Three.js新手指南

betsey · 2017-05-23翻译 · 694阅读 原文链接

如今,Web的复杂程度日新月异,与此同时,其中蕴含的可能性也以同样的速度迅速增长着,特别是在3D渲染方面。WebGL(Web Graphics Library)是一个用于渲染交互式3D和2D图像的JavaScript API。而Ricardo Cabello开发的Three.js是构建于WebGL之上的JS库,它可以确保编写的代码在不同的浏览器中是兼容的。

如同jQuery之于JavaScript一样,对于WebGL而言,Three.js提供了喜闻乐见的声明式语法,并且将在浏览器中制作3D的遇到令人头疼的复杂逻辑抽取了出来。下面让我们对three.js的语法进行一个整体总览,如果你刚开始接触3D制作的话,我们也将告诉你如何开始你的入坑之旅,准备好了吗?

我们的目标

我们看下下面的CodePen给出的示例代码,你可以动一动鼠标尝试着拖动模型进行旋转,也可以滑动鼠标滚轮放大和缩小模型。

1. 设置场景

为了简单起见,我们使用CodePen来进行开发,首先我们需要在你的JS选项卡中引入Three.js(CDN126Kb)

我们开始创建一个scene,这和你在Photoshop里面创建一个画板是一样的。在进一步编写代码之前,你需要声明一个场景变量。所以,在js代码里写入如下代码:

var scene = new THREE.Scene();

摄像机!

当幕布拉开、演员就位的时候,我们需要去展示我们精彩的表演,这时候就需要引入一个相机了!Three.js提供了很多的相机,比如说PerspectiveCameraStereoCameraOrthographicCameraCubeCamera。在这个例子中,我们使用PerspectiveCamera就可以满足我们的要求了,这款相机可以模拟我们人眼看物体的方式。就像我们需要定义一个场景变量一样,我们同样需要定义一个相机变量:

var camera = new THREE.PerspectiveCamera();

我们的PerspectiveCamera接受如下四个参数:fovaspectnearfar

  • fov(field of view 视野)表示围绕着摄像机的中心,你视线所见的范围的大小。想想一下,在相机上使用广角镜头和标准镜头的区别。
  • aspect表示fov的比例,或者说是屏幕的宽高比(比如4:5,16:9)
  • 后两个nearfar可以类比成固体的平面。这两个参数合在一起,控制一个物体在距离相机多远的距离可以被浏览器渲染到画面上。near表示一个物体或者是这个物体的某些部分可以被相机渲染出来的距相机最近的距离,也就是说,如果这个数值设为200,而物体被摆放在距相机100的位置,这个物体就看不到了,相应的far表示一个物体可以被相机渲染出来的距相机最远的距离。这四个参数合起来就定义了相机的观察截锥体——viewing frustum(是不是相当的专业?)

viewing frustum

视锥截平面

下面是PerspectiveCamera参数的一个示例:

var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

现在这个阶段,我们没有必要了解每个值,除非你需要修改这些值。接下来,我们需要调整下相机的位置。

camera.position.set(x, y, z);

这条线是物体所处的位置。这就设置了向量x,y和z的坐标。如果不设置的话,相机将什么也看不到。

2. WebGL渲染器

我们的这个3D“大餐”中下一个重要的“食材”就是创建一个WebGL渲染器。这是能够展现我们的创意作品的很神奇的一个关键所在。

var renderer = new THREE.WebGLRenderer();

这个WebGLRenderer同样可以接受参数并且传入数值。

var renderer = new THREE.WebGLRenderer({
  alpha: true // remove canvas' bg color
});

这样可用的“属性-数值”对有相当多,都列在了这个文档中,如果你想更深入的研究的话,你可以看看(其实我还是相当建议读一下的哦!)。

通过定义这个渲染器,我们可以设置一些方法来进一步地让我们的创意独具一格,比如时候setSize,这个方法几乎在所有的Three.js项目中都用得到。

// Make scene renderer the size of the screen
renderer.setSize(window.innerWidth, window.innerHeight);

Three.js中提供了很多很多的可用方法,这个例子中,我们setSize()就够了。

3. DOM

现在我们已经写好了我们想要的大小,接下来我们就把它放进我们的DOM中去。

document.body.appendChild( renderer.domElement );

这个domElement就是渲染器将要输出到的地方,并且它将以一个canvas元素的形式展现出来。我使用的是document.body,你也可以将这个canvas元素放到你想要的任何一个位置。这完全取决于你自己,你可以根据你项目的需求进行选择。

创建一个物体

下一步,我们可以来创建一个物体了——我们到这个阶段已经声明了一个场景、一个相机以及一个渲染器。基于我们demo的目的,我们在3D Warehouse抓取一个手机的图片,这样我们就可以为人们在线购买iphone的时候提供一个更加生动的参考。

iphone 6 by Jeremie P

iPhone 6+ by Jeremie P

如果你愿意的话,你也可以使用SketchUp甚至是Blender来画一个属于你的3D物体。但是这又创造了一个更为陡峭的学习曲线,因为你还得去学习这些3D绘制应用的使用——显然,这个曲线是超出了这个文章的教授范围的。

如果你喜欢Piña Collada的话

想要在场景中插入我们的3D物体的话,我们就需要用到[ColladaLoader]([https://threejs.org/docs/#Examples/Loaders/ColladaLoader](https://threejs.org/docs/#Examples/Loaders/ColladaLoader))了。需要注意的是,你在three.js中使用的任何图片都必须在1-2Mb的大小而且必须是一个Collada文件:这些文件是以.dae作为扩展名的。如果你不小心打开了一个Collada文件的话,你会看到实际上它是用XML写的。

我们先定义一个ColladaLoader变量,然后接着调用方法来定义另外一个变量,这个变量用来展现3D图片,在接下来我们会用到。

var dae, // graphic
    loader = new THREE.ColladaLoader(); // loader

这是一个很好的开始,但是如果要让我们的手机展现出来,我们还需要做一些其他的工作。接着,我们需要写一个这样的一个函数

function loadCollada( collada ) {
  dae = collada.scene;
  scene.add(dae);
}

下一步,我们将会用到这个load方法,传入我们的Collada文件的URL,然后把上面的函数作为第二个参数也传进来。

loader.load( 'http://myurl.com/file/iphone6.dae', loadCollada);

如果你想了解更多关于ColladaLoader的知识,你可以看下source code on GitHub

4. 渲染循环

在有了我们的加载器和图片之后,我们还需要做最后一步:我们需要创建一个叫做“render loop”的东西。这是因为实际上我们还没有渲染任何东西呢。

“渲染循环”会让你的渲染器每1/60秒绘制一次场景。下面的函数将让让我们脑海中的创意变成眼睛可见的现实(整个过程中最激动人心的时刻就要到啦~)

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

renderPhone();

使用requestAnimationFrame有很多好处。其中最重要的一个好处就是,当用户切换到浏览器的其他标签页的时候,动画就会停止,这样将不会浪费CPU/GPU的处理能力,同时也保护了你的电池。

最后的成品

整个作品就做好了,现在你可以看到浏览器里渲染出了一个3D的iphone,你可以旋转、放大、缩小它(感觉可以被玩坏的节奏):

其实,想要达成我们最终的效果,还有一些东西我没有写出来。你可以深入研究下我们这个demo的JS代码。

比如说,灯光部分(AmbientLightHemisphereLightPointLight),TrackballControlsAxisHelper以及窗口调整事件等。可能有些东西文档中并没有写出来,比如说TrackballControls,但是你可以在the core JS file on GitHub中找到这些属性的具体用法。还有一些特别炫酷的控制器,同样在GitHub上有列出来。

灵感

有时候你需要一些灵感,来激发你大脑中的创意。下面这些使用Three.js来创作的demo是我想当喜欢的,简直是让我梦中的场景变成了现实。

httpspaperplanesworldhttps://paperplanes.worldhttpsthroughthedarkwithgooglecom grab your headphoneshttps://throughthedark.withgoogle.com (grab your headphones)httpcarvisualizerplus360degreescomthreejshttp://carvisualizer.plus360degrees.com/threejs

扩展阅读

Rachel Smith写了一个a great article on CodePen about WebGL,我推荐给你,你可以在闲的时候看一看。整个教程语言通俗易懂,并且基本上都是讲解一些Three.js里面的场景、几何体、灯光、材质以及动画,这些都是我无法在一篇很短的推文里面细致的讲解的

译者betsey尚未开通打赏功能

相关文章