缓冲区|UE渲染师Dyomin:做次世代手游,可以用好这项技能( 二 )


延迟着色在移动端的性能演示
现在我们来了解一下为什么延迟着色在移动端GPU上的操作以及它更好的性能。
移动端GPU大多基于图块,这意味着它们会将帧缓冲区分布到名为图块的更小区块上,然后依次渲染这些图块,且只将最终结果存储到系统内存中,所有图块的渲染都消耗很小,不会将中间结果存入系统内存。这有助于减少内存带宽开销。

缓冲区|UE渲染师Dyomin:做次世代手游,可以用好这项技能
文章插图

但在延迟着色时,你必须为每个tile做两个pass,因此你必须存储中间数据,也就是G缓冲区,将它存入系统内存,然后第二pass会把它采样为纹理并应用光照,从而计算最终像素颜色。
在GPU和系统内存之间,用这种方法移动G缓冲区数据并不高效,我们想要实现的是在单个pass中实现多pass渲染,并且不将中间数据存入系统内存,这样的话 就在保持单个pass渲染的优点的同时,保持了材质和光照数据的相互独立。
为此,负责应用光照的着色器,需要设法获取G缓冲区数据,并将其采样为纹理。
我用的是Metal、Android Vulkan和Android OpenGL,它们都能做到这点,但它们各自的做法都略有不同。
Vulkan是一种现代化的图形API,大部分现代安卓设备都支持它,这是一种非常显性的API,因为它的接口考虑到了基于图块的GPU的运行。

缓冲区|UE渲染师Dyomin:做次世代手游,可以用好这项技能
文章插图

Vulkan渲染过程被分为多个子pass,这些子pass通常有着各自要执行的任务。不过我们可以将多个子pass融合为一个pass,如果可行的话意味着我们可以用较小的消耗保持G缓冲区,而无需把它移动到系统内存,这能节省大量外部内存带宽,这对移动端非常重要。
关于移动端的延迟着色,我们最终会得到三个子pass:第一个是G缓冲区渲染子pass,它会写入G缓冲区,并填充深度附件;第二个是贴花子pass,我们会向G缓冲区写入,但深度是只读的,不过深度还是可以被获取;最后的子pass我们只会向场景颜色写入,并获取G缓冲区和深度。在这里将所有光照都处理完后,我们会利用前向着色来渲染半透明。最终,一切大功告成。
强调一下,我们总共有三个子pass,它们都被融合为一个pass。第二个子pass往往是空的,场景里面并不总是有贴花的,但我们还是要把它做出来。这是为了避免出现两种不同的渲染pass配置,导致渲染pass配置会被烘培进管线状态对象。

缓冲区|UE渲染师Dyomin:做次世代手游,可以用好这项技能
文章插图

Metal的原理与之相似,处理要简单的多。因为在iOS版的Metal上,你无需在渲染pass中分清具体的子pass,以及它们之间的依赖性。在Metal的着色语言中,你可以宣称某些附件为某个碎片着色器的输入。然后,它们就有了G缓冲区数据。利用这个机制,你可以实现程序的混合,也可以实现不同的着色功能。

【精彩生活】jing111.com小编为您精选以下内容,希望对您有所帮助: