Unity技术学习:RenderMesh、RenderMeshInstanced

叠甲:本人比较菜,如果哪里不对或者有认知不到的地方,欢迎锐评(不玻璃心)!

导师留了个任务,渲染大量的、移动的物体。

当时找了几个解决方案:

静态批处理:

这东西只对静态物体管用,哪怕勾上,上万个物体就寄了(虽然灵活度很高),只需要勾上就可以了。

Shader上的GPUInstance:

灵活度也挺高的,但是对于超过上限(貌似是1023?)的物体数量,依旧拉胯,batch数虽然不是猛增但是帧率很拉(后续可能会做性能分析)

RenderMeshIndirect(手动GPUInstance?):

跑了一下示例,woc,吊的一批,就是每个块可控性比较差(也可能是我比较菜,目前已知的就是使用,动画贴图,作为参数传入,才能单独控制某个块的动画,而且没有碰撞、无法单独操控等等),但是,一次性绘制10w,600帧没有一点儿压力。1000w个能跑十几帧(视觉效果拉满)。

所以接下来我从 RenderMesh到RenderMeshInstanced再到RenderMeshIndirect的API给说一下,并且跑一下示例:

 RenderMesh:

使用给定的渲染参数渲染网格。

public static void RenderMesh(ref RenderParams rparams, Mesh mesh, int submeshIndex, Matrix4x4 objectToWorld, Nullable<Matrix4x4> prevObjectToWorld = null);

rparams:

camera用于渲染的相机。如果设置为 null(默认),则为所有摄像机渲染。
layer用于渲染的图层。要使用的图层。
lightProbeProxyVolume用于渲染的光探针代理体积 (LPPV)。
lightProbeUsage光探头使用的类型。
material用于渲染的材质。
matProps用于渲染的材质属性。
motionVectorMode用于渲染的运动矢量模式。
receiveShadows描述渲染的几何体是否应接收阴影。
reflectionProbeUsage用于渲染的反射探针的类型。
rendererPriority渲染器优先级。
renderingLayerMask用于渲染的渲染器图层蒙版。
shadowCastingMode描述几何体是否应投射阴影。
worldBounds定义几何体的世界空间边界。用于对渲染的几何体进行剔除和排序。

MaterialPropertyBlock-CSDN博客

submeshIndex:

当网格体包含多个材质(子网格)时,子网格体 Unity 的索引会呈现。对于具有单个材质的网格,请使用值 0(这个是啥子,冲浪了好久,但是找不到)

objectToWorld:

Unity 用于将网格从对象转换为世界空间的转换矩阵。

prevObjectToWorld:

Unity 使用前面的帧变换矩阵来计算网格的运动矢量。

using UnityEngine;public class ExampleClass : MonoBehaviour
{public Material material;public Mesh mesh;void Update(){RenderParams rp = new RenderParams(material);rp.camera = Camera.main;rp.layer = 6;rp.matProps = new MaterialPropertyBlock();rp.worldBounds = new Bounds(new Vector3(0,0,0),new Vector3(1,1,1));for (int i = 0; i < 10; ++i)Graphics.RenderMesh(rp, mesh, 0, Matrix4x4.Translate(new Vector3(-6.5f + i, 0.0f, 5.0f)));}
}

RenderMeshInstanced:

使用 GPU 实例渲染网格的多个实例。

public static void RenderMeshInstanced(RenderParams rparams, Mesh mesh, int submeshIndex, NativeArray<T> instanceData, int instanceCount = -1, int startInstance = 0);

instanceData:

用于呈现实例的实例数据数组。

instanceCount:

要呈现的实例数。当此参数为 -1(默认值)时,Unity 会呈现从数组到末尾的所有实例。

startInstance:

要呈现的第一个实例。

using UnityEngine;public class ExampleClass : MonoBehaviour
{public Material material;public Mesh mesh;const int numInstances = 1000;struct MyInstanceData{public Matrix4x4 objectToWorld;public float myOtherData;public uint renderingLayerMask;};void Update(){RenderParams rp = new RenderParams(material);MyInstanceData[] instData = new MyInstanceData[numInstances];for (int i = 0; i < numInstances; ++i){instData[i].objectToWorld = Matrix4x4.Translate(new Vector3(-4.5f + i*3, 0.0f, 5.0f));instData[i].renderingLayerMask = (i & 1) == 0 ? 1u : 2u;}Graphics.RenderMeshInstanced(rp, mesh, 0, instData);}
}

RenderMeshIndirect:

public static void RenderMeshIndirect(ref RenderParams rparams, Mesh mesh, GraphicsBuffer commandBuffer, int commandCount = 1, int startCommand = 0); 

commandBuffer:

 把命令打包的buffer

