vue 移动端点击延迟_使用Vulkan的renderpass加速移动端延迟渲染

9ee7e60d09c3065337b6eb0e07725e4f.png

由于本人才疏学浅,翻译难免有误,望各位不吝惜指正。


感谢两位作者,今天为大家分享使用Vulkan的renderpass加速移动端延迟渲染。

fd9047ea905783b483eaffb22d7b8aa8.png

内容

  • multipass是什么?
  • multipass可以做什么?
    • 驱动可以做什么
    • 开发者可以做什么
    • 临时图像和LAZILY内存分配
  • 案例
    • Baseline
    • Sponza
    • Lofoten

f97d412cd202af4f8493c19ead4f2833.png

multipass是什么?

  • 一个renderpass可以有多个subpass
  • subpass之间可以设定依赖关系
    • render pass的关系可以用图表示
  • subpass可以只使用附着的一个子集

2a88d1674d7b94be3e26879af945803e.png

Vulkan对延迟渲染的提升

  • 经典的延迟渲染算法包含两个render pass
    • G-Buffer pass,渲染4张纹理
    • Lighting pass,读取G-Buffer,进行光照着色
  • Lighting pass只读取了gl_FragCoord位置处的G-Buffer数据
  • 考虑使用Vulkan的multipass来实现延迟渲染
    • 需要两个subpass
    • 需要使用的依赖
      • COLOR | DEPTH -> INPUT_ATTACHMENT | COLOR | DEPTH_READ
      • VK_DEPENDENCY_BY_REGION_BIT

3910a4f27c35c64d6768236c61c17e9b.png

Tile-based GPU

  • Tile-based GPU会将一个render pass的所有primitive按tile打包
  • 在片段处理阶段,一次渲染一个tile
    • 硬件具有覆盖这一tile的所有primitive信息
    • framebuffer的数据在更快速,但也更小的SRAM中
  • 让framebuffer数据保持在on-chip SRAM好处很大
    • 读写这一区域的代价极小,不占用外部带宽
  • 当一个tile渲染完后,才会被写入主存

b44daeb33ad3c15b366d9f24e5deedff.png

针对Tile-based GPU的subpass融合

  • subpass在渲染前已经确定
    • VkRenderPass
  • 驱动会查找具有下列属性的subpass
    • BY_REGION依赖
    • 没有影响subpass融合的外部因素
  • 融合G-Buffer pass和Lighting pass
    • 将对G-Buffer和Light的draw call放进同一个renderpass
    • G-Buffer的内容会被保持在on-chip SRAM
    • 在Lighting pass读取G-Buffer数据只读取了tile的buffer
    • vkCmdNextSubpass实质上变成了一个空操作

6955670c33353d2a830e5fbce2dd2470.png

Vulkan GLSL subpassLoad()

  • 读取input附着需要特别处理
    • SPIR-V中的特殊image类型
  • 调用vkCreateGraphicsPipelines,需要下面这些信息
    • render pass
    • subpass index
  • subpassLoad()会变成
    • texelFetch(),如果subpass没有被融合
      • 这也是我们需要特殊的VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT的原因
    • magicReadFromTilebuffer(),如果subpass被融合
  • shader编译器可以在创建管线时进行预处理
    • 避免在最后一刻为shader打补丁带来的不必要的性能损耗

f42d6fefb5f7e76c9f63e4d534ec8e2b.png

临时附着

  • Lighting pass后,G-Buffer中的数据不再需要
    • G-Buffer中的数据实际上只需要保持在on-chip SRAM
    • render pass开始时的清除操作,不需要读取主存
    • storeOp设置为DONT_CARE,不会将G-Buffer写到主存
  • Vulkan可以设定分配的内存类型和用途
    • imageUsage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
    • memoryProperty = VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
    • 在tile-based GPU上,不会将这类数据写回主存

7ee422d90c240fdcee5ed5dfbae2a58d.png

multipass的优点

  • 统一了移动和桌面平台的延迟渲染设置
    • 相同的Vulkan代码
    • 相同的shader代码
  • VkRenderPass包含的信息有利于:
    • 桌面平台可以更好地进行调度处理
    • 桌面平台地GPU有向tile-based转变地趋势
    • 最差情况下,它就是经典的MRT
  • G-Buffer的布局可能会进行微调

a64a9e25c8984b4ca4910453fbdbe0b1.png

e01956cf84b400bd37de0cc908414caa.png

Baseline测试

  • 基本的multipass采样
  • 一个renderpass
  • 几何体打光
  • 8个光源
    • 简易的着色
  • 基准指标
    • multipass(subpass融合)
    • MRT
    • 整体性能表现
    • 带宽

e51acab85b37f18bd1a4d12479d5b471.png

a69819ce9155418b0166c153bf0937f7.png

Baseline测试数据

  • 测试在Galaxy S7 (Exynos)上进行
  • 4096x2048分辨率
    • 垂直同步与1440p相同
  • ~30%的fps提升
  • ~80%的带宽减少
    • 只使用了albedo和normal
    • 节约了对于移动平台GPU至关重要的带宽

