为什么视锥剔除重要,却又不重要 | Why Frustum Culling Matters, and Why It‘s Not Important

编程入门 行业动态 更新时间:2024-10-14 22:13:46

看到一篇不错的介绍视锥剔除的文章,初次投稿,就简单以翻译来做开端吧。

原文链接:https://gist.github/nothings/913056601b56e5719cc987684a16544ehttps://gist.github/nothings/913056601b56e5719cc987684a16544e

(主要是谷歌娘翻译,个人稍作润色。谷歌娘的翻译效果真的太好了,除了一些小问题,如个别助词、连词等可能有些生硬,省略的词翻译不出,且同一个词经常前后翻译不一致外,词义、句意上都准确无误)

目录

性能

GPU

视锥剔除的性能

实践中的视锥剔除

加载与卸载

常见的的图形优化手段

写在最后


这篇 Kotaku 写的文章里有一个关于“视锥剔除”的挺好的示例:Horizon Zero Dawn Uses All Sorts Of Clever Tricks To Look So GoodEvery time you move the camera in Horizon Zero Dawn, the game is doing all sorts of under-the-hood calculations, loading and unloading chunks of world to ensure that it all runs properly. And that’s not even counting the robot dinosaurs.https://kotaku/horizon-zero-dawn-uses-all-sorts-of-clever-tricks-to-lo-1794385026

互联网就是这样,争议不断。

有些人将开场白 “在《地平线:零之曙光》中每次移动相机时,游戏都在进行各种底层计算,加载和卸载世界块以确保一切正常运行” 当做对 GIF 中对应片段的说明(注:指视频的 18:19 分处演示大世界的视锥剔除技术);但这不是视锥体剔除的作用,即这段描述可能不是文章作者的意思。

相反,我们转向第二段就能看到真正的含义,“上面的 GIF [...] 展示了当你四处移动相机时,游戏是如何秘密地动态渲染大块地形的。”

一些游戏开发者可能会对此嗤之以鼻,但如果你将“渲染”替换为“不渲染”,则与开发人员的措辞方式几乎没有区别(注:意思是指我们一般用这样的技术确保在相机移动时,通过不渲染大块地形来达成优化)。对于开发人员来说,这个问题没什么大不了的,但我想让非开发人员对此有所了解。

两件事:一,我将解释你可能已经知道的东西。这不是居高临下;我只是想确保我们对此有差不多的认知。二,专家们会意识到我把一些事情过于简单化了,但如果不这样的话,为了保证说明既准确又简单,我需要用很多繁琐的话语解释。(我也会适时提出一些明确的提示来不断提醒读者这点。)

There is a nice GIF illustrating a technique called "frustum culling" in this Kotaku article: Horizon Zero Dawn Uses All Sorts Of Clever Tricks To Look So Good

The interwebs being what they are, this has also led to some controversy.

Some people have interpreted the opening sentence "Every time you move the camera in Horizon Zero Dawn, the game is doing all sorts of under-the-hood calculations, loading and unloading chunks of world to ensure that it all runs properly," as being about the GIF; that's not what frustum culling does, but that's probably not what the article's author meant anyway.

Rather, for the real meaning, we turn to the 2nd paragraph, "the GIF above [...] shows how the game is secretly rendering giant chunks of terrain on the fly as you move your camera around."

Gamedevs may snark a little at this, but if you just replace "rendering" with "not rendering" it's pretty indistinguishable from how a developer might phrase it. The bigger issue for developers is that it's just not that big a deal, and I want to give non-developers a little insight into this.

Two things: one, I'm going to explain stuff you might already know. This isn't condescension; I just want to make sure we're on the same page. Two, experts will realize I'm oversimplifying some things a lot, but that's to avoid excessive circumlocutional language explaining all the caveats that would otherwise need to be there to be accurate while still keeping it as simple as possible. (I still put in some explicit caveats to keep reminding you of this.)

性能

