关于简单的3D图形

第1部分。简介


嗨,我叫巴尔杜克。 我从事图形程序员已经有好几年了,所以尽管我绝不是专家,但似乎我已经对与图形工作有关的所有知识都了如指掌。

长期以来,这一系列帖子的想法一直徘徊在我脑海中的某个地方,并且在阅读了一篇有趣的文章并分析了最新的Deus Ex之后再次浮出水面。

在我看来,图形,尤其是它在现代游戏中实现的复杂性,是一个有趣的话题。 很少有人会好奇地深入研究其所有细节,但我相信有些话题会引起所有人的兴趣。 我认为大多数玩游戏的人都对如何获得这些效果感到好奇,或者对他们使用什么技术设法在某些新游戏中创造出如此惊人的图形感到好奇。


即使是制作简单的3D游戏,也有许多必要的组件,更不用说看门狗这样的项目了。

对于本文需要考虑的内容,我只有一个大致的了解,但这取决于引起兴趣的主题。 但是,主要思想是对现代游戏中正在发生的事情进行一般性描述,而不会吓到任何读者-我将假设您不具备数学和编程知识。 如果您知道CPU和图形卡之间的区别,并且将RAM与硬盘驱动器区分开,那么这就足够了,其余的我将进行解释。

本文将根据其视频演练Chip&Ironicus的“看门狗的游戏”进行开发,以使演示文稿略有结构。 该游戏以其图形而闻名(关于它的看法可能完全相反),并且其中的许多方面可以通过单独的示例进行考虑。 也许我会谈论其他游戏。

首先,我将解释每款游戏的基本知识,但我还将介绍“看门狗”的一些技术和视觉效果。

我将使用我在业余时间编写的名为RenderDoc的工具。 它用于调试图形问题-该工具可让您将图形框架分解为多个部分,并借助它,我们将了解如何将其组合在一起。


该动画显示了在使用图形卡渲染框架的过程中逐渐创建的框架的一部分。

大多数人都知道计算机图形(以及任何其他视频的图形)由一系列静止帧组成,每个静止帧显示的时间都为一秒钟。 在电影院中,传统上每秒使用24帧(每秒帧数,FPS),在电视中,频率大约相同,约为24-30帧。 在游戏中,FPS可以更改,因为每帧都需要做很多工作。 频率下降到30以下是不希望的,尽管它经常发生。 通常,主机游戏的上限为60 FPS。 开发者寻求实现30或60的频率,具体取决于游戏的目标。 在具有高帧频的PC上,您可以达到90、120甚至更高。 这些特定数字的原因是垂直同步(vsync),我们将在下面进行讨论。

从心理上讲,我们可以从相反的角度来看这个任务-而不是查看FPS频率有多 ,而是查看为每个帧分配多少时间。 如果我们希望游戏以30 FPS的频率运行,那么我们只有33毫秒才能完成框架所需的所有工作。 在60 FPS时,时间只有一半-大约17毫秒。 即使对于计算机,鉴于需要完成的工作量,该时间段也不是很大。 为了使您对数量有所了解,然后根据粗略估计,子弹每毫秒移动大约1米。

我们将主要讨论PC,因为该平台是开放的,并且在不担心违反保密协议(NDA)的情况下,我无法谈论控制台。 无论如何,基本上我将谈论控制台上没有什么大不同,但是如果仍然有不同,那么我将强调这一点。 对于移动平台,PC硬件/控制台与移动硬件之间的大多数差异与本文主题无关。


老实说,我将这张图片放在这里,以便您了解本文将不仅包含文本。

这项任务使我们感兴趣-我们将不必担心如何执行其所有AI计算或如何执行物理模拟来移动对象。 被称为“图形程序设计”的学科的边界相当模糊,但是我要说的是,图形程序设计始于我们拥有构建框架所需的所有信息:我们知道会发生什么,所有的纹理和模型都在内存中(而不是在磁盘上) ),动画已经过动画制作,物理已经计算在内,我们只需要绘制完成的帧以显示在屏幕上即可。

