[翻译] Vulkan-Sample-MSAA (Multisample anti-aliasing)

原文

Aliasing是以低于原始信号采样率的采样率进行采样导致的。在图形学中,这个过程可以描述为:基于一个会产生artifacts的分辨率去计算像素值,从而在模型边缘产生锯齿。多重采样抗锯齿(Multisample anti-aliasing,MSAA)是一种可以减少像素采样误差的技术。在下面的图中,左侧的图是没有进行抗锯齿渲染的,而右侧的使用了4倍的MSAA。

在计算像素的颜色时,GPU会根据给定的图元有没有覆盖像素的中心坐标(前提是这个图元通过了深度测试),来决定这个像素的颜色。如下图所示,如果不进行抗锯齿,fragment shader就是根据“有没有覆盖像素的中心坐标”来决定像素的颜色的。这样的单采样的方式会不会造成锯齿,就取决于像素密度了。

使用多重采样反锯齿,会在一个像素内进行多个位置的测试。在下图中,有四个采样点,因此称为4倍的MSAA。因为每个采样点都需要存储一个颜色值,所以MSAA实际上增加了每个像素的分辨率。需要注意的是,fragment shader仍然只计算一次(使用中心坐标),这时候像素的颜色结果取决于那些落在图元内的采样点的值(fragment shader会计算这个像素的前提仍然是这个图元通过了深度测试,这意味着深度缓冲区也需要更大,以容纳每个像素多个值)。换句话说,片段着色器的值将会是所有被覆盖到的采样点的值合的结果。像素的值会是所有采样点的平均值。以上便是MSAA的步骤。这样的思路里,

边缘处的图元的shader是不一样的,从而改善了锯齿效果。

在上图中,一个像素内采样点的位置,像一个被旋转过的网格,采样坐标在spec 中规定。不同的模式会水平边缘或者垂直边缘获得更好的结果。请注意,MSAA只对边缘有影响,对于图元内的像素没有影响,因为对于内部的像素,所有采样点存储相同的颜色值。

MSAA与超级采样反锯齿(SSAA)不同(MSAA效果更好),在SSAA中,对每个采样点都执行一遍片段着色器。这有助于减少图元内的锯齿状效果,但通常使用mip-maps已经缓解了这个问题。

要启用MSAA,首先查询 vkPhysicalDeviceLimits ,选择支持的MSAA级别,例如 VK_SAMPLE_COUNT_4_BIT,并在创建 multisampled attachments 和 设置图形管线中的pMultisampleState 的 rasterizationSamples 成员时使用它。正如前面所述,对于MSAA,我们不希望设置 sample shading,因为这意味着开启了更昂贵的SSAA。

Color resolve

tiler architectures 中做4倍MSAA是非常合适的,因为颜色解析可以在tile内存中做,因此是一个临时存储,典型的应用是下图的depth buffer。

(1. "Transient"(临时):在这里,"transient"是指将 multisampled attachments 分配为临时内存,意味着它们不需要持久存储和写回主存。这可以提高性能,因为避免了将多重采样数据写回主存的开销。

2. "Necessary load/store"(必要的加载/存储):这指的是对多重采样附件进行读取和写入操作是必要的,因为在渲染过程中需要对其进行处理或使用。这意味着在渲染通道的子通道中,需要正确配置加载和存储操作,以确保正确处理多重采样数据。

3. "Avoidable load/store"(可避免的加载/存储):这指的是在渲染过程中不再需要对多重采样附件进行读取和写入操作。如果已经使用了颜色解析等技术将多重采样数据转换为单一采样数据,并且不再需要多重采样数据,那么对其进行加载和存储操作将是可避免的开销。)

很重要的点是,如果在渲染场景后不再需要 multisampled attachments,那么需要避免将 multisampled attachments写出到内存。也就是说,multisampled attachments 必须使用 storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE 并且 usage |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,并按照 Render Passes tutorial 中解释的方式使用 LAZILY_ALLOCATED 内存属性分配图像。

