GPU驱动的大规模静态物件渲染

news2024/11/17 11:35:41

        GPU Driven 的静态物件渲染,听起来很高级,其实具体操作很简单,基础就是直接调用 Graphics.DrawMeshInstancedIndirect 这个 Unity 内置接口就可以了。但我们项目对这个流程做了一些优化,使得支持的实体数量有大幅提升。

        这套系统主要也是公司的 TA 实现的,这里我也只简明扼要地介绍一下原理。

1、实现思路

        整个 GpuDriven 的实现简图如下图所示:

        CPU端收集好渲染所需要的数据之后,传给GPU进行剔除和整理,之后得到需要上屏的数据。之后通过异步回读,拿到各个类型是否需要渲染的结果,然后再调用 Graphics.DrawMeshInstancedIndirect 命令进行绘制。

        与传统流程相比,主要是增加了剔除和异步回读,使得 DrawCall 数量没有任何浪费,在保证渲染结果的同时,尽可能地减少了实际绘制的实体数量。

2、数据结构

        部分数据结构简单介绍如下:

2.1、实体数据:InstanceData

public struct InstanceData
{
    public int MeshType;//表示这个实体的类型
    public float3 Position;//世界坐标的位置
    public uint ScaleAndRoate;//缩放和旋转值,用位预算合并在一起(会降低精度)
    public float4 CustomData;//自定义数据,根据项目需求设置长度;
}

        这里为了性能考虑,对数据尽可能地做了压缩,例如旋转和缩放就整合成了一个unit,4个字节。自定义数据,可以理解为一些特殊 Shader 特殊效果用到的数据,例如描边颜色、顶点形变等。这个数据是最大的一块,不建议每帧都传给GPU,而是通过AOI来收集,在数据有变化的时候再传给 GPU 。

2.2、网格类型数据:MeshData

        网格类型记录每一个网格上屏需要的参数,包括网格、材质球等:

public class MeshData
{
    public int MeshType;//网格类型ID,需要顺序排列
    public Mesh mesh;//网格
    public Material material;//材质球
    //-----------------以下是一些自定义参数,可自行扩展------------------------
    public float2 lodDistance;//Lod参数
    public bool reciveShaodw;//阴影参数
}

        网格类型数据的改变频率就很低了,基本上可以全局共用一套(或者一个文明、国家用一套)。这里需要注意的是,数据存储时需要将 MeshData 存储为一个数组,且数组的 Index 和 MeshType 一一对应。

2.3、裁剪后的 Buffer 数据

        裁剪后的 Buffer 数据是写在 GPU 里的,除了标记哪些类型需要渲染外,其他数据都是不会异步回读到 CPU 的。这里的数据就随便写了,举个例子:

StructuredBuffer<InstanceData> _IndirectAllInstanceDatas;//所有Instance的几何信息以及自定义的数据
StructuredBuffer<uint> _IndirectInstanceTypeIndexStart;//下标为Meshid,val为起始下标
StructuredBuffer<uint> _IndirectInstanceTypeIndexCount;//下标为Meshid,val为渲染数量

        在回读 _IndirectInstanceTypeIndexCount 这个数据时,我们做了一个优化:由于CPU只需要知道每个类型是否需要渲染,所以是需要1位就能表示。我们将每8个类型合并成一个 int 返回,这样可以节省一点带宽。

3、关于裁剪

        裁剪我们用了视锥体剔除、遮挡剔除和 LOD 剔除,一般来讲这三个结合起来就基本可以剔除得很干净了。剔除顺序以及介绍如下:

  1. LOD 剔除:将距离相机距离大于 LOD 设置的直接剔除视为不渲染;
  2. 视锥体剔除:根据相机矩阵计算,剔除掉不在视野内的物体;
  3. 遮挡剔除:根据上一帧生成的深度图,对当前帧的实体进行遮挡剔除计算。