让我们从 FPS(每秒帧数)开始,这是游戏玩家都知道的概念。

FPS 越高动画越流畅;至少在某种程度上,更高的 FPS 更好。粗略估计,计算机可以在固定的时间内完成固定量的工作。 FPS 越高,可用于创建图像帧的时间就越少,这意味着计算机创建一个图像帧所能做的工作就越少。

因此,游戏开发人员痴迷于“性能”,通过做更少的工作来让程序运行变快(这样游戏运行得更流畅,或者这样他们可以节约资源在游戏中放入更多东西来画面看起来更好看)。游戏编程和图形编程充满了这样节约性能的方法。

粗略地说,绘制画面所需的工作量与需要绘制的东西数量之间的关系是一个简单的比例关系——需要画的东西越多,花费的时间就越多;画得越少,花费的时间就越少。

PERFORMANCE

Let's start with FPS, frames-per-second, as something gamers generally know about.

The higher the FPS the smoother the animation; higher FPS is better, at least to a point. To a first approximation, computers can do a fixed amount of work in a fixed amount of time. The higher the FPS, the less time is available to create a frame of imagery, which means the less work the computer can do to create one image frame.

Thus, game developers are obsessed with "performance", with making things go faster, by making them do less work (because then the game runs smoother, or because then they can put more things in the game and it looks nicer). There are lots of ways to do less work, and game programming and graphics programming are filled with ways of doing this.

To a first approximation, the relationship between the amount of work needed to draw some things and the number of things you can draw is a simple proportion. The more things you need to draw, the more time it takes; the less you draw, the less time it takes.

GPU

GPU 是真正绘制图形的芯片。 但是,通常计算机的 CPU 会进行大量设置并决定每一帧应该绘制什么内容,并进行物理、 AI 和许多其他工作。 CPU 和 GPU 的工作都可以决定最终的帧率,但现在为了保证问题简单,我们只考虑 GPU 的工作。

非常粗略地来说,GPU 主要承担两种工作:第一个与场景中对象的 3D 几何描述有关; 第二个是在屏幕上分别绘制独立的像素。 第一种工作我们简化为“顶点着色”(vertex shading)。 第二种工作我们简化为“像素着色”(pixel shading)。(注:现代 GPU 的功能很多,这里是方便问题说明,提炼出了两个重要的流水线过程进行简化)

GPU

The GPU is the chip that really draws the graphics. However, typically the computer's CPU does a lot of setup and decides every frame what things should be drawn, as well as doing physics and AI and lots of other stuff. Both CPU and GPU work can determine the final frame rate, but let's just think about GPU to keep things simple.

To a very bad first approximation, there are two kinds of work that the GPU is doing. The first is related to the 3D geometric description of objects in the scene. The second is work drawing the individual pixels on the screen. The first kind of work we'll simplify down to something called "vertex shading". The second kind of work we'll simplfy down to "pixel shading".

视锥剔除的性能

当我们按照《地平线:零之曙光》视频中所示进行视锥剔除时,我们会让 CPU 跳过这些告诉 GPU 绘制位于相机 “视锥” 之外的任何东西的过程。 (因为显示器是一个矩形,所以视锥是一个四棱锥;顶部被切掉的金字塔在几何学上被称为“截锥体”,由于各种神秘的技术原因,3D 图形中使用的视锥确实这些同样的点被切断,因此得名 “视锥”。同时跳过绘图,即考虑丢弃,即“剔除”。)这也可能为 CPU 节省一些工作(或花费一些更多的工作!),但请让我们这里只考虑 GPU 的工作。

因为唯一被跳过的东西是视锥之外的东西,所以无论如何它们都是不可见的。如果我们要求 GPU 绘制它们,它会做一堆(不同的、更昂贵的)工作来确定他们最后不会被看到,因此在 CPU 中跳过这些绘制对象根本不会改变最终图像。因为没有像素会被影响,且因为 GPU 这套系统的工作方式,这些对象只会有定点着色器的过程,而不会有像素着色器的过程。

