利用Vulkan与OpenGL的CAD模型网格着色器样本
项目简介
该项目是一个展示如何使用网格着色器渲染大量三角形模型的示例。特别针对CAD模型,它们通常拥有高密度的三角面,因此处理(顶点着色、原始剔除等)大量的几何体可能成为挑战。通过Turing架构,引入了新的着色阶段,从而实现基于网格着色的新几何管线。
如图所示的新管线在这篇博客文章中有更详细的解释,建议先阅读该材料。
项目支持构建两个可执行文件:
- 使用经典OpenGL窗口创建的
gl_meshlet_cadscene
- 使用WSI和Vulkan的
vk_meshlet_cadscene
其中,Vulkan应用支持VK_NV_mesh_shader
和跨供应商的VK_EXT_mesh_shader
扩展,而OpenGL应用仅支持GL_NV_mesh_shader
。对于VK_EXT_mesh_shader
支持,请确保随附的shaderc_shared.lib
(属于Vulkan SDK)实际支持该扩展。在发布此更新样例时,SDK可能尚未提供此支持,您可能需要自己编译库或等待一段时间。
样例概述
样例提供了两个数据集:
- PTC提供的世界汽车CAD模型。
- 由乔治亚理工学院提供的涡轮叶片3D扫描模型。
通过命令行参数加载其中一个模型配置文件,即可选择显示场景。每个配置都会实例化模型几次,以生成有意义的基准测试工作负载。
UI允许您在经典的和网格着色管线之间切换,并有各种可调整选项来观察不同配置对性能的影响。可以通过按V
键启用或禁用垂直同步(vsync
),按R
键重新加载着色器(前提是着色器无错误)。
请注意,性能可能会因硬件差异而有所不同,详情见性能部分。
主要设置
- 演示场景:如果没有通过命令行指定自定义模型,可以在此切换两种预设场景。
- 渲染器:在标准和网格着色器渲染器间切换,更多详情见下文。
- 视点:在一些预置摄像机视角间切换。
- 视场角(FOV):相机视野角度。
网格着色器设置
建议使用数值输入,因为每次更改都会导致模型重新加载,也可以通过命令行传递许多设置。
-
网格let顶点数:每个网格let的最大唯一顶点数。
-
网格let多边形数:每个网格let的最大三角形数。
-
任务网格let计数:一个任务着色器工作组同时操作这么多网格let。
-
任务最小网格lets:如果绘制调用中的网格let数量大于或等于此值,或者如果设置为零,则使用只有网格阶段的渲染器。
-
任务像素剔除:影响任务着色器中子像素集群剔除的强度。1表示使用全分辨率,0.5可能剔除实际上可见但往往不明显的簇。
-
按网格let颜色化:只在网格渲染器中,通过碎片着色器可视化三角形簇。
-
启用按多边形剔除:在网格着色器中启用按多边形剔除(不基于用户剪裁平面进行剔除),否则使用
drawmeshlet_*_basic.mesh.glsl
。 -
也启用按顶点剔除:如果启用了按多边形剔除,也在
drawmeshlet_*_cull.mesh.glsl
中启用按顶点剔除。 -
启用片段巴塞尔坐标:启用硬件片段着色器中的巴塞尔坐标,这可以显著减少网格着色器传递给片段着色器的输出量并提高性能。我们只需要传递顶点索引,然后...
EXT 网格着色器偏好
如果支持VK_EXT_mesh_shader
,将显示此菜单,允许您影响EXT任务和网格着色器。网格着色器对实现特定行为非常敏感,这些偏好有助于获得更好的性能。除了工作组大小外,这些偏好主要影响按多边形剔除的复杂情况。请注意,VkPhysicalDeviceMeshShaderPropertiesEXT
中返回的值可能会随着新驱动版本的变化,即使在同一硬件上也是如此。
- 重置到默认实现:名称表明,以下值将重置为从设备查询的值。
- 紧凑顶点输出:本地网格let中的顶点紧密包装,只有经过剔除(如果有)的才会使用
[0 ... vertexCount-1]
入口。 - 紧凑多边形输出:本地网格let中的多边形紧密包装,只有经过剔除(如果有)的才会使用
[0 ... primitiveCount-1]
入口。 - 本地线程顶点输出:每个线程使用其
gl_LocalInvocationIndex
作为写入输出顶点数组的索引。 - 网格工作组大小:网格着色器工作组中的线程数。
- 任务工作组大小:任务着色器工作组中的线程数。
渲染设置
-
显示原始ID:以颜色显示三角形ID,用于评估“可见性缓冲区”填充性能。
-
显示网格let边界框:绘制网格let的边界框,用于任务着色器剔除。
-
显示网格let法线:绘制网格let的锥形法线,用于任务着色器剔除。
-
仅显示剔除的边界框/法线:仅绘制被任务着色器剔除的辅助图形。
-
启用背面剔除:影响固定功能以及任务或网格阶段中进行的剔除。
-
启用裁剪平面:启用三个裁剪平面,这意味着我们将增加顶点输出的数量。
-
裁剪位置:沿三个主轴的裁剪平面相对坐标。
模型设置
- 额外的v4属性:着色在这个示例中相对简单,无论是顶点属性还是传递到片段着色器的内容。这个值可以添加属性,模仿纹理坐标、切线等的顶点成本。设置为零意味着只有一个vec4加载,它包含顶点法线。
- 使用fp16属性:将顶点位置和属性编码为16位浮点数(半精度)。
- 模型副本:复制模型多次(共享几何内存)。
杂项设置
- 超分辨率:模拟更大的窗口分辨率或降采样,通过此因子增加实际渲染分辨率。此值的下采样质量较差,所以超过4x不会看起来更好。此值可用于调查亚像素剔除。
统计信息
- GPU渲染时间:渲染步骤所需的时间(不包括UI、blitting等)。
- 原始索引大小:原始索引缓冲区数据的大小。
- 网格let大小:所有网格let数据的大小,取代索引缓冲区。
- 详细统计:列出网格着色产生的各种统计数据。可能会消耗一些渲染性能。(激活时调整ui窗口大小或向下滚动)
- 任务总数量:任务着色器工作组的数量(每个处理最多32个网格let)。
- 网格总量:场景中的总网格let数。
- 网格输出量:由网格着色器处理的网格let数量(第二个值是百分比)。
- 多边形总量:场景中的总多边形数。
- 多边形输出量:网格着色器输出的多边形数(第二个值是百分比)。
- 顶点输入:网格着色器读取的位置顶点数。
- 属性读取:网格着色器读取的属性顶点数(第二个值是百分比)。如果启用了按多边形剔除并且“按顶点剔除”已启用,则此值可能较低,因为此时网格着色器将在加载被剔除的属性时跳过。
网格let构造
在样本中,我们提供了一个基础的实现,即nvmeshlet_packbasic.hpp
,在CPU上扫描索引缓冲区并创建网格let。这些网格let数据由drawmeshlet.*.glsl
着色器用来在适当的渲染器中绘制模型。
下面的图表说明了代替原始三角形索引缓冲区的主要数据结构。在使用网格着色器渲染时,我们使用这三个缓冲区,而不是经典的索引缓冲区。
在示例中,你会找到一个网格let构建器,它扫描索引缓冲区并创建网格let。每个网格let都有一个头部,然后将原始和顶点索引交错存储在一个单一的缓冲区范围内,而不是两个单独的原始和顶点索引缓冲区。这种交错使得头部可以仅存储这两个的单一起始值,而不是两个独立的值,从而节省了一些位。
整体来说,这个开源项目提供了一种创新的方法,利用Vulkan和OpenGL的最新特性来优化大规模3D模型的渲染,无论是在CAD场景还是其他高密度几何体应用中,都能展现出卓越的性能和灵活性。借助它的强大工具和可调整选项,开发者可以深入探究现代GPU的潜力,优化自己的图形应用程序。
- CangjieCommunity为仓颉编程语言开发者打造活跃、开放、高质量的社区环境Markdown00
- redis-sdk仓颉语言实现的Redis客户端SDK。已适配仓颉0.53.4 Beta版本。接口设计兼容jedis接口语义,支持RESP2和RESP3协议,支持发布订阅模式,支持哨兵模式和集群模式。Cangjie032
- 每日精选项目🔥🔥 推荐每日行业内最新、增长最快的项目,快速了解行业最新热门项目动态~ 🔥🔥02
- qwerty-learner为键盘工作者设计的单词记忆与英语肌肉记忆锻炼软件 / Words learning and English muscle memory training software designed for keyboard workersTSX022
- Yi-CoderYi Coder 编程模型,小而强大的编程助手HTML07
- advanced-javaAdvanced-Java是一个Java进阶教程,适合用于学习Java高级特性和编程技巧。特点:内容深入、实例丰富、适合进阶学习。JavaScript085
- taro开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。 https://taro.zone/TypeScript09
- CommunityCangjie-TPC(Third Party Components)仓颉编程语言三方库社区资源汇总05
- Bbrew🍺 The missing package manager for macOS (or Linux)Ruby01
- byzer-langByzer(以前的 MLSQL):一种用于数据管道、分析和人工智能的低代码开源编程语言。Scala04