// multisampled attachments是临时的
// 这使得tilers可以完全避免将multisampled attachments写入到内存中,
// 显著的性能和带宽改进
load_store[i_color_ms].store_op = VK_ATTACHMENT_STORE_OP_DONT_CARE;

如下所示,为了在write-back过程中(write-back是指在渲染管线结束时将图像数据从 GPU 内存返回到 CPU 内存的过程)解析颜色,请配置subpass,将 pResolveAttachments 指向我们希望多采样颜色解析到的那个单采样附件(single-sampled attachment),在本例中是名为 swapchain 的图像。

// Good practice
// 启用write-back 解析到单采样附件(single-sampled attachment)
subpass->set_color_resolve_attachments({i_swapchain});

启用了4X MSAA后,我们所渲染到的color attachment 是一个更大的color attachment ,这个color attachment 里面,每个像素会存储4个颜色值。如果把这个attachment 保留在 tile 内存中,性能的影响仍然很小(如上面屏幕截图中所示,带宽增加3%),而在边缘处会使抖动现象大大减少。原因正是前面所说的,因为硬件在将image写回主内存时对multisampled attachmen作了解析(对样本进行平均处理) 。

Vulkan提供了一种替代方法,使用 vkCmdResolveImage 来明确定义颜色附件的单独解析步骤:

// Bad practice
//将多采样附件解析到目标位置,非常昂贵
vkCmdResolveImage(cmd_buf.get_handle(),
                  multisampled_img.get_handle(),
                  VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                  swapchain_img.get_handle(),
                  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                  to_u32(regions.size()), regions.data());

这种做法会产生较高的性能开销和内存占用,因为在这个做法里,需要在subpass 结束的时候存储这个multisampled attachments,并把这个比frambuffer大四倍的attachment 写回GPU以进行解析。

如图所示,这种方法消耗了更多的带宽,如果有其他实现方法,不建议在write-back过程中使用pResolveAttachments 解析颜色。为了说明这一点,示例中设置了切换选项:一种是 resolving on write-back(在write-back期间解析颜色),另一种是在separate resolve pass(单独的过程中解析颜色),并监视由此对带宽的影响。

截图所示的在搭载 Mali-G76的高端智能手机的结果,带宽的差异可以如下解释。当示例渲染2168 x 1080像素的图像,每个像素需要32位(RGBA8,4字节),帧率为60FPS:

1Xattachment :2168 * 1080 * 4 * 60 = 562字节/秒
// 这里比较奇怪,我自己计算的结果是↓
// 字节(Byte)和位(Bit)之间的换算关系是:1 字节(Byte) = 8 比特(Bit)
// 字节(Byte)和M 之间的换算关系是:1MB = 2E+20 Bytes = 1048576Bytes
// 2168 * 1080 * 4 * 60 = 561,945,600 字节/秒 = 536 M/s

如果我们需要为每个像素存储4个样本值,则将其乘以4:

4Xattachment :2168 * 1080 * 4 * 4 * 60 = 2247字节/秒

比较上面屏幕截图中计数器数字,读取和写入带宽都大约增加了4倍attachment 的大小,因为在当前场景renderpass结束时需要将 multisampled attachments 写出,然后重新读取,再解析得到最终的颜色。这意味着 separate resolve pass导致带宽增加了5GB/秒。考虑到在移动设备中,外部DDR带宽的成本约为每GB/秒100毫瓦,这个500毫瓦的开销占据了设备大约2.5瓦功耗预算的20%,这是非常昂贵的。

这些计数器还可以使用Streamline之类的分析工具来记录,图示显示的 resolving on write-back的过程在前,随后进行separate resolve pass的过程。 

Depth resolve

在上面举的例子中,无论 MSAA 是如何设置的,深度缓冲区都是临时存储的。这是因为当颜色值被计算出来,写出到swapchain给显示器显示用后,深度值就没有用了,因此我们建议配置加载/存储操作以避免将其写出。

有时候我们可能需要保存 depth attachment。比如一些简单的post-processing pass需要同时对颜色和深度采样(作为纹理绑定),从而计算出基于屏幕空间(而不是世界空间或裁剪空间)的一些特殊效果。(比如SSAO(Screen Space Ambient Occlusion))