因此,视锥剔除节省了顶点着色器的工作,而不是像素着色器的工作(因为不会完成像素着色器的工作)。

粗略估计,具有 90 度视锥的户外场景可以看到整个 360 度范围的 1/4,因此如果我们比较绘制完整场景与仅在视锥内绘制会发生的情况,我们大约可以跳过 3/4 的顶点着色工作。

GPU 使用与计算像素着色器相同的硬件来计算顶点着色器,因此,对于固定帧率,即每帧给予固定时间去运算,顶点着色节省的时间现在可以用来做更多的像素着色,比如增加像素着色的复杂性(例如图像质量),比如增加场景中对象的数量或几何复杂性(将节省的资源花在顶点着色和像素着色上)。

尽管事情总是在变化,甚至在一代人的时间里,3A 游戏、 “普通” 非 3A 游戏和普通独立游戏之间可能会有很大差异,但可以想象,曾经有一段时间,在许多游戏中,像素着色成本可能明显高于顶点着色,在这种情况下,视锥剔除可能不会对实践中的帧率和每帧的质量产生那么大的影响,因为减少顶点着色并没有节省“那么多”的工作。 (确实,从历史上看,曾经有一段时间 GPU 使用不同的运算单元进行顶点着色,而这样的单元不能用于像素着色,因此节省顶点着色的工作实际上并没有为像素着色提供任何额外资源,尽管这个结论也过于简单化了。)作为图形开发人员的部分经验是,您的旧知识(“视锥体剔除总是值得的”)可能会随着技术的变化而变得无效……然后再次变得有效。

(注:2001 年的 GeForce 3 系列,具体有 Ti200 等型号,是 NVIDIA 第一款引入可编程的定点着色器和像素着色器的 GPU,此时这两种着色器在硬件上还是使用不同的计算单元;而 2006 年的 GeForce 8 系列,具体有 8800 等型号,是 NVIDIA 第一款使用统一着色架构(unified shader architecture)的 GPU,支持用一种硬件着色器处理单元,去处理多种着色器任务,如顶点着色器、片元着色器、几何着色器等等,故同时也诞生了 CUDA,详见 https://en.wikipedia/wiki/Graphics_processing_unithttps://en.wikipedia/wiki/Graphics_processing_unit

FRUSTUM CULLING PERFORMANCE

When we frustum cull as shown in the HZD gif, we have the CPU skip telling the GPU to draw anything that lies outside of the "view cone" of the camera. (Because the display is a rectangle, that view cone is a four-sided pyramid; a pyramid with its top cut off is called a "frustum" in geometry, and for various arcane technical reasons the view cone used in 3D graphics does have its point cut off, hence the name. And we are skipping drawing, i.e. discarding from consideration, i.e. "culling".) This may also save the CPU some work (or cost it some!), but let's stick to the GPU.

Because the only things that are skipped are things outside the view cone, they were never visible anyway. If we asked the GPU to draw them, it would do a bunch of (different, more expensive) work determining they weren't visible, so skipping them in the CPU doesn't change the final image at all. Because no pixels would have been affected, and because of the way the system works, no pixel shader work would ever have been done for those objects at all, only vertex shader.

So, frustum culling saves vertex shader work but not pixel shader work (because no pixel shader work would have been done).

To a very rough approximation, an outdoors scene with a 90-degree view cone sees 1/4 of the full 360 degrees, so if we compare what would happen if we draw the full scene to drawing only within the view cone, we skip approximately 3/4 of the vertex shading work.

GPUs use the same hardware to compute vertex shaders as to compute pixel shaders, so, for a fixed frame rate, aka a fixed time budget per frame, aka a fixed work budget per frame, the time saved on vertex shading can now be spent on more pixel shading, either by increasing the complexity of the pixel shading (e.g. image quality), or by increasing the number or geometric complexity of objects in the scene (spending that savings on both vertex and pixel shading).

Although things are always changing and even in a single generation there may be abig difference between AAA games and the "average" non-AAA game and the average indie game, one can imagine there might once have been a time where in many games, pixel shading costs might dominate over vertex shading costs, and in that situation frustum culling might not make that big a difference to frame/rate quality in practice, since reducing vertex shading isn't saving "that much" work. (Indeed, historically, there was once a time when GPUs used different units for vertex shading than for pixel shading, so saving vertex shading work didn't actually provide any extra resources for pixel shading, and thus no way to leverage the improvement, although even that conclusion is an oversimplification.) Part of the experience of being a graphics developer is that your old knowledge ("frustum culling is always worth it") can become invalid as technology changes... and then later become valid again.