Game视图下与渲染并无异常
在Scene视图下查看的剔除效果,可以看到遮挡剔除和视锥体剔除都生效了

        在剔除的时候,用到了一些加速手段。例如使用 Cluster(或者叫Chunk)剔除加速优化:例如草,数量很多时,将其用莫顿码编每64个编成一个Chunk,然后整体做剔除。在视锥体剔除的时候,也可以先构建稀疏八叉树等等。(涉及的相关技术和参考文档我会放到最后)
        这一套整体下来,百万物体的剔除在编辑器上测试只有 0.163 ms (GTX 1050ti),非常高效。

        当然,我们实际实现的时候也遇到了不少问题,最常见就是单位闪烁的问题(主要原因是异步回读和深度图的数据并不是本帧的数据),后面也通过各种手段解决了。但这个技术路线本身原理是可行的。

参考文章

Graphics-DrawMeshInstancedIndirect - Unity 脚本 API

https://zhuanlan.zhihu.com/p/468542418

计算机图形学:使用体素锥体跟踪实现全局渲染_技术交流_牛客网

【Unity】相机视锥体剔除算法_unity视椎体剔除-CSDN博客

【Unity】LODGroup 计算公式_unity lod 计算viewdistance-CSDN博客

GPU Driven Occlusion Culling(Hiz)_hiz遮挡剔除-CSDN博客

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

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

相关文章

海南云亿商务咨询有限公司引领抖音电商新潮流

在当今这个数字化时代&#xff0c;电商行业如日中天&#xff0c;而抖音作为短视频与社交电商完美融合的典范&#xff0c;正以前所未有的速度改变着人们的购物习惯和消费模式。在这片充满机遇与挑战的蓝海中&#xff0c;海南云亿商务咨询有限公司凭借其敏锐的市场洞察力和专业的…

【算法/学习】:flood算法

✨ 君子坐而论道&#xff0c;少年起而行之 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;算法学习 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &…

鸿蒙交互事件开发01——点击/拖拽/触摸事件

如果你也对鸿蒙开发感兴趣&#xff0c;加入“Harmony自习室”吧&#xff01;扫描下方名片&#xff0c;关注公众号&#xff0c;公众号更新更快&#xff0c;同时也有更多学习资料和技术讨论群。 1 概 述 事件是人机交互的基础&#xff0c;鸿蒙开发中&#xff0c;事件分…

EmguCV学习笔记 VB.Net 2.1 颜色空间和颜色

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV学习笔记目录 Vb.net EmguCV学习笔记目录 C# 笔者的博客网址&#xff1a;VB.Net-CSDN博客 教程相关说明以及如何获得pdf教程…

威胁组织伪造Loom,Mac用户警惕AMOS窃取软件威胁

近期&#xff0c;一个复杂且可能与神秘威胁组织“Crazy Evil”有关联的网络犯罪活动&#xff0c;已将注意力转向了Mac用户群体。该组织利用广受欢迎的屏幕录制工具Loom作为掩护&#xff0c;悄无声息地传播着臭名远扬的AMOS数据窃取软件。Moonlock Lab的安全研究员们揭开了这一阴…

【数据结构与算法 | 图篇】拓扑排序

1. 概念 拓扑排序是是一种针对有向无环图进行的排序方法。它将图中所有顶点排成一个线性序列&#xff0c;使得对于图中的每一条有向边(u, v)&#xff0c;顶点u在序列中都出现在顶点v之前。 适用范围&#xff1a; 拓扑排序只适用于有向无环图。 结果非唯一&#xff1a; 对于…

阿里云ubuntu系统安装mysql8.0

一、安装mysql8.0 1.已安装其他版本的mysql&#xff0c;需要删除 若没有不需要此操作 1 #卸载MySQL5.7版本 2 apt remove -y mysql-client5.7* mysql-community-server5.7* 4 # 卸载5.7的仓库信息 5 dpkg-l | grep mysql | awk iprint $2} | xargs dpkg -P2.更新仓库 apt u…

FASTSPEECH 2论文阅读

FASTSPEECH 2: FAST AND HIGH-QUALITY END-TOEND TEXT TO SPEECH 现状 非自回归模型可以在质量相当的情况下显著快于先前的自回归模型合成模型。但FastSpeech模型训练依赖与自回归教师模型进行时长预测&#xff08;提供更多的信息作为输入&#xff09;和知识蒸馏&#xff08;…

【开端】Java中判断一个对象是否是空内容