be10795284cbbed6aee79ba19594c3ff.png

Sponza测试

  • 对于移动端来说的中高复杂度的模型
    • 每帧~200k三角形绘制
  • ~610个点光源
    • 完整的PBR
    • 对部分光源生成阴影贴图
  • 8个反射探头
  • 方向光和阴影
  • 完整的HDR管线
    • 自适应tonemapping
    • Bloom

fabe48ea62c59d6f608670fae1291f3c.png

ca688d307ea9896db142e814d7c5a206.png

11eaa15d10805c3c635a13028a25161a.png

b94575ba4d90849b36a527c658ccecb4.png

c705232cef25025af9adab444865bd09.png

83e0fd415b0b243dcaa709df5acd5de0.png

Clustered stencil culling

  • 经典的light stencil culling算法包含大量切换状态的操作
    • 即使使用Vulkan仍然代价非常大
    • 在GPU上表现不佳
  • 将局部光源沿相机Z轴进行划分
    • 每个光源按depth被归属于一个cluster
    • 在一个pass为所有局部光源写入stencil信息
    • 使用stencil额外的2位depth buffer进行depth peel
    • 使用double sided depth test渲染光源

b84e74dbbd296e0c3db54435d62af7e1.png

308f729eded3d3d4e94969c9ac7607da.png

Sponza测试数据

  • 远远超过移动平台能力的数据量
  • 1440p
    • 过度的压力
  • ~50%-60%带宽减少
  • ~18%帧率提升

a83b877767b3532637c49e4829377b32.png

05678a425e7e33d447635e35c80997ac.png

Lofoten

  • 包含~2.5百万个图元的城市场景
    • 重度依赖CPU端的场景剔除来减少负载
  • 100个聚光灯和点光源以及它们的阴影贴图
  • 反射探针
  • 太阳光以及它的CSM
  • 大气散射
  • 海水模拟
    • GPU计算的FFT
    • 独立的折射pass
    • 屏幕空间反射
  • Bloom和自适应色调后处理

141f0866fccffff5534531bf48e1d949.png

ba65c13bce57c0199ed82f99e06de0b5.png

实现细节

  • G-buffer pass
    • 对于tile-based GPU来说,填充速率不等于带宽
    • 光照材质信息直接写入light buffer
    • 使用模板标记反射影响范围
    • 用于clustered stencil culling的depth peeling
  • Lighting pass
    • 使用混合添加光照
    • 用于局部光源的Clustered stencil culling
    • 透明物体
    • 着色后的雾处理
  • 只需要提交light buffer到内存

e20d5584384ea500d09170fb7655b18a.png

Render pass

  • 高层接口显式定义render pass
    • OpenGL等也可以作为后端实现
  • BeginRenderPass()
  • NextSubPass()
  • EndRenderPass()

4f8c0f2be0835ef731a1b157b9008cce.png

整合临时资源

  • 添加虚拟附着支持
    • 建立以TRANSIENT_ATTACHMENT_BIT标记分配的图像资源池
    • 实际的图像处理对API用户不可见

a030c84b85f4ea2f9848106759d6c97a.png

69a72e044c9842696ffa9a161c2dec18.png

Lofoten测试数据

  • 比Sponza更大的数据量
  • 1440p
    • 过度的压力
  • ~50%带宽节约
  • ~12%帧率提高
  • ~25%GPU资源节约

deb02e469a41fbe4521060d2186415c9.png

4bc9a03b7ea5861a12ca55883217abf1.png

tile-based GPU的性能考虑

  • 因为on-chip SRAM的存在,每个像素的buffer大小有限制
    • G-Buffer大小也因此受限
  • 对于目前的Mali硬件,每个像素可以有128位空间大小
    • 可能会因GPU的不同而有所不同
  • 较小的tile可以使用更大的G-Buffer
    • 但会有较大的性能损失
    • 更少的活动线程,着色器核心使用较少
    • 需要更多次地扫描tile列表

1143be94624f9b3095389d07f74501cd.png

引擎对多种API的整合

  • 引擎需要有render pass的概念
    • 否则无法表示多个subpass
  • subpassLoad()是Vulkan GLSL特有的
    • 方案1,将Vulkan GLSL作为主要的着色语言
      • SPIRV-Cross可以将subpassLoad()调用映射到MRT风格的texelFetch
    • 方案2,使用HLSL或者类似着色语言
      • 定义自己的指令,引发Vulkan执行subpassLoad())
  • 将multipass展开来满足其它API的要求
    • 在NextSubpass()改变渲染目标
    • 将subpass使用的input附着绑定到纹理单元
    • 在shader中静态地映射input_attachment_index到纹理单元

9c6eb2e4c9f90c6f8f39b13f2725b482.png

处理图像布局

  • G-Buffer图像的使用是临时的
  • 不需要知道使用什么布局
    • 程序不应该直接访问G-Buffer图像
  • 可以使用VK_SUBPASS_EXTERNAL作为subpass依赖

最后放个图

e943808c61b4893f86d8431dd38daff2.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值