我补充说,我将​​考虑具有相当传统渲染效果的3D游戏,例如“看门狗”(Watch Dogs)-许多基本原理都适用于2D游戏,但是要在其上展示概念会有些困难。 我还将向我解释(尤其是对图形程序员)我主要是为理解而努力,因此,如果我允许我实现自己的目标,也许我将使用相当可疑的解释。

第2部分。框架由什么组成


在大多数情况下,我们只会看一帧,并谈论游戏用来创建最终帧的构造块。 同样在这部分中,将有几张新的精美图片。

用构建块组装框架的方法有多种。 播放器看到的完成图像不会立即呈现。 它是在很多年前立即绘制的,但是现代图形引擎几乎总是使用某种预处理。 在屏幕上显示完成的帧之前,图形引擎会绘制许多各种类型的中间图像,以帮助计算最终图像。

这些图像高度依赖于引擎的类型以及图形程序员需要应用的技术。 例如,如果他希望阳光创建正确的阴影,则将需要一种类型的图像作为阴影。 他可能还需要在玩家驾驶的汽车上进行正确的反射,为此,他也需要另一幅具有反射的图像。







看门狗框架的构造中使用的中间图像的各种示例。

在本文中,我将不考虑“看门狗”框架中使用的每个图像,而只考虑基本图像,以便您可以学到一些东西。 在这个领域中,图形研究不断进行,新技术不断涌现。 创新也在较小的层次上出现,但是当市场营销告诉您一些新的图形功能时,通常指的是这种改进。



这些中间图像中的每一个也都由更小的片段构成。 场景中的每个对象或一组相关对象都分别作为纹理模型创建。 在开发游戏时,美术师会在3D编辑器中构建这些模型,并为其创建所有必要的资源。 然后,使用关卡编辑器将这些模型放置在世界中,并从中逐步构建一个虚拟城市。

可能几乎每个人都知道这一点,如果您过去20年来观看了实时3D图形的发展,那么您就会知道当今变得更加复杂的模型了。 在图形形成的最初阶段,纹理贴图是一个昂贵的过程,并且如果可能的话,可以通过用相同颜色的对象绘画来进行处理。 仅将纹理留给确实需要细节的元素,例如眼睛或脸部。

3D模型完全由形成对象形状的相互连接的三角形组成。 每个三角形都有三个称为顶点的点,并且由于这些三角形相互连接,因此这些顶点可以由多个三角形共享。 因为顶点和三角形足够重要,我们稍后再讲。 还值得记住的是,在渲染之前必须对某些对象(例如,字符或树)进行动画处理。 以标准静态形式创建模型,并在每个帧中应用动画。 我们也将回到这一点。


这是Aiden Pierce动画后头部的3D模型。 三角形是可见的,因为通常将三角形绘制为平坦且未平滑。

为了向3D模型添加更多细节,需要叠加纹理。 纹理是常规的平面图像文件,通常为正方形或简单大小,例如比例为2:1的矩形。 使用更复杂的过程将纹理叠加在3D模型上,我将在下面对此进行更详细的讨论,但是从概念上讲,它类似于包装礼物的过程。 图像与包装纸的尺寸完全匹配,而不是简单的重复纸包装图案。 如果看到用胶水组​​装的纸模型,则原理是相同的。

这种类比比您想象的更合适,因为这些纹理通常是通过将3D模型“展开”到平坦的毛坯中来创建的,就像使用纸模型一样,然后在其顶部绘制纹理。 这种部署通常是自动执行的,但是在特别复杂的对象中,可以手动完成。


这是与上面显示的Aiden Pierce头部模型相对应的纹理。 有牙齿和舌头的部分。 请注意,他的额头上方的区域没有纹理,因为该区域已被艾登·皮尔斯™传奇棒球帽永久覆盖。

注意事项


展开时,需要更多细节的对象的某些部分会增加,而其他部分会减少。