和我们的预判一致,在这种情况下,增加的带宽约等于写出两个全屏附件的attachment。只要我们记住在write-back 期间解析颜色和深度,使用 4X MSAA 几乎不会带来额外开销。

为了在 write-back期间解析depth值,需要使用 VK_KHR_depth_stencil_resolve (从 Vulkan 1.2开始支持) 。在配置subpass的时候, 我们必须使用 VkSubpassDescription2 a并将 pNext 指向一个 VkSubpassDescriptionDepthStencilResolve .这个结构定义了一个用于解析depth single-sampled attachment

// Good practice
// Multisampled attachment 是临时的
// 这使得tilers 完全避免将multisampled attachment 写出到内存。
// 带来了显著的性能和带宽改进
load_store[i_depth].store_op = VK_ATTACHMENT_STORE_OP_DONT_CARE;

// 启用 解析到 single-sampled attachment的write-back
subpass->set_depth_stencil_resolve_attachment(i_depth_resolve);
subpass->set_depth_stencil_resolve_mode(depth_resolve_mode);

通过设置 depthResolveMode ,也可以选择如何解析深度,​depthResolveMode​可选的选项在这里: supported (示例代码中查询了设备支持的模式并且提供了一个下拉菜单):

typedef enum VkResolveModeFlagBits {
    VK_RESOLVE_MODE_NONE,
    VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
    VK_RESOLVE_MODE_AVERAGE_BIT,
    VK_RESOLVE_MODE_MIN_BIT,
    VK_RESOLVE_MODE_MAX_BIT
} VkResolveModeFlagBits;

与颜色相比,Vulkan 不提供其他方式来解析深度附件( vkCmdResolveImage 不支持深度)。因此,如果 VK_KHR_depth_stencil_resolve  没有未支持或没有正确地配置,那么这个pipeline将需要额外的读取 multisampled depth attachment 来执行后处理效果。

 

 

 在这个最糟糕的情况下,即同时将multisampled depth 和multisampled color 写入主存储器,由于separate resolve需要重新读取颜色,读取带宽增加了2366 MiB/s(接近上面计算出的4X附件的带宽)。写入带宽增加了3951 MiB/s,这大致对应于4X附件(2247 MiB/s)和1X附件(562 MiB/s)之间的差异(在这种情况下,深度也是32bpp),即1685 MiB/s,再加上写出额外的4X颜色附件所需的带宽,即2247 MiB/s。总的来说,读写带宽的增加为6.3GB/s,相对于 write-back 解析的最佳实践增加了302%,并且消耗了630 mW的功耗(预算的25%),如果节省下来,可延长电池寿命,实现可持续性性能和更好的用户体验。

最佳实践小结

对于大多数 multisampling的使用场景,可以将所有额外的采样数据保存在GPU内部的 tile 内存中,并在write-back tile 时将其解析为单个像素颜色。这意味着这些额外增加的采样点,不会增加额外的带宽,不会访问外部存储器,这使得它非常高效。多重采样抗锯齿(MSAA)可以完全与Vulkan render passes集成,允许明确指定在subpass结束时做多重采样解析。

应该:

  • 尽量使用(4x MSAA);它不会过于昂贵,同时又很好的改善了图像质量。
  • 对于多重采样图像,使用 loadOp = LOAD_OP_CLEAR 或者 loadOp = LOAD_OP_DONT_CARE
  • 对于多重采样图像,使用 storeOp = STORE_OP_DONT_CARE 。
  • 使用 LAZILY_ALLOCATED 内存来配合分配的 multisampled images;它们不需要持久化到主内存,不需要保存在物理存储设备上。
  • 在 subpass 中使用  pResolveAttachments 自动将多重采样颜色缓冲区解析为单采样颜色缓冲区。
  • 在subpass 中使用 VK_KHR_depth_stencil_resolve 来自动将多重采样深度缓冲区解析为单采样深度缓冲区。通常,只有在深度缓冲区将进一步使用的情况下才有用,在大多数情况下,它是临时的,不需要解析。

