目录
第6章 动态图形
现代图形设备的渲染管线相当复杂。即使在屏幕上渲染一个三角形,也需要执行大量的图形API调用,其中包括许多任务。
本章学习如何收集正确的数据,深入了解管线渲染,并探索各种解决方案和解决大量潜在问题的方法。
6.1 渲染管线
在确定GPU瓶颈的过程中,可能需要采用一些猜测或过程排除法查找原因。
CPU的命令放入“命令缓冲区“(CommandBuffer)的队列,GPU逐一处理。只要GPU能在下一帧之前跟上指令的速度和复杂度,帧速就保持不变。然而,如果GPU跟不上,或者CPU花费太多时间生成命令,帧速率将开始下降。
6.1.1 GPU前端
前端是指渲染过程中GPU处理顶点数据的部分。它从CPU中接收网格数据(一大堆顶点信息)并发出DrawCall。
顶点->图元(三角形)->片元(像素)
这里有顶点着色器和几何着色器。
6.1.2 GPU后端
后端描述了管线渲染中处理片元的部分。
片元着色器比顶点着色器包含更复杂的活动:深度测试、alpha测试、着色、纹理采样、光照、阴影以及一些可行的后期效果处理。
图形API默认使用两个帧缓冲区,流程的最后一步是切换帧缓冲区。
在后端,有两个指标往往是瓶颈的根源:填充率和内存带宽。
1.填充率(Fillrate)
填充率指的是GPU绘制片元的速度,这些片元指的是通过各种条件测试后的片元。片元只是一个潜在的像素,只要它未通过任一测试,则会被立即丢弃。一个可能导致片元被丢弃的测试是Z-测试。
显卡的填充率越高,说明设备通过管线渲染可处理的片元数量越多。
公司里的各个显卡:
家里小米笔记本的显卡(双显卡):
参数上的能力是理论上的最好情况,填充率会被其他高级渲染技术所消耗,例如阴影和后期效果处理需要提取同样的片元数据,在帧缓冲区中执行自己的处理。
由于渲染顺序的限制,总会重绘一些相同的像素,称为过度绘制。这是衡量填充率是否有效使用的一个重要指标。
Scene窗口的Overdraw Shading模式直观显示过度绘制的程度。
HDRP下好像没有这个,HDRP/URP的渲染过程还需要另外找资料了解。
过度绘制越多,覆盖片元数据所浪费的填充率就越高。
渲染分为透明队列和不透明队列,透明队列是过度绘制的主要来源。
2.内存带宽
只要从GPU VRAM的某个部位将纹理拉入更低级别的内存中,就会消耗内存带宽。这通常发生在对纹理采样时。
GPU有多个内核,每个内核都可访问VRAM的相同区域,还都有一个小得多的本地纹理缓存,来存储GPU最近使用的纹理。这种设计和CPU的多级内存缓存结构类是。
内存带宽通常时基于每个内核列出。
---------------------------
这里没有具体指出“内核”是什么,GPUZ里面也没有这个,CPU能够在设备管理器和资源管理器中看到几个CPU,而GPU只有一个。
搜索了一下,GPU有个SP的概念。
sp:是最基本的处理单元,streaming processor 最后具体的指令和任务都是在sp上处理的。GPU进行并行计算,也就是很多个sp同时做处理。
https://blog.csdn.net/asasasaababab/article/details/80447254
GPUZ里面有个 着色器:NN单元,这个是基本的单元吗?
说是GPU的“内核”是商业炒作出来的一个概念
RTX5000的参数里有三处是Cores的
6.1.3 光照和阴影
测试:没有任何光照和阴影信息的Shader的模型的渲染性能测试。
在现代游戏中,单个对象很少能在一个步骤中完成渲染,主要原因是光照和阴影。这些任务通常在片元着色器的多个过程中处理,对于多个光源的每一个都处理一次。
阴影信息的收集需要多个过程,这些信息最终变成附加的纹理,称为纹理阴影(Shadowmap)。
在管线渲染的所有过程中,光照和阴影往往会消耗大量的资源。和大多数其他渲染特性相比,实时阴影异常昂贵,在启用后会显著增加DrawCall数。
Unity提供了多种影响光照和阴影的特性,包括实时光照和阴影到名为Lightmapping的静态光照。
LightingOverview.html
渲染有两种不同的方式:前向渲染和延迟渲染
1.前向渲染
前向渲染是场景中渲染灯光的传统方式。在前向渲染中,每个对象都通过同一个着色器进行多次渲染。渲染的次数取决于光源的数量、距离和亮度。
使用前向渲染处理带有大量点光源的场景,将导致DrawCall计数呈爆炸式的增长。
2.延迟渲染
延迟渲染有时又称为延迟着色,已经使用10年的技术,未能完全取代前向渲染。
延迟着色的实际着色发生在处理的后期,也就是延迟到后期才发生。
它的工作原是创建一个几何缓冲区(称为G-缓冲区),在该缓冲区中,场景在没有任何光照的情况下进行初始渲染。有了这些信息,延迟着色系统可以在一个过程中生成照明配置文件。
3.顶点照明着色
目前仅存的照明方法是顶点照明着色和很原始、功能粗放的延迟渲染版本。
顶点照明着色是光照的大规模简化处理。
该技术主要应用在一些不需要使用阴影、法线映射和其他照明功能的简单2D游戏。
4.全局光照
全局照明(Global Illumination,GI),是烘培Lightmapping的一种实现。Lightmapping类似于阴影映射技术创建的Shadowmap,其为每个表示额外照明信息的对象生成一个或多个纹理,然后在片元着色器的光照过程中应用于对象,以模拟静态光照效果。
6.1.4 多线程渲染
多线程渲染默认开启,低端设备可手动切换。
渲染过程3个任务:首先确定对象是否需要渲染(通过视锥剔除技术),如果需要,就生成渲染对象的指令(因为单个对象的渲染可能产生数十个指令),最后调用相应的图形API将指令发送到GPU。
在没有多线程渲染的情况下,渲染相关任务都在CPU的主线程上执行,那么主线程上的任何活动都将成为渲染的关键路径的节点。
多线程渲染启动时,渲染线程会将指令推送到GPU,其他任务则分散到多个工作线程中。
6.1.5 低级渲染API
Unity通过CommandBuffer类对外提供渲染API。这允许通过C#代码发出高级渲染命令,来直接控制管线渲染。
如果需要更直接地控制渲染,需要创建本地插件(c++编写),挂接到Unity的管线渲染。