他们经常谈论各种模型的“皮肤”,尤其是在可自定义角色的情况下。 如今,所谓的“皮肤”通常是指模型中的细微变化-一条新皮带或另一顶帽子-但最初出现此术语是因为使用了相同的模型,但纹理发生了变化(或“皮肤”),字面意思是“皮肤”)来创建外观不同的角色。 即使在今天,借助此类纹理,您也可以创建NPC或对象的巨大可变性,从而节省时间和金钱-您无需创建许多独特的3D模型。 艾登可以穿的不同衣服通常只是同一模特的不同质地。


这是3D模型头部旋转的简短片段。 仅叠加纹理,仅此而已。

在我们考虑的框架中,主要渲染部分中渲染了大约1700个对象。 它们中的一些将是相同的模型-诸如花盆中的花朵和垃圾桶之类的对象永远不会实际创建,这是一个模型或放置在不同位置的多个模型。 但是,为完成框架而绘制的对象的大致数量接近4700-这使我们知道除了渲染所有这些模型之外还需要执行多少额外的工作。

让我们看一个物体的另一个例子-艾登戴的棒球帽。



这是一个纹理和纹理棒球帽模型。 可以看出,纹理是由连接到模型的独立部分构成的。

注意事项


帽檐的遮阳板和主要部分不会碰触,因为扫描可能非常复杂,并且如果需要,可以在几个不同的部分进行扫描。 有时,对复杂形状的模型进行纹理处理而没有明显的问题和接缝需要大量的技能。

我们在艾登的脑袋上看到的相同原理也适用于瓶盖。 实际上,如果我们忽略执行展开所需的特定纹理和数量,则原理总是相同的。

为了演示在开发过程中可能出什么问题,并演示如何在编写图形时获得乐趣,我们可以进行一个小实验。 由于大多数纹理的尺寸都是标准的正方形,并且在模型上包裹和展开纹理的方法也相同,所以为什么不花一点时间呢? 如果我们将艾登头部的纹理应用于棒球帽模型,会发生什么?


已经与艾登·皮尔斯传奇棒球帽不太相似。

在棒球帽的纹理上有徽标的地方,耳朵和牙齿位于头部的纹理上。 在有遮阳板的地方,头部的纹理上只有头发。 覆盖图完全相同,但是使用了不同的纹理。 当然,该示例在游戏中将是一个错误,但是请考虑一下,如果您对纹理进行动画处理或使其闪烁,该怎么办-在游戏中,这些东西用于各种效果,您现在可以注意到。 特别是,游戏《圣徒的行4》对“模拟”的特殊效果使用了类似的方法。

考虑这种情况的后果也很有用-游戏必须非常仔细地将模型和纹理对结合在一起,也就是说,最独特的模型必须匹配自己独特的纹理。

当然,该规则不是绝对的-在某些情况下,为了节省空间,纹理是可以用于许多对象的标准重复图案。 链接的对象集(例如,新闻通讯社)可以对不同的报纸使用相同的纹理,而每份报纸只占该纹理的一小部分。

但是,这意味着要构建最终图像,必须存在所有构建块,也就是说,可以获得许多所需的模型和纹理。 在下一部分中,我们将讨论为什么某些方面(例如反射)很难正确实现。 我还将讨论游戏如何使用小技巧来节省时间和资源。

第3部分。您不需要画什么


通常,对图形进行编程是平衡十几个不同约束以获得完美折衷的任务。 在最后一部分中,我们看到了每次绘制场景时,它都是由许多小的构建块组装而成的,这些构建块是人,汽车,路标,建筑物。 屏幕上的所有内容均由需要绘制的各个组件组成。 我们将在此处讨论一些微妙的平衡操作。

中央处理器和图形卡一起渲染框架。 游戏的其余部分在CPU中执行,因此它决定应在当前帧中绘制哪些对象,相机在哪里看以及播放哪些动画。 图形卡是一种“劳力士”,可以执行渲染像素所涉及的所有复杂工作,这就是为什么它是单独的专用设备。

事实证明,CPU和图形卡都对计算速度或计算量有限制,但这是不同类型的限制。