应避免:

  • 避免使用vkCmdResolveImage()函数;这会对带宽和性能产生显著负面影响。
  • 避免对 multisampled image attachments 使用  loadOp = LOAD_OP_LOAD
  • 避免对 multisampled image attachments 使用 storeOp = STORE_OP_STORE 。
  • 避免在未经过性能检查的情况下使用超过4倍的 MSAA。

影响:

  • 未能进行内联解析可能导致内存带宽显著增加和性能降低;手动编写和解析一个4x MSAA的1080p表面,以60 FPS运行,需要3.9GB/s的内存带宽,而使用内联解析时只需要500MB/s。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/339608.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vivado 接口、端口映射

接口 重要&#xff01;接口只能在“fpga”类型的&#xff1c;component&#xff1e;中定义。接口部分提供了<component>上所有可用物理接口的列表。<interfaces>部分包含嵌套在其中的一个或多个<interface>标记。一个接口是通过使用<port_map>标记由多…

[pytorch入门] 3. torchvision中的transforms

torchvision中的transforms 是transforms.py工具箱&#xff0c;含有totensor、resize等工具 用于将特定格式的图片转换为想要的图片的结果&#xff0c;即用于图片变换 用法 在transforms中选择一个类创建对象&#xff0c;使用这个对象选择相应方法进行处理 能够选择的类 列…

股东出资透明度提升:企业股东出资信息API的应用

前言 在当今商业环境中&#xff0c;股东出资信息的透明度对于投资者、监管机构以及企业自身的健康发展至关重要。随着企业信息公开化的推进&#xff0c;企业股东出资信息API应运而生&#xff0c;为各方提供了一个便捷、高效的信息获取渠道。本文将探讨企业股东出资信息API如何…

【动态规划】【广度优先搜索】【状态压缩】847 访问所有节点的最短路径

作者推荐 视频算法专题 本文涉及知识点 动态规划汇总 广度优先搜索 状态压缩 LeetCode847 访问所有节点的最短路径 存在一个由 n 个节点组成的无向连通图&#xff0c;图中的节点按从 0 到 n - 1 编号。 给你一个数组 graph 表示这个图。其中&#xff0c;graph[i] 是一个列…

03.时间轮

时间轮 1.为什么需要时间轮 海量的定时任务下&#xff0c;小顶堆时间复杂度比较高&#xff0c;性能差 2.时间轮是什么 时间轮这个技术其实出来很久了&#xff0c;在kafka、zookeeper、Netty、Dubbo等高性能组件中都有时间轮使用的方式 时间轮&#xff0c;从图片上来看&…

自定义数据集 - Dataset

文章目录 1. PASCAL VOC格式 划分训练集和验证集2. 自定义dataset 1. PASCAL VOC格式 划分训练集和验证集 import os import randomdef main():random.seed(0) # 设置随机种子&#xff0c;保证随机结果可复现files_path "./VOCdevkit/VOC2012/Annotations" # 指定…

Sentinel限流规则支持流控效果

流控效果是指请求达到流控阈值时应该采取的措施&#xff0c;包括三种&#xff1a; 1.快速失败&#xff1a;达到阈值后&#xff0c;新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。 2.warm up&#xff1a;预热模式&#xff0c;对超出阈值的请求同样是拒绝并抛…

网络安全的信息收集方法有哪些?

网络安全攻击中的信息收集是攻击者为了了解目标系统的弱点、配置、环境和潜在的防御措施而进行的活动。以下是一些常见的信息收集手段&#xff1a; 开放网络资源查询&#xff1a; 使用搜索引擎查找关于目标组织的信息&#xff0c;包括新闻稿、社交媒体帖子、官方网站等。通过W…

答案之书程序

答案之书程序 需求&#xff1a;用户输入手机号码后4位或者生日&#xff0c;自动生成答案之书对应答案 效果图 C#代码实现过程 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq;…

新买电脑配置不低却卡顿?