using UnityEngine;public class ExampleClass : MonoBehaviour
{public Material material;public Mesh mesh;GraphicsBuffer commandBuf;GraphicsBuffer.IndirectDrawIndexedArgs[] commandData;const int commandCount = 1;public uint   num=100;void Start(){commandBuf = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, commandCount, GraphicsBuffer.IndirectDrawIndexedArgs.size);commandData = new GraphicsBuffer.IndirectDrawIndexedArgs[commandCount];}void OnDestroy(){commandBuf?.Release();commandBuf = null;}void Update(){RenderParams rp = new RenderParams(material);rp.worldBounds = new Bounds(Vector3.zero, 10000 * Vector3.one); // use tighter bounds for better FOV cullingrp.matProps = new MaterialPropertyBlock();rp.matProps.SetMatrix("_ObjectToWorld", Matrix4x4.Translate(new Vector3(0f, 0, 0)));commandData[0].indexCountPerInstance = mesh.GetIndexCount(0);commandData[0].instanceCount = num;commandBuf.SetData(commandData);Graphics.RenderMeshIndirect(rp, mesh, commandBuf, commandCount);}
}
Shader "ExampleShader"
{SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs#include "UnityIndirect.cginc"struct v2f{float4 pos : SV_POSITION;float4 color : COLOR0;};uniform float4x4 _ObjectToWorld;v2f vert(appdata_base v, uint svInstanceID : SV_InstanceID){InitIndirectDrawArgs(0);v2f o;uint cmdID = GetCommandID(0);uint instanceID = GetIndirectInstanceID(svInstanceID);float timeOffset = _Time.y * 0.5; // 调整运动速度float xOffset = sin(timeOffset + instanceID *5) * 10; // x方向偏移float yOffset = cos(timeOffset + instanceID * 7) * 10; // y方向偏移float zOffset = sin(timeOffset + instanceID * 9) *10; // z方向偏移float4 wpos = mul(_ObjectToWorld, v.vertex + float4(instanceID%1000+ xOffset, cmdID+ yOffset, instanceID / 1000 *3+zOffset, 0));o.pos = mul(UNITY_MATRIX_VP, wpos);o.color = float4(cmdID & 1 ? 0.0f : 1.0f, cmdID & 1 ? 1.0f : 0.0f, instanceID / float(GetIndirectInstanceCount()), 0.0f);return o;}float4 frag(v2f i) : SV_Target{return i.color;}ENDCG}}
}

100w个方块能跑150帧,cool!

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

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

相关文章

golang for经典练习 金字塔打印 示例 支持控制台输入要打印的层数

go语言中最经典的for练习程序 金字塔打印 &#xff0c;这也是其他语言中学习循环和条件算法最为经典的联系题。 其核心算法是如何控制内层循环变量j 每行打印的*号数量 j<i*2-1 和空格数量 j1 || j i*2-1 golang中实现实心金字塔 Solid Pyramid和空心金字塔 Hollow Pyram…

CSS浮动(如果想知道CSS有关浮动的知识点,那么只看这一篇就足够了!)

前言&#xff1a;在学习CSS排版的时候&#xff0c;浮动是我们必须要知道的知识点&#xff0c;浮动在设计之初是为了实现文字环绕效果的&#xff0c;但是后来被人们发现浮动在CSS排版中有着很好的实用价值&#xff0c;所以浮动便成为了CSS排版的利器之一。 ✨✨✨这里是秋刀鱼不…

pandas学习笔记12

缺失数据处理 其实在很多时候&#xff0c;人们往往不愿意过多透露自己的信息。假如您正在对用户的产品体验做调查&#xff0c;在这个过程中您会发现&#xff0c;一些用户很乐意分享自己使用产品的体验&#xff0c;但他是不愿意透露自己的姓名和联系方式&#xff1b; 还有一些用…

《尿不湿级》STM32 F103C8T6最小系统板搭建(五)BOOT

一、BOOT是什么&#xff1f; 大多数初学者第一次接触BOOT总是对这个词感到不解&#xff0c;从哪冒出一个奇奇怪怪的东西还要接跳线帽&#xff0c;为什么要配置它才能进行串口程序的下载&#xff1f;为什么不正确配置会导致单片机无法正常启动…… boot&#xff0c;及物动词&…

AI-数学-高中56-成对数据统计-线性回归方程

原作者视频&#xff1a;【成对数据统计】【一数辞典】1线性回归方程_哔哩哔哩_bilibili 注意&#xff1a;高中只学线性回归。 最小二乘法&#xff08;残差和平方最小的直线、方差最小>拟合程度最好&#xff09;&#xff1a;

2.spring security 简单入门

创建springboot 项目&#xff0c;引入spring security坐标 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--spring security坐标--><dependency&g…

17_Scala面向对象高阶功能

文章目录 1.继承1.1 构造对象时,父类对象优于子类对象1.2父类主构造有参数,子类必须要显示地调用父类主构造器并传值 2.封装3.抽象3.1抽象定义3.2子类继承抽象类3.3抽象属性 4.伴生对象4.1创建类和伴生对象4.2调用 1.继承 –和Java一样,权限protected , public.父类定义子类用…

分布式锁之-redis

什么是分布式锁&#xff1f; 即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题&#xff0c;而分布式锁&#xff0c;就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是&#xff0c;分布式系统中竞争共享资源的最小粒度从线程升级成了…