通常,CPU对自己的工作更感兴趣:我们总共需要绘制多少个对象? 这些物体有何不同 -是100盏相同的灯,还是100棵灌木/植物/树木? 这些对象是否具有动画效果,是否动态移动以及其中哪些是静态或静止的?

我们要尽可能减少负载的第一件事是仅绘制屏幕上可见的内容。 这似乎很明显,但是实现需要仔细的工作。 不要忘记我们从头开始构建每个框架,因此在每个框架中,我们需要查看每个对象并确定它是否可见。 这意味着在每个游戏中,跟随玩家的每个地方都有一个黑洞,当他不看物体和人物时,它们就不复存在了。


在此动画中,我们旋转相机,在播放器后面显示出空虚。 细心的观众会注意到它并不完全是空的...

在这种情况下,很难制定任何实用的规则,但是通常,您可以在场景中绘制约1000个对象,而不必担心空间不足。 但是,如果需要渲染5,000个对象,则应考虑使用技巧。 不要忘记,在大多数游戏中玩家可以控制摄像机的游戏中,我们无法知道他将以什么角度观看,因此您需要节省操作空间。

事实证明,有许多技巧可以让您几乎完全使用有效资源,并且在诸如“看门狗”之类的游戏中尤为重要。 越靠近边界,从相同数量的对象获得的视觉效果越好,游戏的外观就会越好。

即使您看着场景中面前的东西,也并不意味着有必要绘制整个城市。 如果左侧或右侧有一栋巨大的建筑物,那么它后面的所有内容都将变得不可见,因此您无法绘制它。 同样,远处的一些物体变得很小,因此我们不必担心在远处绘制微小的植物和灌木。


该动画显示,如果您沿着街道走得比我们看到的要远,那么小巷中将没有任何东西,但是距离很远,细节会变小。

实际上,此场景中仍然有很多对象会因此变得不可见。在这个领域还有很多要探索的地方,必须应用各种复杂的技术。您总是必须做出妥协,但是如果您可以花一点时间,或者想出一种非常聪明的方法来避免几乎无需额外的努力即可渲染100个对象,那么我们可以使场景变得更加复杂或更密集。

另外,还有另一个小问题。在某些情况下,我们必须绘制一个在屏幕上几乎看不到的建筑物,并且远远超出它。浪费资源。我们总是可以将这些对象划分为几个部分,然后可以绘制或跳过每个部分,这将减少浪费。然而,现在我们已经增加了渲染时,他们对物体的总数在屏幕上,并创建了相反的问题!

这个例子是数百个例子中的一个,但是很容易解释必须做出什么决定以及要为每个游戏找到最佳平衡点的实验。

由于我们从《看门狗》拍摄的动作是在城市中进行的,因此我们可以从上方观看,以大致了解正在绘制的内容。在这张静态图片中,特别值得注意的是看门狗每季度进行一次工作。


现在,我们移开以显示摄像机前面的可见区域(抱歉,安装过程节省了时间)。


相机的可见区域大约叠加在图像上。这个三角形的宽度取决于视野-有时在游戏中这是一个自定义选项,有时是一个恒定值。


这是场景的线框显示,相机的视野仅限于白色。



你们中有些人可能已经想到了一个小技巧,可以绕开渲染一定数量对象的限制-为什么不让对象成为小区域中所有事物(直到单个叶子)的非常复杂的组合?然后绘制1000个对象将绰绰有余。

但是在这里,我们面临着一套完全不同的限制-图形卡的性能有限,并且对象越复杂,绘制所需的时间就越长。也就是说,即使一个物体非常复杂,也可以将游戏的帧频降低到20 FPS。包括这就是为什么我说对象数量的限制相当模糊。

在对象上花费的时间取决于模型和纹理的复杂性和细节,以及照明和阴影的复杂程度。这也是为什么尝试实现更复杂或更复杂图形的游戏倾向于使用不太复杂和详细的场景-平衡将比例尺朝一个方向或另一个方向移动,因此您可以为自己提供更多的操作空间,从而牺牲了对游戏不那么重要的内容。


