使用 Three.js 的 3D 制作动画场景
推荐:将 加入你的3D开发工具链。
由于 GSL 语法的复杂性,对于许多开发人员来说 WebGL 是一个未知的领域。但是有了 Three.js,在浏览器中 3D 的实现变得简单。下面将讲述一下如何使用 Three.js 创建一个简单的 3D 飞机飞行的动画场景。
译注:WebGL 是一项利用 JavaScriptAPI 渲染交互式 3D 电脑图形和 2D 图形的技术,可兼容任何的网页浏览器,无需加装插件。通过 WebGL 的技术,只需要编写网页代码即可实现 3D 图像的展示。GLSL-OpenGL Shading Language 也称作 GLslang ,是一个以 C 语言为基础的高阶着色语言。它是由 OpenGL ARB 所建立,提供开发者对绘图管线更多的直接控制,而无需使用汇编语言或硬件规格语言。详细麻烦谷歌或百度一下~
在本教程中,我们将创建一个简单的 3D 场景, 在两个主要的部分会有一些交互。在第一部分,我们会讲解 Three.js 的基础和如何创建一个简单的场景。第二部分会详细讲述如何优化模型,如何为场景中的不同元素增添气氛以及更流畅的运动效果。
由于完整的游戏超出了本教程的范围,但是你可以下载或 checkout 源码。它包含了许多额外有趣的部分如:碰撞,抓硬币和增加得分。
在本教程中,我们将重点学习 Three.js 中的一些基础概念。这些基础概念将带你走进 WebGL 这新领域!
事不宜迟,我们马上开始~
本教程主要采用 Three.js 类库,Three.js 让 WebGL 变得易于使用。从官网或 GitHub repocheckout 获取关于 Three.js 更多的信息。
第一样要做的事情就是在 HTML <header> 标签中引入 Three.js:
然后在 HTML 中需要添加一个元素作为容器。
你可以像下面那样写一些简单的样式,让它填满整个 viewport:
正如你所见的一样,背景有些渐变的效果,就像天空。
以上是标签和样式!
如果你已经掌握了一些 JavaScript 的基础知识,使用 Three.js 会变得相当简单。来~我们看看实现不同部分的代码。
在开始场景编码之前,我觉得定义一个调色板是很有用的。因为在整个项目中会经常使用到。在这个项目中,我们会选择以下这些颜色:
虽然 JavaScript 代码十分冗长,但是它的结构很简单。我们需要创建所有主要的函数并放入初始函数中:
创建一个 Three.js 的项目,我们至少需要以下这些:
- 场景: 把这看作一个舞台,将需要呈现的对象都添加进去;
- 相机: 在这情况下,我们将使用透视相机,但它也可能是正投影相机;
- 渲染器: 使用 WebGL 渲染器显示所有的场景;
- 渲染一个或多个对象: 在我们的例子中,我们会创建飞机,大海,天空(一些云);
- 光源: 有不同类型可用的光源。在我们的项目中,我们主要用到营造氛围的半球光和制造阴影的方向光。
在 createScene 函数中创建场景,相机以及渲染器。
有了这三样东西,才能使用相机将对象渲染到页面中。
由于屏幕的尺寸改变,我们需要更新渲染器的尺寸和相机的纵横比。
当创建一个场景时,光源是最棘手的一部分。光源可以奠定整个场景的基调,所以要适当地选取。在这部分我们要尽量制造足以让对象可见的光源。
正如你所见,创建光源用到许多参数。不要再犹豫,大胆尝试用不同的颜色,强度的光源。你发现不同的光源在场景中能够营造有趣的氛围和环境。而且你会找到感觉:如何按照你的需求优化它们。
Three.js 中已经有大量的现成几何体如:立方体,球体,圆环面,圆柱体以及飞机原型。
对于我们的项目,所有的对象只需要通过这些几何体组合而成。这非常适合低多边形的风格,而且我们可以不必在 3D 建模软件中创建对象。
我们开始创建大海模型,因为它是我们实现中最简单的对象。为了简单起见,我们将大海看作一个简单的圆柱体放置在屏幕的底部。之后我们再深入研究如何改善大海的外观。
接着,让我们使大海看起来更具吸引力,海浪更加逼真。
总结一下创建对象,需要什么东西。
我们需要:
- 创建几何体
- 创建材质
- 将它们传入网格
- 将网格添加至场景
通过这些步骤,我们可以创建许多不同种类的几何体。现在,如果我们把它们组合起来,就可以创建更多复杂的形状。
在以下步骤中,我们将精确地学习如何创建复杂的形状。
云的制作会有一点点复杂,因为他们是由若干个正方体组合而成的一个随机形状。
现在,我们已经创建一朵云,我们通过复制它来创建天空,而且将其放置在 z 轴任意位置。
坏消息是:创建飞机模型的代码有点复杂有点长。但是好消息是:为了创建它我们已经学习了所有应该知道的。这里所有都是关于组合和封装形状的代码。
这飞机看起来很简单吧?不要担心它现在的样子,接着我们将看到如何改进形状,让飞机更加好看!
现在,我们可以实例化这飞机并添加到场景中:
我们已经创建了几个对象并把它们添加到我们的场景中了,但是为啥运行游戏的时候什么都看不到呢?那是因为我们需要渲染场景,添加一下这句简单的代码:
通过使螺旋桨旋转并转动大海和云让我们的场景更具生命力。因此我们需要一个无限循环函数。
正如你看到的一样,我们将渲染器的 render() 函数移动到 loop() 函数中。因为每次修改物体的位置或颜类的属性就需要重新调用一次 render() 函数。
在这刻,我们已经看见飞机在场景在中间,接下来我们还需要实现什么呢?就是监听鼠标的移动实现交互。
当文档加载完成,我们就需要为文档添加监听器,检测鼠标是否有移动。因此,我们需要对初始化函数作出以下的修改。
另外,我们创建一个 mousemove 事件的事件处理函数。
现在获得鼠标的 x , y 坐标值,我们可以适当地移动飞机。
我们需要修改循环函数并添加一个新功能去更新飞机的位置。
恭喜你!到这里,已经实现了飞机随着鼠标的移动而移动。到目前为止,看看我们已经实现了什么功能:
第一部分的 Demo
正如你所看见的,使用 Three.js 对创建 WebGL 内容有非常大的帮助。建立一个场景和渲染一些自定义对象不需要懂太多 WebGL 的知识。到目前为止,我们已经学会一些基础概念和你已经可以开始通过调整一些参数类似光源的强度,雾的颜色和物体的大小掌握了一些基本的诀窍。或许现在你已经很熟悉创建一些新的对象了。
如果你想学习更加深入的技术,请继续阅读。因为你将会学习到如何改进 3D 场景,使飞机飞行得更加平稳,并模仿低多边形海浪对大海的影响。
好了~我们之前创建了非常基础的飞机。我们现在知道如何创建对象并组合它们,但是我们仍然需要学习如何修改几何体令其更加符合我们的需求。
例如正方体,可以移动它的顶点。在我们的案例中,我们需要使它更加像驾驶舱。
让我们看一下驾驶舱这部分的代码,还有看下我们是如何让他的背部变得更窄的:
这就是如何操纵一个形状以适应我们的需求的一个例子。
如果你看到飞机的完整代码,你会看到几个对象:更像窗口的对象和更美观的螺旋桨。没有什么复杂的东西,试着调整相关的值找找感觉,制造属于你自己的飞机。
为我们的飞机添加一个飞行员,就好像添加几个盒子一样容易。
但是我们只需要一个酷酷的飞行员,头发要很飘逸的!感觉它好像很难实现的样子,但是由于我们开始的时候是在低多边形的场景下开始的,所以这就变得简单多了!尝试通过几个盒子模拟创建飘逸的头发,同时会给予一种独特的感觉。
让我们看看源码:
现在让头发动起来,只需要在循环函数里添加以下这句代码。
或许你已经注意到这大海不像真的大海那样,但更像被压路机压平的表面。
它需要一些海浪。这需要结合我们之前用到的两项技术来完成:
- 操纵几何体的顶点就像我们处理飞机的驾驶舱那样
- 每个顶点执行循环移动就像我们移动飞行员的头发一样
为了制造海浪,我们将围绕圆柱体的初始位置对每个顶点旋转。通过给它们一个随机旋转速度和一个随机距离(旋转半径)。很抱歉,这里还是需要用到一些三角函数!
让我们对大海作出一些修改:
就好像我们对飞行员的头发做的那样,我们在循环函数中添加以下这句代码:
现在好好欣赏海浪吧!
在教程中的第一部分,我们已经创建了一些光源。但是想为场景添加更好的气氛,并使阴影更加柔和。为了实现它,我们打算使用环境光源。
在 createLight 函数中,我们添加以下几行代码:
别再犹豫了!调节环境光源的颜色和强度,它会为你的场景增添独特的润色。
我们的小小飞机已经随着我们的鼠标移动。但它总感觉不像真正的飞行。当飞机改变它的飞行高度,如何改变它的位置和方向时更加流畅就完美了。在教程的最后一点,我们将实现它。
一个简单的方法就是让它移动到目标位置,通过添加一点点距离让它在每一帧与目标位置分离。
基本上,相关的代码会这样(这是一个通用的公式,不要马上添加到你的代码中):
更现实点来说,飞机旋转也可以根据运动的方向。如果飞机很快的向上移动,它应该很快地沿着逆时针方向旋转;如果飞机慢慢向下移动,它应该慢慢地沿着顺时针方向旋转;为了准确地实现它,我们应该把旋转比例值简单地分配给在目标和飞机位置之间的剩余距离。
在我们的代码里,updatePlane 函数需要像以下这样:
现在飞机的移动看起来更加自然和真实。通过修改一下小数值,你可以使用飞机随着鼠标的移动响应速度更加快或更加慢。
看下我们场景中的最后一个阶段:第二部分 Demo
很好!!!
如果你看到这,你已经学会 Three.js 中的通用的一些技术了,能够让你创建您的第一个场景。现在你知道如何通过原始几何体创建物体,如何激活它们,以及如何设置一个场景中的光源,你已经知道如何改进你的对象的外观和运动,还有如何调整环境氛围。
下一步已经超出本文范围了,由于它涉及到更多复杂的技术,它是实现一个游戏,大概思路是碰撞,收集点数,液位控制。下载源码,看看实现的思路;你会看到到目前为止你学到过的概念和一些高阶的知识点,你可以研究一下和玩一下。请注意这游戏已经优化了以便桌面使用。
但愿,这篇教程帮助你熟悉Three.js和激发你实现属于你自己的项目。让我看到你的创造力;我希望看到你做出什么来~
DEMO源码**
原文链接:
裸眼3D三维立体图训练来啦,会动的三维立体图合集,欢迎来挑战!
这次是会动的三维立体图合集,有一些难度,有几个是高难度,希望大家喜欢!对有一定技巧的朋友有些挑战。后面我讲了一下,看三维立体图的技巧,希望对刚入门的朋友有帮助!
秘诀一:学会分散自己的注意力你现在或许看到的只是一张布满斑点的图片,但是我要悄悄告诉你,这幅画里暗藏了一只斑点狗哦。那么我们先来回顾下自己发呆时的感觉,有时我们发呆时看东西是模糊的,或者一个物体会变成好几个,对了就是这样的发呆看着这幅图,你能看出什么么?如果什么都没看出不要紧,那么来试试第二个方法!
秘诀二:左右眼分视,调节眼焦如何左右眼分视呢?请在心中想着,左眼看左边的东西,右眼看右边的东西,是不是觉得有点晕眩的感觉,那就对了,同时调节眼肌,将视线将图片拉远拉近看看,一般大部分人里图片远些会比较好看出。
秘诀三:盯住图片中间盯住图片中心范围一直看,直到视力模糊为止,然后将视线锁定,保持状态不变,慢慢拉远眼睛与图片的距离。
秘诀四:瞪大双眼瞪大双眼,让眼球突出些,然后迅速斗鸡眼,此时的斗鸡眼并非是要将眼球集中,而是拉紧双眼的眼肌,尽量向中间靠拢。
总结一下,先左右眼看两遍红点,然后左眼看右边的红点,右边看昨天的红点,让两点重合,然后放松眼睛,直盯中间红点,然后就看出来了。抓紧时间多练习一下吧!
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。