详细介绍ARM-ORACLE Database 19c数据库下载

目录 1. 前言 2. 获取方式 2.1 ORACLE专栏 2.2 ORACLE下载站点 1. 前言 现有网络上已有非常多关于ORACLE数据库机下载的介绍&#xff0c;但对于ARM平台的介绍不多&#xff0c;借此机会我将该版的下载步骤做如下说明&#xff0c;希望能够一些不明之人提供帮助和参考 2. 获…

Linux理解文件操作 文件描述符fd 理解重定向 dup2 缓冲区 C语言实现自己的shell

文章目录 前言一、文件相关概念与操作1.1 open()1.2 close()1.3 write()1.4 read()1.4 写入的时候先清空文件内容再写入1.5 追加&#xff08;a && a&#xff09; 二、文件描述符2.1 文件描述符 fd 0 1 2 的理解2.2 FILE结构体&#xff1a;的源代码 三、深入理解文件描述…

DETR类型检测网络---思考和Tricks测试

目录 batch_size的影响辅助损失的作用学习率的影响Decoder层数增多的影响3D检测中, feats位置编码和query位置编码是否共享mpl层背景-关于query的生成方式 利用widthformer类似的方式简化注意力机制 batch_size的影响 batch8: batch20: 由实验结果可知:这里实验有问题,横坐标…

JAVA语言开发的智慧城管系统源码:技术架构Vue+后端框架Spring boot+数据库MySQL

通过综合应用计算机技术、网络技术、现代通信技术等多种信息技术&#xff0c;充分融合RS遥感技术、GPS全球定位技术、GIS地理信息系统&#xff0c;开始建设一个动态可视的、实时更新的、精细量化的城市管理系统。智慧城管将采用云平台架构方式进行建设&#xff0c;基于现有数字…

人工智能大模型应用指南

大家好&#xff0c;我是爱编程的喵喵。双985硕士毕业&#xff0c;现担任全栈工程师一职&#xff0c;热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。…

直流屏整流模块HG07A220R电源模块HG10A220R

直流屏整流模块HG07A220R电源模块HG10A220R 其他同类型监控模块PM09T电源模块HG22005/S&#xff0c;HG22010/S&#xff0c;HG11010/S&#xff0c;HG11020/S&#xff0c;HG10A220Z&#xff0c;HG10A220F&#xff0c;HG05A220Z&#xff0c;HG07A220Z&#xff0c;HG10A110Z&#x…

免费可商用字体素材大全,办公设计字体合集打包166款

一、素材描述 这是一套免费可商用字体素材&#xff0c;这些字体一般会在办公与设计的时候用到&#xff0c;比如&#xff0c;Photoshop、illustrator、Coreldraw、AfterEffects、Indesign、WPS、Office&#xff0c;等等&#xff0c;想要更好更快地办公与设计&#xff0c;字体还…

【Java】面向对象核心知识点(二),文章层次分明,内容精益求精,代码简单易懂

目录 一、构造方法 1.1 概念 1.2 作用 1.3 代码 二、抽象 2.1 概念 2.2 作用 2.3 注意 2.4 代码 三、接口 3.1 概念 3.2 作用 3.3 注意 3.4 语法 3.5 代码 四、内部类 4.1 成员内部类 4.2 局部内部类 4.3 静态内部类 4.4 匿名内部类 &#xff08;原创文章&…

WWW‘24 | 课程学习CL+模仿学习IL用于ETF及商品期货交易

WWW24 | 课程学习CL模仿学习IL用于ETF及商品期货交易 原创 QuantML QuantML 2024-05-04 13:47 论文地址&#xff1a;[2311.13326] Curriculum Learning and Imitation Learning for Model-free Control on Financial Time-series (arxiv.org) 本文探讨了在金融时间序列数据上…

W801学习笔记十七:古诗学习应用——上

硬件驱动以及软件架构大体上已经完成&#xff0c;尚存一些遗漏之处&#xff0c;后续会寻找合适的时机进行补充。自此章起&#xff0c;将正式迈入软件应用阶段&#xff0c;尤其是游戏开发领域。 关于第一个应用&#xff0c;此前已有一些构想&#xff1a; 其一&#xff0c;随机…

【跟我学RISC-V】(二)RISC-V的基础知识学习与汇编练习

写在前面&#xff1a; 这篇文章是跟我学RISC-V的第二期&#xff0c;是第一期的延续&#xff0c;第一期主要是带大家了解一下什么是RISC-V,是比较大体、宽泛的概念。这一期主要是讲一些基础知识&#xff0c;然后进行RISC-V汇编语言与c语言的编程。在第一期里我们搭建了好几个环…

FBA头程空运发货流程详解|携手天图通逊,开启高效跨境物流之旅

在众多头程发货方式中&#xff0c;空运以其速度快、时效高的特点&#xff0c;成为许多卖家特别是急需快速补货或应对市场变化的友好选择&#xff0c;那FBA头程空运的发货流程是怎样的呢? 1、发货准备 在开始空运之前&#xff0c;首先需要进行发货准备。这包括将货物送达指定的…