深入理解Mesh Shader优化原理

news2025/2/7 3:45:07

参照AMD官网文章和GDC中其分享内容https://gpuopen.com/learn/mesh_shaders/mesh_shaders-index/总结自用,大佬直接原文。

一、传统顶点着色器管线与Mesh 着色器对比

具体之前也研究过可参照:DX12_Mesh Shaders Render
这里主要针对之前忽略的一些知识点进行补充。

1.1 顶点着色器的弊端

我们先深入了解一下GPU 是如何使用顶点缓冲区和索引缓冲区来处理传统的绘制调用的(可参照:GPU架构与管线总结)。在传统的图形管线中,网格通常被定义为一组顶点,连续的三个顶点构成一个三角形。为了减少数据冗余,可以通过索引缓冲区将三角形定义为一组三个索引,每个索引引用一个不同的顶点。如下图所示:
在这里插入图片描述

常规流程如下:
在这里插入图片描述

对于索引缓冲区引用的每个顶点,GPU都需要运行一个vertex shader实例,将顶点从顶点缓冲区中的输入布局转换为裁剪空间(clip-space)中的位置。由于输入网格使用的是索引缓冲区,因此重复使用顶点的好处同样适用于此——减少不必要的顶点着色计算,从而降低图形处理成本。Input Assembler负责解析索引缓冲区并启动后续的顶点处理。

在Input Assembler中实现顶点重用的一种显而易见的方法是对顶点缓冲区中的每个顶点运行vertex shader,并存储转换后的顶点。然而这种方法具体实施起来却并不可行,因为存储数百万个转换后的顶点可能会超出GPU的内存。另外,这样的实现会延迟图元组装,导致着色必须要等到所有vertex shader实例执行完成之后才开始。

以要绘制上述四个三角形为例,我们需要向图形命令列表提交以下绘制调用:

graphicsCommandList->DrawIndexedInstanced(12 /* index count */,
1 /* instance count */,
0 /* start index location */,
0 /* base vertex location */,
0 /* base instance location */).

一旦提交了命令缓冲区,API 运行时和 GPU 驱动程序处理了绘制调用,就会向 GPU 发送绘制命令。该命令由以下各部分接收和处理:
在这里插入图片描述

  • Command Processor 从 GPU 驱动程序接收绘制、调度或其他命令,并根据当前命令设置其他组件,如Geometry
    Engine。
  • Geometry Engine 负责从索引缓冲区加载索引、设置并启动vertex shader实例。
  • Dual Compute Unit 执行vertex shader以及其他shader。Geometry Engine会指示计算单元每个线程处理哪个顶点。计算单元从一个或多个顶点缓冲区获取顶点信息,并将转换后的顶点信息存储到shader export中。
  • Shader Export 是一个内存块,用于接收和存储计算单元的顶点和图元信息。
  • Primitive Assembler 从shader export读取图元连接信息和转换后的顶点位置,将它们组装成独立的三角形,然后输出到rasterizer。
  • Rasterizer 接收组装好的三角形,并确定每个三角形需要进行着色的片段。

为了确定哪些顶点需要由vertex shader处理,geometry engine会从索引缓冲区中选择一个图元子集(primitive subset)。从概念上讲,一个图元子组(即重新索引的顶点索引和唯一顶点)会形成一个小网格,或者成为meshlet,具有自己的一组顶点和索引。由于这些索引并不直接引用原始输入顶点缓冲区中的顶点,而是引用唯一顶点列表中的顶点索引,因此我们将这些索引称为图元连接(primitive connectivity)。
在这里插入图片描述
在一个图元组中的顶点将一起进行处理,一旦顶点处理完成,图元连接将被用于把它们组装成三角形,以便进行光栅化处理。一个图元组形成并送去处理后,geometry engine会对索引缓冲区中的下一个图元子集重复相同的处理步骤,直到所有图元都渲染完毕。

为了最大限度地提高顶点重用率,理想情况下我们希望所有引用同一顶点的图元都在同一个图元子组中。换句话说,我们希望每个顶点只存在于一个图元子组中。否则 GPU 将为同一个顶点多次调用vertex shader,造成多余计算,影响整体的性能。由于图元子组受顶点最大数量或图元最大数量的限制,理想的顶点重用,即每个顶点只被处理一次,在一般情况下是不可能的。

其实狭长三角形光栅化性能消耗更大,底层原因也是如此。一个简单的demo示意可以上述所有啰嗦(顶点缓存优化)。
在这里插入图片描述