实践中的视锥剔除

几乎所有的游戏都使用视锥剔除,因为它简单、占用资源少并且(通常?)有效。 《玩具总动员》电影就使用过视锥体剔除。 从 90 年代开始,每个预渲染的游戏过场动画都使用了视锥体剔除。 它可能是图形中最普遍的“优化”。

FRUSTUM CULLING IN PRACTICE

Nearly ever game out there uses frustum culling, because it is simple and cheap and (usually?) effective. The Toy Story movies used frustum culling. Every pre-rendered game cutscene from the 90s used frustum culling. It is probably the single most ubiquitous "optimization" found in graphics.

加载与卸载

视锥剔除没有做的一件事是“加载”或“卸载”场景(虽然 Kotaku 文章没有声明这一点,但我已经看到其他使用这种术语进行剔除的半技术文章)。

通常,开发人员使用加载/卸载来指代内存(RAM)中的事物。它可能指从磁盘加载到 CPU 的内存,也可能指从 CPU 的内存加载到 GPU 的内存(有时称为“上传”)。

“流式传输”通常用于描述当相机在开放世界中移动时加载/卸载地形块的过程。这与上述定义的性能没有直接关系,通常是因为只有有限数量的 RAM;由于 CPU/GPU 只能渲染 RAM 中的内容,因此有必要从该内存加载/卸载内容。但是,在大多数游戏中,你都可以随机且不可预测地旋转相机,在此时加载/卸载内容没有意义——你可能几乎立即再次需要它,因此最好将其保存在 RAM 中而不是绘制它。

(一个例外:id Software 的游戏《狂怒》可以在您转动相机时加载/卸载纹理。另一个:似乎某些版本的《我的世界》可能会根据相机角度进行一些加载/卸载工作,尽管游戏开发人员通常不认为 《我的世界》是图形优化或图形质量的典范。)

一些对象看起来像是被“卸载”了,因为计算机并没有绘制它知道的看不到的东西;但是在视锥剔除的场景下,这些对象仍然“存在”,它们在某种意义上只是“隐藏”了;而如果卸载,在某种意义上,计算机甚至根本不知道那里有什么。例如,如果卸载了某些东西,游戏通常无法计算该区域的物理;所以所有“远处”的东西可能会停止移动,因为它们被卸载了(在这种情况下你看不到它们,所以你看不到它们停止移动),但是靠近但在相机后面的东西不会停止移动(所以他们仍然可以从你身边驶过,或者在你倒车或爆炸时挡住你的路)。当然,凡事都有例外。

LOADING/UNLOADING