这是一种热图,显示场景的哪些部分特别复杂。注意树木和植被可能导致多少问题。

还有另一套称为“详细程度”(LOD)的技术,专门用于解决此类问题。与我们可以优化对象数量,减少不必要的一切这一事实类似,我们可以增加“复杂性”的提供,从而消除不必要的情况。

技巧之一实际上是众所周知的-这正在改变纹理的分辨率。该主题通常与许多其他主题相交,因此我将尝试以一种易于访问的方式对其进行解释。

游戏中的纹理通常是大小等于2的幂的矩形-512、1024、2048、4096。这有很多原因,但是这样做的优点之一是,您可以获取1024x1024大小的纹理,并轻松地创建较小尺寸的512x512的纹理。

由于下面将要讨论的原因,始终需要纹理具有各种较小的版本。也就是说,大小为1024x1024的纹理将具有较小的版本512x512、256x256、128x128、64x64、32x32、16x16、8x8、4x4、2x2和1x1。但是,这样做的优点之一是,如果远处的对象在屏幕上的尺寸很小,则对其应用1024x1024纹理意味着浪费资源。我们可以使用相同纹理的较小版本进行保存。

同样,即使接近的对象也可以被认为不是很重要,并使用较小的纹理。

注意事项


通常,当玩家接近某个对象时,会使用最大的纹理,但是正如大多数人在特定游戏中所看到的那样,这种情况并不总是会发生,并且纹理在加载之前看起来过于模糊。通常会发生这种情况,因为无法将纹理从DVD或硬盘驱动器直接加载到图形卡的内存中进行渲染。这种情况通常发生在玩家突然改变其位置时,例如在重生,加载新关卡或非常快速的移动时。在所有其他情况下,通常会在将播放器移动到世界各地的过程中逐渐加载纹理。

您也可以将此简化过程应用于游戏中使用的模型,尽管这要困难得多。通过创建复杂对象的简化版本,可以确保在很长的距离内它们不会吃掉有限的复杂性。

得益于简化的对象和裁剪的模型,您可以节省很多钱,并且您必须在诸如“看门狗”之类的任何游戏中使用此方法。但是同时,这可能会浪费大量资源。有必要对需要多少个简化版本的模型做出周到且平衡的决定。如果它们太少,那么您将无法节省太多,或者在更改它们时质量会出现明显的飞跃。如果它们太多,那么您将浪费内存并花费创建对象所需的工时。


当复杂的对象和角色与高度详细的版本无法区分时,这就是它们如何看待某个距离。



我希望现在您对图形程序员,美术师和关卡设计师试图将最高质量的图形与高速相结合的问题有所了解。在控制台上,此方程比在PC上更容易解决,因为设备是恒定的。

在上一部分中,我说过我将谈论为什么很难正确实现反射和其他类似的东西。原因很简单-我经常谈论的生产力和资源储备不会根据您是否有反思而改变。如果要创建可以再次显示整个场景的反射,则必须重做我刚才谈到的所有工作。此外,反射很大程度上取决于我们观察它们的角度,因此要获得每个反射对象的精确反射,它们必须是自己的!

这可能很快就会失控,通常在进行反思的游戏中会允许自己有一定的自由或假设。游戏很少在复杂的环境中产生反射,最大可能是浴室中的镜子,那里没有太多的物体,场景的复杂性很小,因此您可以负担额外的费用。也许游戏中的真实反射只会出现在不平坦或波浪状的水面上,因此即使是非常粗糙且细节不多的场景也足以产生令人信服的反射。

通常很难完全避免反射表面,这就是为什么游戏使用即时渲染的预渲染图像的原因,从而给出“合理良好”的结果。但是他们并没有受到严格的审查,如果仔细观察这些反射,您会发现这是一个模仿。有一些现代技术可以在特定条件下创建反射,也许以后我会讨论它们,但是仍然需要这种预渲染(“预渲染”)图像。


该渲染图像称为“立方体贴图”。关于艾登站着的地方,这并不完全准确,但离他很近。