总结: 顶点管线无法直接控制vertex shader的调用和顶点的重用,所以说管线驱动层一定就存在一定的性能浪费。

1.2 Mesh Shader优势

Mesh shaders引入了一种新的、类似compute shaders的几何管线,让开发者能够直接将顶点和图元信息批量发送到rasterizer。这些集合通常被称为meshlet,由少量顶点和引用这些顶点的三角形列表组成。其可以用来表示较大网格的一小部分,但这些meshlet可以完全由用户定义,因此也可以用来渲染程序化几何图形(如地形)或细分曲面等网格几何图形。下边我们重点介绍如何使用mesh shader渲染三角形网格。

Mesh shader引入了两个新的 API shader阶段:

  • Task Shader(VK)/Amplification Shader(DX),决定要发起哪些以及多少个mesh shader线程组。
  • Mesh Shader 将上述顶点和图元输出到rasterizer。

这两个新的shader阶段取代了传统的几何管线,包括vertex shader、hull shader、domain shader和geometry shader,并且不能与这些阶段中的任何一个结合使用。

在这里插入图片描述
Mesh shader和amplification shader都采用了和compute shader类似的编程模型,因此更符合现代显卡架构的统一计算硬件发展趋势。在传统的图形渲染模型中,每个线程负责一个顶点、采样或图元,线程之间并不可见或通信。而mesh shaders以线程组的形式组织,每个线程组不再限定于特定的顶点或图元,可以指定并写入可变数量的顶点和图元。任何线程都可以处理任何顶点或图元。

由于mesh shader采用了类似compute shader的线程组组织方式,因此启动mesh shader的方式也与传统的绘制调用有所不同。使用 DispatchMesh 命令(在 Vulkan 中为 vkCmdDrawMeshTasksEXT)时,不再需要指定要处理的顶点或索引的数量。相反,该命令需要指定在compute shader所在的三维网格中启动的mesh shader线程组的数量:

graphicsCommandList->DispatchMesh(threadGroupCountX, threadGroupCountY, threadGroupCountZ);

这种直接启动线程组的方式也意味着mesh shader跳过了Input Assembler阶段。开发者因此可以自定义从mesh shader导出哪些图元,输入数据的各种限制也消失了。就像compute shader一样,mesh shader可以读取甚至写入任何资源。另外,开发者还可以直接控制哪些图元进行光栅化,对单个图元进行剔除,或者和amplification shader配合使用,剔除整个meshlet。

Mesh shader绕过了传统的input assembler阶段,就需要将顶点重用计算移到预处理阶段。这就可以避免在每一帧或每个绘制调用中重复计算顶点重用信息,实现信息在多个绘制调用和帧之间共享。移除了input assembler也意味着它不会成为渲染管线的瓶颈。mesh shader也可以直接适应不同GPU配置。此外,放弃了传统的几何生成编程模型,如tessellation shader和geometry shader,意味着mesh shader中的几何生成可以更好地映射到计算硬件,并减少对固定功能硬件的依赖。

最后,mesh shader中线程组的组织方式允许线程通过wave intrinsics和组共享内存通信,共同计算一个或多个顶点或图元。

总之,mesh shader类似compute shader的编程模型让开发者能够克服传统顶点管线的关键瓶颈,同时还能更灵活地使用高级渲染技术,例如三角形剔除或实时几何解压缩。

Amplification shaders

Amplification Shader是可选的一个shader阶段,在mesh shader之前运行,可以控制mesh shader线程组的后续启动。每个amplification shader线程组可以启动不同数量的mesh shader线程组,从而增加在GPU上执行的工作负载。不过,这种放大与使用tessellation shader实现的放大不同。Amplification shader不是通过固定功能硬件来生成control patch内的图元数量,而是只指定要启动的mesh shader线程组的数量。不过,使用amplification shaders可以模仿固定函数tessellation shader生成的效果

为了启动mesh shader,amplification shader可以调用 DispatchMesh shader 内置函数,并指定要启动的三维网格的mesh shader线程组。这个内置函数的行为与 CPU 上的 DispatchMesh 命令相同。 CPU 可以在 DispatchMesh 调用之间对shader的根签名进行写入或修改,但amplification shader则不能。相反,amplification shaders可以通过传递用户定义的payload,将信息从amplification shader传递给所有随后启动的mesh shader

DispatchMesh(threadGroupCountX,
threadGroupCountY,
threadGroupCountZ,
payload);