One thing frustum culling is not doing is "loading" or "unloading" the scene (and while the Kotaku article doesn't claim this, I have seen other semi-technical articles that used this kind of terminology for culling).

Generally, developers use loading/unloading to refer to things being in memory ("RAM"). It may refer to loading from disk into the CPU's memory, or it may refer to loading from the CPU's memory to the GPU's memory (sometimes called "uploading").

"Streaming" is often used to describe the process of loading/unloading chunks of terrain as a camera moves in an open world. This is not directly related to performance as defined above; typically there is simply a finite amount of RAM; since the CPU/GPU can only render things that are in RAM, it is necessary to load/unload content from that memory. However, in most games you can turn randomly and unpredictably, and it doesn't make sense to load/unload content as you turn--you might need it again almost immediately, so better to just keep it in RAM and not draw it.

(An exception: the id software game Rage could load/unload textures as you turned the camera. Another: it seemed like some versions of Minecraft might have done some loading/unloading depending on camera angle, though game developers do not generally consider Minecraft a paragon of graphics optimization or graphics quality.)

It can look like objects are "unloaded", because the computer isn't trying to draw the things it knows can't be seen; but in the case of frustum culling, they're still "there", they're just "hidden" in some sense; whereas if unloaded, there is a sense in which the computer wouldn't even know what was there at all. For example, if something is unloaded, the game typically can't compute physics in that area; so everything "far away" might stop moving because they're unloaded (in which case you can't see them, so you can't see that they stop moving), but things close but behind the camera do not stop moving (so they can still drive past you, or get in your way if you're backing up, or explode). As always, there are exceptions.

常见的的图形优化手段

如前所述,图形“优化”很重要,因为它可以腾出 GPU 的时间来渲染更多、更好的东西。 因此,图形实践(以及“学术”图形文献)充满了在 GPU 上节省工作的方法,例如:

  • 视锥剔除(尽量不绘制因为在视锥体外而无法看到的东西)
  • 遮挡剔除(尽量不绘制因为被其他东西遮挡而无法看到的东西)
  • 细节层次(LOD,省略因为距离太远而无法辨别出来的几何上的小细节)
  • 更简单的控制物体如何反射光的数学近似方程

还有很多方法可以节省 CPU 上的工作,这里就先列举这些。

GRAPHICS OPTIMIZATION IN GENERAL

As stated, graphics "optimization" is important because it frees up GPU time to render more, better stuff. Thus, the practice of graphics (as well as the "academic" graphics literature) is replete with ways of saving work on the GPU, such as:

  • frustum culling (not trying to draw things that can't be seen because of the view cone)
  • occlusion culling (not trying to draw things that can't be seen because they're behind other things)
  • level of detail (skipping small geometric details when things are far enough away those details can't be made out anyway)
  • simpler mathematical approximations to the equations governing how things reflect light

There are also hosts of ways of saving work on the CPU, but I've bored you enough already.

写在最后

几乎每个游戏都使用了一些或更多的 “聪明的技巧”,这就是一些开发者对 Kotaku 这篇文章反应过激的根本原因:没有迹象表明《地平线:零之曙光》做得比其他任何人都更好,所以一些游戏开发者可能认为它在做不必要的公关吹嘘,在这方面批评它。 另一方面,Kotaku 的文章实际上是在引起人们对这部视频的关注(或者说是公关?),而不是《地平线:零之曙光》或《地平线:零之曙光》的开发人员。

(当然,也许《地平线:零之曙光》确实有一些独特的聪明技巧!如果是这样,我们可能终有一天会发现的,因为游戏开发的社区里的大家(也许令人惊讶)都很乐意相互分享聪明的技巧。)

FINAL NOTE

Almost every game uses some or more of these "clever tricks", and this is the source of some of the developer backlash over the Kotaku piece: there is no indication that HZD is doing anything more clever than anybody else, and so some gamedevs may perceive it as needless PR puffery to single it out on that front. On the other hand, the Kotaku article is actually calling attention to (giving PR to?) a documentary, not to HZD or to HZD devs, so.

(Of course maybe HZD does have some unique clever tricks up its sleeve! If so, we may find out some day, because the gamedev community is (perhaps surprisingly) open about sharing clever tricks with each other.)

更多推荐

为什么视锥剔除重要,却又不重要 | Why Frustum Culling Matters, and Why It‘s Not Important

本文发布于:2023-06-14 08:32:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1456573.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:却又   不重要   Frustum   Important   Matters

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!