目录 前言&#xff1a; 电脑卡顿的原因 Windows 10必做的系统优化 禁用 IP Helper 关闭系统通知 机械硬盘开启优化驱动器功能 开启存储感知 前言&#xff1a; 新买的电脑配置不低&#xff0c;但却卡顿甚至程序不反应&#xff0c;这是怎么回事儿&#xff1f; 其实并不…

获取主流电商平台商品价格,库存信息,数据分析,SKU详情

要接入API接口以采集电商平台上的商品数据&#xff0c;可以按照以下步骤进行&#xff1a; 1、找到可用的API接口&#xff1a;首先&#xff0c;需要找到支持查询商品信息的API接口。这些信息通常可以在电商平台的官方文档或开发者门户网站上找到。 2、注册并获取API密钥&#x…

【代码随想录算法训练营第二十四天|回溯算法的理论基础、77. 组合】

代码随想录算法训练营第二十四天|回溯算法的理论基础、77. 组合 回溯算法的理论基础77. 组合 回溯算法的理论基础 这里我觉得《代码随想录》和y总的课都比较好了 《代码随想录》 &#xff1a; https://programmercarl.com/0077.%E7%BB%84%E5%90%88%E4%BC%98%E5%8C%96.html#%E5…

成人高考和自考到底应该选哪个呢?

在成人学历提升的各项方式之中 成人高考与自学考试经常会被人拿来对比 但它们之间的差别在哪里 又分别去适合什么类型的考生 成考自考报名一般8月底开始&#xff0c;要准备考试的考生需要提前做好准备了哦 成考自考报名都需要上传证件照&#xff0c;而且都很严格 大家可使用小程…

react 页签(自行封装)

思路&#xff1a;封装一个页签组件&#xff0c;包裹页面组件&#xff0c;页面渲染之后把数据缓存到全局状态实现页面缓存。 浏览本博客之前先看一下我的博客实现的功能是否满足需求&#xff0c;实现功能&#xff1a; - 页面缓存 - 关闭当前页 - 鼠标右键>关闭当前 - 鼠标右…

启发式教学是什么

学生们在上课时看似认真听讲&#xff0c;但是在下课后却一片茫然&#xff0c;不知道你讲了什么内容&#xff1f;这是因为你可能使用了传统的教学方法&#xff0c;而不是启发式教学。 启发式教学是指老师在教育教学中&#xff0c;采用引导、启示、激发等手段&#xff0c;调动学…

主板电路学习; 华硕ASUS K43SD笔记本安装win7X64(ventoy)

记录 老爷机 白色 华硕 K43SD 笔记本 安装 win7X64 1. MBR样式常规安装win7X64Sp1 (华硕 K43SD 安装 win7X64 ) 老爷机 白色 华硕 K43SD 笔记本 安装 win7X64 &#xff08;常规安装&#xff09; 设置&#xff1a; 禁用UEFI 启用AHCI ventoy制作MBR&#xff08;非UEFI&#…

安全防御-基础认知

目录 安全风险能见度不足&#xff1a; 常见的网络安全术语 &#xff1a; 常见安全风险 网络的基本攻击模式&#xff1a; 病毒分类&#xff1a; 病毒的特征&#xff1a; 常见病毒&#xff1a; 信息安全的五要素&#xff1a; 信息安全的五要素案例 网络空间&#xff1a…

Anything本地知识库问答系统:基于检索增强生成式应用(RAG)两阶段检索、支持海量数据、跨语种问答

QAnything本地知识库问答系统&#xff1a;基于检索增强生成式应用&#xff08;RAG&#xff09;两阶段检索、支持海量数据、跨语种问答 QAnything (Question and Answer based on Anything) 是致力于支持任意格式文件或数据库的本地知识库问答系统&#xff0c;可断网安装使用。…

Vue diff原理

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…

DAY15--learning English

一、积累 1.loyalty Bro had loyalty on that. 老兄对那个东西情有独钟。 2. consent its illegal to film anyone without consent in many country 。 在一些国家里面&#xff0c;没有经过别人的同意就去拍摄别人是违法的。 3. butt 4.disciplinary Welcome to our discip…