从 CPU 启动amplification shader的方式与启动mesh shader的方式相同:如果图形管线状态指定了amplification shader,则 DispatchMesh 命令中指定的三维网格会直接指向要启动的amplification shader网格。需要注意的是,选择要启动的是mesh shader还是amplification shader需要通过设置不同的图形管线状态来实现。

在这里插入图片描述

但amplification shader还存在着一些关键的差异和限制:

  • Mesh shader图形管线只包含一个amplification shader,更重要的是只包含一个mesh shader,这意味着amplification shader直接与mesh shader绑定。amplification shader只能控制启动多少个mesh shader线程组,并不能控制使用哪个mesh shader或pixel shader。
  • Amplification shader只能调用mesh shader,不能调用其他amplification shader或自身。这意味着amplification shader仅提供一层work amplification。
  • Amplification shader内的 DispatchMesh 内置函数仅接受单一payload,供所有随后启动的mesh shader线程组使用。同样,amplification shader线程组只能调用一次 DispatchMesh。

尽管有这些局限,amplification shader也能扩展mesh shader管线的灵活性,完全在 GPU 上实现动态work amplification或work reduction。Amplification shader的应用实例包括:

  • Meshlet或实例剔除: amplification shader可用于每个meshlet或实例的剔除。每个线程都负责测试特定meshlet或实例的可见性,通常通过检查其bounding box(包围盒)是否在摄像机的视锥体内。
  • 动态LOD: 与上述实例剔除示例类似,每个网格实例都会启动一个amplification shader线程。然后,每个线程会确定其实例与摄像机的距离,并选择相应的LOD进行渲染。
  • 生成程序式几何图形: Amplification shader通过动态地将工作负载分配给多个mesh shader线程组,可以扩展mesh shader的输出能力,用于处理例如程序生成的几何图形或细分曲面。

有一点需要注意:在实例剔除和动态 LOD 的情况下,amplification shader线程组中的每个线程希望启动的mesh shader线程组数量在整个线程组中会有所不同。这可能会使将mesh shader线程组分配给payload中特定元素的过程更加复杂。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[BT]BUUCTF刷题第17天(4.15)

第17天(共3题) Web [强网杯 2019]高明的黑客 .tar.gz 是 Linux 系统下的压缩包,访问即可下载 打开后有3000多个php文件,通过题解得知需要写Python脚本找出合适的GetShell文件(因为每个文件里都会通过system函数执行…

贵阳市人民政府副市长刘岚调研珈和科技

4月9日,贵阳市人民政府副市长、党组成员刘岚一行到珈和科技走访调研,珈和科技总经理冷伟热情接待了考察团,就企业算力需求与合作,特色产业园区建设,科技成果转化落地等方面进行深入交流。 贵阳市教育局局长李波&#…

Vmware 虚拟机自定义IP地址 - UbuntuServer2204

Vmware 虚拟机自定义IP地址 - UbuntuServer2204 设置网段 选择喜欢的网段, 例如: 166 自定义 IP地址 打开虚拟机, 输入命令查看网卡名 ip addr查看网卡配置文件 ls -al /etc/netplan/编辑网卡配置文件 sudo vim /etc/netplan/00-installe…

稀疏数组思想

稀疏数组的处理方法是: 1)记录数组一共有几行几列,有多少个不同的值 2)思想:把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模 例如下面原数组对应稀疏数组:

Git-常规用法-含解决分支版本冲突解决方法

目录 前置条件 已经创建了Gitee账号 创建一个远程仓库 Git的优点 版本控制 Git 下载 Git的使用 检查Git的是否安装成功 git的常用命令 常用流程 Git 分支 分支流程 Git 远程仓库 远程仓库流程 特殊 可能遇到的问题 前置条件 已经创建了Gitee账号 创建一个远程仓…

CTK插件框架学习-事件监听(07)

CTK插件框架学习-服务工厂(06)https://mp.csdn.net/mp_blog/creation/editor/137295686 一、简介 事件监听指当事件发生变化时所产生的通信,是动态的,对于已经发生过的事件无法监听 二、事件类型 1、框架事件 监听框架状态变化,因为监听…

【ARFoundation自学01】搭建AR框架,检测平面点击位置克隆物体