看门狗实时渲染反射。我没有详细研究这个问题,但是我相信它们总是在角色在街上时渲染,主要用于使他对他坐着的汽车有确切的反映,以改善图像并给他带来些许真实感。由于玩家始终专注于自己的车子及其周围环境,因此在其他车子上反射不正确的事实几乎不明显。

有许多近似方法可用来加快这些反射的渲染速度。例如,反射中渲染的对象比真实场景中的要少得多(总共约350个),并且与完整版本相比,它们中的许多对象都非常简化。我怀疑诸如人之类的复杂物体会被完全丢弃,而不管其距离如何,但是我还没有检验这种理论。此外,这些物体上没有阴影,并且照明非常简单-仅来自太阳和天空。反射像“鱼眼镜头”一样从地面渲染,也就是说,地球本身不可能反射,其旁边的细节非常低。

但是即使进行了所有这些简化,反射也只能满足预期的要求。如果您在铁轨下行驶,则可以从汽车上看到正确的反射,实际上这是行不通的。

这个决定是有意的,不容易做出。股票是一个恒定值,因此,如果您为这些思考留出空间,则需要付出其他代价。


这是艾登周围场景的非常“腥”的视图,带有底视图,用于反射。您可以沿着火车的两个灯光和轨道导航。



我想在这里提到工作的另一部分-阴影。后来我计划谈论阴影如何工作,因为这是一个有趣的话题,但是现在最重要的是要记住阴影与反射非常相似。每个投射阴影的光源都应从其角度渲染场景图像。这次,没有太多方法可以简化工作-为了正确计算阴影,每个光源都必须具有此图像。

注意事项


, . , «» , . , , .

阴影照明最明显,最重要的光源是太阳(如果月亮在夜间发生,则是月亮)。由于太阳很大,因此通常会渲染3-5个图像,而不像大灯或手电筒那样渲染一个图像。

不幸的是,这是看门狗不能作为一个很好的例子的情况之一。游戏中阴影的计算非常复杂,在我看来,它是为在城市中投射阴影而专门优化的。因此,我最好切换到《孤岛惊魂4》,并考虑在此游戏的帧示例中计算阴影。


这是我以《孤岛惊魂4》中的场景为例。


这是一张包含有关此场景阴影信息的图像-每个图像都需要对场景进行全新的渲染。

因此,当我们需要向光源添加阴影投射时,我们将不得不再渲染一次场景。 在这里,您还可以使用一些在反射情况下使用的近似值,只是它们要小得多。 您可以跳过较小或较远的对象,但请记住,这些对象似乎不会投射阴影。 您可以将图像渲染得非常小,但是阴影会显得粗糙且细节不足。 通常,不可能使用非常简化的对象版本,因为那样看来,对象似乎会在自身上投射阴影,或者在对象与其阴影之间出现间隙。

很容易错过的另一个结果是需要为每个光源创建阴影图像。 在许多情况下,可以通过组合使用来简化光源-在“看门狗”中,这种情况通常发生在汽车前灯上。

当两个灯都打开时,仅绘制了一个光源,但是它具有特殊的形状,因此看起来像两条光线。 如果前灯有阴影,那么就不那么简单了,它将变得更加引人注目-当玩家经过车前时,光线将来自两个前灯之间的某个地方。 也许那时您将不得不分开大灯,但与此同时,不仅会产生计算阴影的额外费用,而且还必须绘制新的照明。



我要强调的所有主要事情是妥协。 我们当然可以摆脱所有这些近似,但是我们将不得不为此花费我们的资源储备,也就是说,牺牲一些东西。 每个游戏开发者必须决定对他而言,在游戏中专注于什么重要,以及最能给玩家留下深刻印象或最讨厌的东西。

第4部分。移动峰


在这一部分中,我将更多地讨论场景中为对象设置动画的技术细节。

图形程序员经常谈论“图形管道”。 3D图形有点像一条装配线,从一个阶段到另一个阶段的移动定义明确,但一次只能用于一个对象。