一、绪论 在Java中&#xff0c;我们常常使用的到的就是封装&#xff0c;为什么要封装&#xff0c;封装有什么好处。首先在系统开发过程中&#xff0c;其实很多功能和场景都共性的。那么为了避免重复造轮子&#xff0c;我们这时就使用到了封装。封装可以一次造轮子&#xff0c;无…

数据集搜索

1. 数据集和数据集的分类 数据集是一组数据的集合&#xff0c;通常用于机器学习、统计分析、数据挖掘等领域&#xff0c;帮助算法训练、模型验证和评估。可以是各种形式的数据&#xff0c;如表格、图像、机器学习相关的文件等。 根据在机器学习中的应用&#xff0c;数据集可以…

1. MongoDB概念解析

1. 概念解析 在 MongoDB 中基本的概念是文档、集合、数据库。 SQL 术语/概念MongoDB 术语/概念解释/说明databasedatabase数据库tablecollection数据库表/集合rowdocument数据记录行/文档columnfield数据字段/域indexindex索引table joins表连接,MongoDB不支持primary keypri…

1.3 数据库的发展历史与演变

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

鸿萌数据恢复服务: 如何修复 SQL Server 数据库错误 829?

天津鸿萌科贸发展有限公司从事数据安全服务二十余年&#xff0c;致力于为各领域客户提供专业的数据恢复、数据备份、网络及终端数据安全等解决方案与服务。 同时&#xff0c;鸿萌是众多国际主流数据恢复软件(Stellar、UFS、R-Studio、ReclaiMe Pro 等)的授权代理商&#xff0c…

pandas 笔记crosstab

用来计算两个&#xff08;或更多&#xff09;因子的交叉表&#xff08;即频率表、列联表或透视表&#xff09;。这个功能特别适用于统计分析和数据探索阶段&#xff0c;帮助理解不同变量之间的关系 1 基本用法 pd.crosstab(index, columns, valuesNone, rownamesNone, colnam…

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(二)---ROS2与UE5进行图像数据传输

前言 本系列教程旨在使用UE5配置一个具备激光雷达深度摄像机的仿真小车&#xff0c;并使用通过跨平台的方式进行ROS2和UE5仿真的通讯&#xff0c;达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础&#xff0c;Nav2相关的学习教程可以参考本人的其他博…

HarmonyOS-MPChart以X轴或y轴为区间设置不同颜色

本文是基于鸿蒙三方库mpchart OpenHarmony-SIG/ohos-MPChart 的使用&#xff0c;以X轴为区间设置不同的曲线颜色。 mpchart本身的绘制功能是不支持不同区间颜色不同的曲线的&#xff0c;那么当我们的需求曲线根据x轴的刻度区间绘制不同颜色&#xff0c;就需要自定义绘制方法了。…

LVS (Linux virual server)

LVS简介 LVS&#xff08;Linux Virtual Server&#xff09;是一个基于Linux平台的开源负载均衡系统。它通过将多个服务器组成一个虚拟服务器集群&#xff0c;实现了高效的负载均衡和流量分发。 LVS的核心思想是利用IP负载均衡技术和内容请求分发机制&a…

传知代码-【CLIP】文本也能和图像配对

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 模态&#xff1a;数据的一种形式&#xff0c;如图像、文本、声音、点云等。 多模态学习&#xff0c;就是利用模型同时处理多个模态数据&#xff0c;有助于提高模型的准确性和泛化能力。在自动驾驶场景中&am…

利用住宅代理应对机器人流量挑战:识别、使用与检验指南

引言 什么是机器人流量&#xff1f;其工作原理是什么&#xff1f; 机器人流量来自哪里&#xff1f; 合法使用机器人时如何避免被拦截&#xff1f; 如何检验恶意机器人流量&#xff1f; 总结 引言 你是否曾经遇到过访问某个网站时&#xff0c;被要求输入验证码或完成一些其…

源代码加密的意义和办法?

一、源代码加密的意义1、防止恶意修改&#xff1a;未加密的源代码容易被恶意用户或竞争对手获取并修改&#xff0c;以植入恶意代码或病毒&#xff0c;损害软件的功能性和安全性。加密后的源代码即使被非法获取&#xff0c;也无法修改或理解&#xff0c;从而防止了被破坏的风险。…