Unity开发ARFoundation相关应用首先安装ARFoundation包 然后设置XR 1.基础AR场景框架搭建 2.一个基本的点击克隆物体到识别的平面脚本 挂在XROrigin上 脚本AppController 脚本说明书 ## 业务逻辑 AppController 脚本旨在实现一个基本的 AR 应用程序功能:用户通过…

【24年物联网华为杯】赛题分析与初步计划

赛事介绍 官网链接:2024 年全国大学生物联网设计竞赛 (sjtu.edu.cn) 含金量:属于A类赛事 (注意:很多搜索结果的序号是按照选入时间排列的,与含金量无关,华为杯是23年选入的) Kimi Chat: 全国…

攻防世界09cookie

9-cookie Cookie是保存在客户端的纯文本文件。比如txt文件。所谓的客户端就是我们自己的本地电脑。当我们使用自己的电脑通过浏览器进行访问网页的时候,服务器就会生成一个证书并返回给我的浏览器并写入我们的本地电脑。这个证书就是cookie。一般来说cookie都是服务…

数字孪生技术在设备故障检测中的应用

数字孪生技术在设备故障检测中的应用主要体现在以下几个方面,数字孪生技术在设备故障检测中的应用展现了其在智能制造和工业互联网领域的重要价值,通过实时监测、故障预测、诊断分析和预测性维护等手段,显著提升了设备管理的智能化水平。北京…

CAN终端电阻

目录 概述终端电阻的作用提高抗干扰能力确保快速进入隐性状态提高信号质量 为什么选120Ω 概述 CAN总线终端电阻,顾名思义就是加在总线末端的电阻。此电阻虽小,但在CAN总线通信中却有十分重要的作用。 终端电阻的作用 CAN总线终端电阻的作用有两个&…

轻松上手MYSQL:MYSQL初识(下)

​🌈 个人主页:danci_ 🔥 系列专栏:《MYSQL入门》 💪🏻 制定明确可量化的目标,坚持默默的做事。 轻松上手MYSQL:从零开始构建你的数据库世界 🚀 🚀欢迎来到My…

office竟然可以直接PDF转Word?这个“锅”请wps来背!

WPS和Office都是非常出色的办公软件,它们都能够满足我们日常办公的需求。然而,作为一款国产办公软件,WPS在功能集成和操作上更加符合中国人的使用习惯,因此很多人选择使用WPS作为他们的办公软件,包括我自己。 然而&…

初识微服务:重塑软件开发的未来

引言 随着信息技术的飞速发展,软件系统的复杂性和规模不断攀升,传统的单体应用架构已经难以满足现代业务的灵活性和可扩展性需求。在这样的背景下,微服务架构应运而生,成为当前软件开发领域的一大热门话题。本文将深入探讨微服务架…

LeetCode 73.矩阵置零————2024 春招冲刺百题计划

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]] 示例 2: 输入:matrix […

解决EasyPoi导入Excel获取不到第一列的问题

文章目录 1. 复现错误2. 分析错误2.1 导入的代码2.2 DictExcel实体类2.2 表头和标题 3. 解决问题 1. 复现错误 使用EasyPoi导入数据时,Excel表格如下图: 但在导入时,出现如下错误: name为英文名称,在第一列&#xff0c…

0-1 设计高质量数据可视化大屏

5 大指南塑造高阶可视化 可视化是个友好的媒介 理解数据是成为优秀媒介的关键 业务驱动下的设计策略 图扑设计的无限可能 创新思维让可视化更具价值 可视化是个友好的媒介 我们正处于一个数据泛滥的时代,随处可见数据的身影,更知其不可忽视的重要…

金三银四面试题(二十):单例模式知多少?

设计模式也是面试中的热门考题,基本这个部分都是问问你知不知道XXX设计模式,有什么用,优缺点,然后再现场手写一个demo。很多时候是和spring一起考的,问问你知不知道spring框架用了哪些设计模式。今天我们来先看看单例模…

免费SSL证书安全吗?和付费的有什么区别?

SSL(安全套接层)证书是一种数字证书,用于在Web服务器和浏览器之间建立加密链接,以保护在线交易的安全。这种技术可以防止数据被窃取或篡改,从而保护用户的隐私和安全。 免费SSL证书与付费SSL证书在安全性方面存在一定…

java的Spring XML和注解解析深入理解

正文 熟悉IOC体系结构 要学习Spring源码,我们首先得要找准入口,那这个入口怎么找呢?我们不妨先思考一下,在Spring项目启动时,Spring做了哪些事情。这里我以最原始的xml配置方式来分析,那么在项目启动时&a…