所有现代图形卡都具有大致相同的传送带,它们具有特殊的设备和软件,这些设备和软件可以直接在“硅片”中闪烁以最大程度地提高传送带的速度。 当然,不同制造商和图形卡系列之间会有很多差异,但是通常我们不必担心它们在此级别上如何工作。

注意事项


如果您对一切在抽象硬件级别上的工作方式感兴趣,那么我建议您使用Fabian Giesen在图形管道上的一系列文章 。 本系列文章比我的文章更加详细,需要更多的了解。

我将跳过许多细节来解释有趣且重要的原理。 在这一部分中,我们将研究管道的第一部分,即Vertex Shader

着色器在DirectX 9发布后大约16年前开始普及,其中出现了顶点和像素着色器。 为了解释什么是着色器并将它们与以前的着色器进行比较,我将讨论它们所做的工作。


艾登的骷髅头又回到了我们身边。

让我提醒您,在第2部分中,我们检查了创建游戏世界的模型。 这些图案由称为顶点的单个点组成,这些点以三角形连接。 我说过以后我会再告诉您更多信息,现在我信守诺言。

由于游戏世界中的所有内容都由顶点组成,因此使用这些模型完成的所有操作都必须使用顶点。 对于图形卡,所看到的只是一长串顶点。 对她而言,没有诸如运行动画,摇曳的树叶或任何其他抽象概念之类的东西。

让我们看一下我们要做的一个简单示例-在世界上移动和定位对象。 首先,让我们看一个简单的案例,而不是一个字符。

在Maya和3D Studio Max等3D编辑器中创建对象时,艺术家总是从自己的独立世界中构建。 这些对象并不是在芝加哥随行人员中立即创建的,相反,它们的周围看起来就像是Matrix中的“空白房间”。 每个对象都位于绝对空的中心。


这是游戏中的红绿灯,它位于自己的世界中。

当保存到磁盘上时,该模型不知道它在世界上的什么位置以及何时下载并将其转移到图形卡。 这意味着当需要绘制对象时,我们需要将其从自己的世界移动到绘制的场景。 绘制每个对象都会发生这种情况,甚至建筑物和桥梁之类的静止对象也从它们自己的世界移动到每一帧中的场景。


在这里,我们看到已经放置在部分构造的最终场景中的几个交通信号灯。

正如我上面提到的,我们只能使用高峰。 我们不能只对图形卡说:“您能把这个交通信号灯放在桥下吗? 然后再放一点吗? 太好了!

因此,我们不必告诉图形卡它需要如何处理对象本身,而需要说出如何处理其所有顶点。 事实证明,在这种情况下,一切都变得非常简单。 如果我们以完全相同的方式更改所有顶点,并且它们彼此之间保持不动,则这类似于将对象整体移动。 我们需要做的就是弄清楚什么是“变化”,即所谓的转变。

注意事项


所有这些的数学计算并不是特别复杂,但是超出了本文的范围。 如果您已经研究过线性代数,那么您可能知道所需的一切-基本上所有这些都归结为向量的矩阵乘法。

在出现顶点着色器之前,用于转换图形卡中顶点的可能选项非常有限。 可以使用移动和旋转对象以及其他一些操作,但是没有特别多余或复杂的对象。

顶点着色器是在图形卡上运行的小型计算机程序。 他们获取一个顶点,对其执行任何必要的操作 ,然后发出输出顶点。 他们不仅可以移动它,而且还可以使它们上下跳跃,远离最近的山峰,随风而摇摆,具有动画效果等等。

我采用了“看门狗”中使用的一种顶点着色器,并对其进行了一些实验以展示其功能。 这是一项艰巨的工作,但是我设法找到了用于角色的顶点着色器并进行了更改。 还有另一种用于皮肤的顶点着色器,例如用于脸部和手部,但是您会很快了解其原理。


我做了一个非常简单的更改,为角色模型添加了一个折弯,但是其他所有操作都照常使用。

上面的动画显示,角色以某种方式奇怪地变形了。 这使我们回到了原理“如果移动每个顶点,则类似于移动整个对象”。 对顶点着色器所做的更改一次仅适用于一个顶点,但是由于它们都以相同的变形工作,因此效果将应用于整个对象。

