我学习了游戏devise的matrix变换,并且与一些基本概念纠缠在一起。 我看到在按照这个顺序渲染之前发生的实际乘法:
我敢肯定,没有人乘以任何matrix的世界顶点,如果我在这里,那么整个乘法堆栈的变换发生? 我想我错过了一些低级的理解。
PS所以强调一下我的观点:为什么要用全部的东西来繁衍整个世界呢? 我只会看到它的一部分! 在游戏引擎(openGL,ect)中如何避免这种巨大的乘法。
PSS感谢您的答案家伙! 巨大的工作只是为了帮助我____这些都是我在任何stachexchange论坛上得到的最详细的答案。 🙂
PSSS我来自财务数据的二维可视化。 你们中的一些人指出,这可能是我误解为什么每个世界物体必须被处理的原因。 我的管道:
Serie.bar[i]
在这个数组中导航。 我通常说数据序列在“数组空间”,因为我使用“我”来导航那里。 camera.width=300bars, camera.X =11000bar, camera.Y=33 $ per share.
使用鼠标,用户只更换相机(这就是为什么当有人说视图不应该移动,世界应该移动时,它是超级有线的。 相机坐标变化,当它是时间渲染,你只需看看相机内部,做这样的事情: for (int i = camera.left; i < camera.right; i++) { g.DrawSerie(google.bar[i]); }
所以你看,这里没有必要和世界的转变。 我知道所有我需要渲染之前感谢“相机在世界坐标”。 我想你不能在3D中做,但一些细节仍然缺less我。
从逻辑上考虑:
当你渲染什么东西时你的目标是什么?
要在屏幕上显示它!
什么是约束?
模型必须对相机可见(即在视锥体中,不被其他物体遮挡等)
什么是投入?
什么是输出?
这个过程是这样的:
我想如果你没有游戏世界,你可以消除世界空间计算步骤,直接从模型空间去查看空间(本质上,你会说你的模型空间是你的世界空间),但这意味着你只能有全世界只有一个物体,而且没有办法做任何游戏世界的具体逻辑,比如多个物体之间的碰撞。 一般来说,这不是很有用。
正如你所看到的,所有这些步骤不仅是必要的,而且后面的步骤实际上是巨大的优化(例如截锥体剔除),因为它们可以帮助你避免渲染场景中的大部分东西(尤其是小的封闭诸如建筑物内部的区域)。 当你站在一个没有窗户的3000顶点小屋内时,为什么要花费时间渲染400,000,000个顶点森林?
MODEL into WORLD:将每个模型的顶点乘以worldMatrix。 如果模型很大,那对GPU来说有点压力。
这实际上不是一个“压力”。 GPU是量身定制的硬件,可轻松执行数十万次操作。 这很重要,因为它似乎是你混乱的根源。 这只不过是你想象的那么大。
世界进入VIEW:好吧,如果Model to World不好,那么将整个世界充满模型乘以一些matrix是GPU的巨大负担。
事实上,除非某些顶点着色器需要在世界空间中做某些工作(这并不总是必要的,这一步和前一步是结合在一起的),也就是模型到世界和世界到视图matrix相乘在渲染之前一起渲染一次,每个渲染的顶点只有一次被合并后的matrix相乘,光照工作有时是在视图空间中完成的,所以变换往往会暂停,但是也可以将整个世界 – >视图 – 如果在视图空间中不需要做任何事情,则将空间转换成单个matrix。
这进一步降低了转换的有效成本。
VIEW只是一个点(一个顶点),更改一个顶点要比数百万更容易。
不,这个观点在概念上是一个点和一个基础(一个旋转的参照系)。 你不能“只是改变看法”。 你最终需要知道所有顶点相对于视图的位置和方向的位置,所以你必须变换所有的顶点。 您可以在世界空间中使用您的视图的位置和方向来完成一些照明工作,但最终您仍然需要相对于视图框架的坐标来裁剪它们以抵制视锥,所以这是一个有争议的问题。
我敢肯定,没有人乘以任何matrix的世界顶点,如果我在这里,那么整个乘法堆栈的变换发生? 我想我错过了一些低级的理解。
你不对。 世界顶点乘以matrix将它们带入剪辑空间。
几何变换管道非常简单:几何graphics从模型空间开始,转换到世界空间,然后查看空间,然后剪切空间,剪切平截面。 然后应用透视分割,坐标转换为标准化的设备坐标,最终转换为光栅化的窗口坐标。
没有隐藏的技巧,事实上,有时候可以跳过你不需要通过组合matrix显式地进入的空间(例如,将模型空间顶点乘以组合的世界视图投影matrix来右移到剪辑空间)。 在逐个顶点的基础上进行这种转换的代价是非常小的。
请允许我详细说明在最常见的情况下,GPU的责任应该是什么,以及CPU,游戏引擎和OpenGL的责任。
首先,在OpenGL渲染stream水线的情况下,GPU有一个顶点着色器程序,一次只能处理一个顶点。 这个顶点被3个特殊的matrix转换(按此顺序):
经过顶点着色器处理后,变换后的顶点在原始assembly过程中与其他顶点合并,然后再进行光栅化和分片处理等操作。
您的初步观察是有效的,如果GPU处理大场景的每个顶点,则可能会强调GPU。 这意味着我们必须小心处理发送给GPU的内容。 正如您所指出的,浪费GPU时间来处理屏幕上永远不会结束的事情是毫无意义的。 所以,在游戏devise中,游戏引擎必须以某种方式决定如何管理场景的哪一部分。 有很多方法可以做到这一点,但我会列举几个:
所有上述游戏引擎优化都发生在CPU上,因为它们涉及决定发送给GPU的数据。 但是,GPU和OpenGL管道还提供了其他优化。 这包括诸如按样本操作和testing (如深度testing)之类的内容,还包括视图裁剪等内容。 在裁剪的情况下,这防止了视锥之外的顶点被进一步处理。
OpenGL还提供了一些更多的优化方法,允许您通过使用顶点数组对象和各种types的缓冲对象将模型卸载到GPU内存中。 OpenGL也有不同的渲染模式,比如索引渲染 ,可以减less实际发送给顶点着色器的顶点数量。
至于优化,主要有两个地方,你最省时间。
许多其他的优化仍然是有用的,但只能削减less量的处理时间。
我希望这有助于为您提供所需的“低级”理解。 随意提问如果有什么不清楚的地方!
我认为其他答案已经涵盖了这个大部分,但我想在PS上做一些断言:
PS所以强调一下我的观点:为什么要用全部的东西来繁衍整个世界呢?
因为世界空间不匹配,所以是在屏幕上的表示。 例如,在2D游戏中,您可能会轻视将偏移量应用于世界的位置,并只画出屏幕上的内容…而不是3D。 为什么? 因为你有旋转和透视。 为了存档这些效果,我们使用matrix转换。
那没有解决堵塞的问题。 如果不改变摄像头坐标,就无法告诉对象隐藏了另一个对象,因此我们需要进行转换。
此外,考虑到您可能需要额外的几何形状(在视锥之外)来制作其他效果,如阴影或reflection。
我只会看到它的一部分! 在游戏引擎(openGL,ect)中如何避免这种巨大的乘法。
游戏引擎可能需要额外的工作来保持GPU和CPU的低负载。 需要指出的是,video游戏长期以来一直在使用我所描述的技术,现代GPU硬件比第一次引入时要好得多。
将这些技术结合起来,可以让巨大的开放游戏拥有数千或数百万个对象,将所有内容发送给GPU确实会对性能产生影响。
例如,游戏引擎不再仅仅依靠3D的画家algorithm; 相反,引擎将遮挡问题留给了GPU,由于深度缓冲区,GPU可以处理交错的三角形。 虽然有引擎可以优化遮挡的情况,但并非一般情况。
二进制空间分区
让我们从古老的厄运开始。 原来的厄运是当时硬件的制约因素。 该发动机是基于Wolfenstein 3D的发动机,该发动机是通过射线投射来发现水平视野与墙壁之间的距离,并在屏幕上缩放它们以产生透视效果。
Doom在地图上添加了垂直层次,这意味着当发现地板上的一个台阶时,发动机必须重新检查该区域以find在recursion过程中超出该步骤的区域…这意味着“复杂”的垂直结构(楼梯)非常重视性能。
该解决scheme是一种称为BPS(二进制空间分区)的技术, 通常意味着将世界分成两半(做一个二进制分区),然后再一次,所以…将整个结构添加到树结构可以通过导航find附近的物体或物体,这些物体或物体与另一个物体处于相同的方向。 这意味着他们不必每步查询整个几何。
由于Doom的缘故,BSP在游戏引擎中很常见。
分裂你的世界
我们要避免一次加载整个地图。 相反,我们只想加载我们需要的部分。
原始PlayStation的各种游戏将使用每个房间的每扇门作为加载点。 应该指出的是,加载是(并将继续)是PlayStation的瓶颈。
但这并不意味着没有巧妙的解决scheme和解决方法。 比如Crash Bandicoot使用了狭窄而曲折的道路,这就隐藏了一个事实,那就是只有靠近玩家的物体才会被装载,因为path经常扭曲,并且保持玩家看到的距离有限。
任天堂64有一个不同的约束。 即使有更好的加载速度,地图的大小也有一个上限。 例如,马里奥64负担不起一个大的开放世界。 相反,世界被划分在墙壁上的图画中,每个图像的大小都被控制住了。
在某些地方,同样考虑了塞尔达:时之笛(这将被限制在海尔勒城堡,你可以在墙上input图片)。 幸运的是,引擎的改进允许更大的地图,但区域之间仍然存在负载点。
最后考虑一下旧的GTA游戏,它将地图分成较小的一个。 GTA副城有两个主要的岛屿分开装载,当玩家从一个到另一个有一个负载屏幕…从一个城市另一个是可见的距离,但这只是一个低多边形模型。
certificate负载
现在考虑我的世界。 尽管外观不太好,但它有很高的多边形数量(考虑所有立方体的所有三角形几乎是无尽的地图,也就是很多顶点)。 它如何处理它们? 那么他们被加载在大块,引擎只发送到GPU附近的玩家的大块。
如果您尝试使用“Minecraft”的渲染距离和其他graphics选项,或者由于未能加载的块,您可能会发现自己正在寻找虚空(实际上就是天空盒),在那里应该有土地。
详细程度
GTA圣安地列斯没有负载屏幕分割地图,他们是怎么做的? 他们使用LOD(详细程度)… GTA圣安地列斯工作在一个完整的游戏世界(包括道路和建筑物)的低多边形模型,总是加载,然后其他模型加载在它的顶部(包括道路和再次建设)。 当他们靠近相机时,模型被更高层次的细节所取代。
这意味着如果你移动得足够快(或者你的电脑足够慢),你可以赶上模型正在加载的边缘……但是,由于基本模型总是在那里,你总是会看到道路和原油版本的建筑,而不是空白。
这是最先进的技术(加上针对特定情况和我不知道的任何专有algorithm的任何自定义优化)。 这些技术除了GPU硬件的进步外,还可以在GTA,Skyrim,Red Dead Redemption,Wild Breath等等中find巨大的地图。
PS OpenGL? 不是一个游戏引擎。