StoneのBLOG

生活这种事情,从来都是自我陶醉

0%

游戏中的渲染

游戏中的渲染是一个很大的概念,以至于我都不知道该怎么分类。于是便将其制作成了一个分类。因为在游戏的制作过程中关于渲染的知识无处不在,我在优化游戏的部分也记录了很多关于渲染流程的部分,但还是不够。

关于渲染,我所理解的是:

  • 了解渲染流程
  • 和渲染相关的技术
  • 优化渲染

我知道上面的肯定不是准确的,暂时先记着。

渲染流程

我在最适化的文章中有提到一些渲染流程的知识,但是那只是非常宽泛的概念具体做了哪些事情不去实现一遍渲染流程我应该是不会了解的。更加具体的内容我也只能一点点更新了。好了废话就说到这里了,之后关于渲染的相关内容就整理到这篇文章里。

渲染网格

创建这篇文章的初衷就是为了这篇文章:

这里面有提到GPU处理多边形数据的内容

  • 多边形数据存储
  • 绘制多边形
    • 这里有些在意的是动画处理的时候顶点着色器的动作是什么样的
  • 顶点缓存
  • 顶点参数
    • 这里的内容不是特别明确,主要是使用的场合有什么区别

      为了准确照亮表面,通常每个顶点都存储一条法线,即从表面向外指出的一个矢量。让所有多边形共享一个由同一条法线定义的顶点,可以使形状看起来非常平滑。这便是所谓的平滑着色。如果每个三角形都有自己的法线,那么多边形之间的边缘将凹凸不平,而表面光滑平坦,这就是它为什么被称作平面着色。

  • 评估形状
    • 感觉之前在哪篇文章中有读到过,GPU并不是单个的像素一个一个处理,而是一块一块的像素进行处理,也就是说这个一块里面未必会全是我们想要绘制的,优化网格的形状,尽可能避免长而细的网格会有效降低GPU绘制资源的浪费。

      GPU 的速度很快,主要因为它能并行执行许多操作。GPU 营销材料通常强调它们拥有的管道数量,这决定了 GPU 所能同时执行的操作量。GPU 绘制多边形时,它会分配许多管道来填充一方块像素。通常是维度大约为 8 × 8 像素的一个四方形。GPU 持续执行直至填满所有像素。显然,三角形不是四方形,因此四方形中的部分像素位于三角形内部,部分像素位于三角形外部。硬件将分配给四方形中的所有像素,甚至是哪些落在多边形外部的像素。计算完四方形中的所有顶点后,硬件就会舍弃三角形外部的像素。

  • 过度绘制
    • 场景中不可避免的出现一些重复绘制,比如说有遮挡的部分的片元在大多数无意识的情况下被绘制两次甚至更多次,在这片元的位置遮挡物与被遮挡物没有意识的情况下都会被绘制一遍。

      一些引擎采用高级算法以避免绘制最终图像中所没有的对象,但非常困难。相比 GPU 进行绘制,CPU 通常需要更长的时间来确定不需要绘制的内容。
      一些情况下我们想要删除被遮挡的部分的网格(比如说两个静态模型重合的部分),但是这个时候有需要我们的判断,因为减少多边形换取部分过度绘制和添加多边形避免过度绘制,在时间的维度上总是此消彼长的关系。
      在这类场景中,您需要执行判断调用。有时候值得通过减少多边形来换取部分过度绘制。有时候值得添加多边形以避免过度绘制。
      出现各种情况也只能具体问题具体分析。

  • 使用绘制调用(DrawCall)
    • 这里我发现了一个我之前从未注意到的问题:CPU每帧能发出多少DrawCall命令?GPU每帧能处理多少多边形?在固定帧数的情况下,那么每一帧的时间是固定的,如果在这一帧固定时间里,GPU能够胜任CPU的绘制调用,那么为网格增加多边形数量就是免费的。反之同理。

      GPU 的速度非常快,CPU 很难跟上它们。由于 GPU 基本上只执行一项操作,因此它们更容易加快执行速度。显卡,顾名思义,就是计算多个像素,因此能够构建并行计算许多像素的硬件。但 GPU 仅调用 CPU 让其绘制的内容。如果 CPU 不能快速反馈 GPU,GPU 就会闲置。每次 CPU 让 GPU 绘制某一内容就称为绘制调用。基本绘制调用包括绘制一个网格,包含一个着色器和一组纹理
      绘制调用的构成及其成本可能因引擎和架构的不同而有很大差异。有些引擎能够以单次绘制调用的形式批处理许多网格,但所有网格都需要有相同的着色器或满足其他限制条件。Vulkan、DirectX 12 等新 KPI 经过专门设计,可通过优化程序与显卡驱动程序之间的通信来解决这一问题,从而增加每帧发出的绘制调用数量。