您还可以更改转换部分,该部分负责“简单地移动到位”,以便她将角色放到地面上,而不是将角色放置在正确的位置。 这不是借助物理学来模拟的,因此与重力或与其他物体的碰撞无关-如果我们愿意,我们可以使所有人在空中飞翔。


在此动画中,我们使顶点着色器逐渐升高和降低对象。

显然,所有这些都不是很有建设性的,但是它使我们对顶点着色器的工作原理有了一个大致的了解-如果我们现在想对树上的叶子进行动画处理以便它们摆动,我们将做同样的事情。 它们只是沿风向摆动而不是升高和降低。 然后我们可以改变风的强度,使树木或多或少地摇摆。


在这里,我们看到当一切增加大约七倍时会发生什么。

我简化了一点,但是基本上大多数顶点着色器的任务是“将对象移到适当位置”。 例外是所有动画对象-人,动物以及诸如摇摆的绳索,飘动的衣服等对象。



使人动起来与使用骨骼和“皮肤”的想法有关。 骨架是对移动角色的简单描述。 在此阶段,我们不关心没有动画效果的带扣,帽子或牛仔裤-我们只关心最适合人体骨骼的重要动作。


这里显示了一个人物的简单骨架。 它不是取自“看门狗”,因为该骨架很难在3D编辑器之外可视化。

图片由Attribution-ShareAlike CC BY-SA授权© MakeHuman team 2001-2014


这是一个快照姿势或T型姿势,用于演示角色在不使用动画的情况下的外观。

动画-跑步,步行,跳跃-仅适用于此骨骼。 这使整个过程变得非常简单,因为我们只需要考虑大约一百个骨骼而不是成千上万个顶点。

创建骨架后,每个顶点都以这种静态姿势附着到一个或多个骨骼上,这种连接称为“蒙皮”。 在半条命1时代开始使用这项技术时,每个顶点仅与一个骨骼关联。 如今,它们甚至可以连接四根骨头,而每一根骨头都具有一定的重量,这取决于骨头对顶点的影响程度。 因此,您可以获得更流畅的动画,使骨骼在不同区域交叉,而在移动手臂或腿部时不会产生锐角。


这是上面显示的骨骼,其中大腿骨骼已旋转。 颜色显示了髋骨相对于模型顶部的重量。

图片由Attribution-ShareAlike CC BY-SA授权© MakeHuman team 2001-2014

这项技术有其局限性,特别是在衣服和皮肤在铰链上被压缩或拉伸的地方,例如在肘部和肩膀上。 这是一种不完美的动画,但是非常有效。 最严重的限制是,以这种方式创建引人注目的面部动画非常困难。 您可以在脸上创建很多“假”骨骼,例如眉毛和嘴周围的骨骼,但这只是肌肉和皮肤的粗略近似。

该技术的另一个重要特征是顶点和骨骼的比较非常具体,并且与该比较的执行方式有关。 可以为多个不同的模型使用动画,但是要在其中使用骨骼的每个单独模型都必须与骨骼关联。 原因是动画使顶点从其原始位置相对于骨骼移动。 如果顶点不在预期的位置,则会出现问题。


如果模型与她使用的骨架不匹配,则动画将完全不正确。


如果我们将角色的宽度扩大两倍,我们将获得与Drake的“过度甜甜圈”类似的效果,但是值得注意的是,靠近画笔的动画变得不正确,因为这是它们离原始位置最远的地方。

第一个动画对您来说似乎很奇怪-这样的故障动画经常出现在游戏中。 通常,它们是由以下事实造成的:将错误的动画应用于骨骼,或者模型使用了错误的骨骼。 与使用纹理和模型的情况一样,必须非常仔细地比较骨骼,蒙皮和模型,否则结果很快就会令人感到难过。

我希望您对顶点着色器的用途有所了解,并了解如何使用动画将静态模型转换为活动角色。

Source: https://habr.com/ru/post/zh-CN430930/


All Articles