GPU Instancing 实战:一句话画一万个,怎么开怎么用全讲透
开场一个一万棵草让 CPU 崩溃的难题小王要做一片草地一万棵草。他先试了动态批处理——直接卡爆“一万棵草DrawCall 爆炸CPU 直接跪了老鸟说这种’大量相同物体’要用GPU Instancing……可这玩意儿到底怎么开启、怎么用是勾个选项就行还是要写代码有几种用法”老鸟说“GPU Instancing 就是为’大量相同物体’而生的神器一次 DrawCall 画上万个相同网格CPU 几乎不累开启方式有好几种从’勾选项’到’写代码’都有今天把每种用法手把手教你” 第一幕GPU Instancing 是什么核心定义GPU Instancing(GPU实例化) 用一次DrawCall画大量相同网格的物体 ↓ 关键: 网格相同、材质相同,但 每个实例可以有不同的 位置/旋转/缩放(和少量其他属性) ↓ CPU只传每个实例的差异数据 GPU自己复制网格,画出所有实例!为什么它高效普通渲染1000棵树: CPU发1000个DrawCall 每个都传网格数据 → CPU累死 GPU Instancing: CPU发1个DrawCall 一个1000个实例的变换数组 GPU拿着同一个网格,画1000次 ↓ CPU超轻松,GPU高效批量!生动理解GPU Instancing像盖章印刷 普通渲染: 一张张手画1000棵树(累) Instancing: 刻一个树的印章(网格) 给GPU一张1000个盖章位置的清单 GPU咔咔咔盖1000个章! ↓ 一个模子,批量复制,飞快!和其他批处理的定位动态批处理: 小的、不同的动态物体(CPU拼顶点) 静态批处理: 静止物体(预处理合并) GPU Instancing: 大量相同网格⭐ ↓ Instancing专治: 树、草、石头、子弹、 敌人群、粒子...大量重复的东西! 第二幕方式一——材质勾选(最简单)⭐开启步骤✅ 最简单的开启方式 1. 选中材质 2. Inspector里找到 Enable GPU Instancing 3. 勾选它! ↓ 搞定!用这个材质的相同物体 会自动尝试Instancing前提条件✅ 要生效需满足 1. Shader支持Instancing (URP的Lit、Unlit等内置Shader都支持) 2. 物体用相同网格 相同材质 3. 物体是普通的MeshRenderer (场景里摆放的GameObject) ↓ 勾选满足条件 → 自动Instancing适用场景✅ 这种方式适合 场景里手动摆放/Instantiate的 大量相同物体 (如摆了一堆相同的石头、树) ↓ 最省事,勾一下就行!生动理解勾选方式材质勾选像告诉系统:这批可以盖章印 勾上Enable GPU Instancing 跟Unity说这材质的相同物体, 请用盖章方式批量画 ↓ Unity自动识别相同的,批量处理! 第三幕方式二——代码 DrawMeshInstanced适用场景✅ 当物体不是场景GameObject, 而是纯数据驱动渲染时 (如程序生成的大量草、子弹、特效) ↓ 用代码直接调用Instancing绘制! 不需要创建GameObject!基础代码usingUnityEngine;publicclassGrassInstancing:MonoBehaviour{publicMeshgrassMesh;// 草的网格publicMaterialgrassMat;// 开启Instancing的材质Matrix4x4[]matrices;// 每个实例的变换voidStart(){intcount1000;// ⚠️单次上限1023!matricesnewMatrix4x4[count];for(inti0;icount;i){Vector3posnewVector3(Random.Range(-50f,50f),0,Random.Range(-50f,50f));QuaternionrotQuaternion.Euler(0,Random.Range(0,360f),0);Vector3scaleVector3.one;matrices[i]Matrix4x4.TRS(pos,rot,scale);}}voidUpdate(){// ⭐一次画1000棵草!Graphics.DrawMeshInstanced(grassMesh,0,grassMat,matrices);}}关键限制单次1023个⚠️ DrawMeshInstanced单次最多画1023个! ↓ 超过要分批: 10000棵草 → 分成10次调用 每次≤1023个分批处理代码voidDrawManyInstances(Matrix4x4[]allMatrices){inttotalallMatrices.Length;// 假设10000intbatchSize1023;for(inti0;itotal;ibatchSize){intcountMathf.Min(batchSize,total-i);// 取这一批的子数组Matrix4x4[]batchnewMatrix4x4[count];System.Array.Copy(allMatrices,i,batch,0,count);Graphics.DrawMeshInstanced(grassMesh,0,grassMat,batch);}}⚠️ 注意: 上面每帧new数组会GC! 实际应预先分好批,缓存数组复用!生动理解代码方式DrawMeshInstanced像直接下达印刷指令 不用摆GameObject 直接跟GPU说: 拿这个网格(草),照这1000个位置(矩阵), 给我批量印出来! ↓ 纯数据驱动,超高效,适合海量物体! 第四幕方式三——DrawMeshInstancedIndirect(超大量)适用场景✅ 当数量巨大(几万、几十万) 甚至实例数据在GPU上生成时 ↓ 用Indirect版本: 实例参数放在GPU缓冲(ComputeBuffer) 连画多少个都由GPU决定! ↓ 适合: 超大规模草地、粒子、 GPU剔除后的渲染简化示例usingUnityEngine;publicclassMassiveGrass:MonoBehaviour{publicMeshmesh;publicMaterialmat;publicintinstanceCount100000;// 十万!ComputeBufferargsBuffer;// 绘制参数ComputeBufferpositionBuffer;// 实例位置数据uint[]argsnewuint[5]{0,0,0,0,0};voidStart(){// 设置绘制参数args[0]mesh.GetIndexCount(0);// 索引数args[1](uint)instanceCount;// 实例数argsBuffernewComputeBuffer(1,args.Length*sizeof(uint),ComputeBufferType.IndirectArguments);argsBuffer.SetData(args);// 准备实例位置数据(传到GPU)Vector4[]positionsnewVector4[instanceCount];for(inti0;iinstanceCount;i){positions[i]newVector4(Random.Range(-100f,100f),0,Random.Range(-100f,100f),1);}positionBuffernewComputeBuffer(instanceCount,sizeof(float)*4);positionBuffer.SetData(positions);mat.SetBuffer(_Positions,positionBuffer);}voidUpdate(){// ⭐一次调用画十万个!Graphics.DrawMeshInstancedIndirect(mesh,0,mat,newBounds(Vector3.zero,Vector3.one*1000),argsBuffer);}voidOnDestroy(){argsBuffer?.Release();positionBuffer?.Release();}}关键点✅ Indirect版本特点 - 数量几乎无上限 - 实例数据在GPU缓冲 - 参数(画多少)也可GPU动态定 - 配合Compute Shader做GPU剔除 ↓ ⚠️ 复杂度高,ComputeBuffer要记得Release!生动理解 IndirectIndirect像全自动印刷厂 普通DrawMeshInstanced: 你告诉印刷机印1000个(CPU定数量) Indirect: 印刷机自己的系统(GPU)决定印多少! 连数量都在GPU算(如剔除后剩多少) ↓ 超大规模、GPU驱动的终极方案! 第五幕让实例各不相同(每实例属性)需求不同实例不同颜色Instancing默认所有实例材质属性一样 → 但想让每个实例不同颜色怎么办? ↓ 用MaterialPropertyBlock传每实例数据!代码实现usingUnityEngine;publicclassColoredInstances:MonoBehaviour{publicMeshmesh;publicMaterialmat;Matrix4x4[]matrices;MaterialPropertyBlockprops;voidStart(){intcount500;matricesnewMatrix4x4[count];Vector4[]colorsnewVector4[count];for(inti0;icount;i){matrices[i]Matrix4x4.TRS(newVector3(Random.Range(-20f,20f),0,Random.Range(-20f,20f)),Quaternion.identity,Vector3.one);// 每个实例随机颜色colors[i]newColor(Random.value,Random.value,Random.value,1);}// ⭐用PropertyBlock设置每实例颜色数组propsnewMaterialPropertyBlock();props.SetVectorArray(_Colors,colors);}voidUpdate(){Graphics.DrawMeshInstanced(mesh,0,mat,matrices,matrices.Length,props);}}Shader 要支持每实例属性// Shader里声明每实例属性 UNITY_INSTANCING_BUFFER_START(Props) UNITY_DEFINE_INSTANCED_PROP(float4, _Color) UNITY_INSTANCING_BUFFER_END(Props) half4 frag(v2f i) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); // 关键 // 取当前实例的颜色 float4 col UNITY_ACCESS_INSTANCED_PROP( Props, _Color); return col; }生动理解每实例属性每实例属性像同款盖章不同颜色墨水 网格相同(同一个印章) 但每个盖章用不同颜色墨水(每实例颜色) ↓ 还是批量盖章(Instancing不断) 但每个又能不一样! ↓ 既高效又有变化! 第六幕三种方式对比与选择对比表方式 数量 用法 场景 ────────────────────────────────────────────────────── 材质勾选 中等 最简单 场景摆放的相同物体 DrawMeshInstanced ≤1023/次 写代码 程序生成的大量物体 DrawMeshInstanced- 几乎无限 复杂 超大规模、GPU驱动 Indirect (草海、GPU剔除) ──────────────────────────────────────────────────────选择建议✅ 怎么选 场景里摆的相同物体(石头堆) → 材质勾选,最省事 程序生成、几百到几千个(子弹、敌人) → DrawMeshInstanced 超大规模、几万几十万(草海、森林) → DrawMeshInstancedIndirect 配合GPU剔除 ↓ 按数量和场景选!⚠️ 第七幕使用注意点注意1Shader 必须支持⚠️ 不是所有Shader都支持Instancing! ↓ ✅ 检查 - URP内置Shader(Lit/Unlit)默认支持 - 自定义Shader要加Instancing支持代码 #pragma multi_compile_instancing注意2性能不一定总赢⚠️ Instancing也有开销(准备实例数据) 物体数量少时,可能不如普通渲染 ↓ ✅ 适合大量相同物体 少量(几个)没必要用注意3数组不要每帧 new// ❌ 每帧new,GC暴增!voidUpdate(){Matrix4x4[]mnewMatrix4x4[1000];// 坏!}// ✅ 缓存数组,复用Matrix4x4[]cached;voidStart(){cachednewMatrix4x4[1000];}voidUpdate(){/* 用cached */}注意4ComputeBuffer 要 Release// ⚠️ Indirect用的ComputeBuffer// 必须手动释放,否则内存泄漏!voidOnDestroy(){argsBuffer?.Release();positionBuffer?.Release();}注意5验证是否真的Instancing了✅ 用Frame Debugger确认 看到 Draw Mesh (instanced) → 成功!一次画了多个 ↓ 没生效就查Shader支持、材质设置️ 第八幕实战——完整草地方案需求做一片5000棵草的草地 要求: 高性能、每棵草朝向随机完整代码usingUnityEngine;publicclassGrassField:MonoBehaviour{publicMeshgrassMesh;publicMaterialgrassMat;// 勾了InstancingpublicintgrassCount5000;publicfloatfieldSize50f;// 分批(每批1023)Matrix4x4[][]batches;voidStart(){intbatchSize1023;intbatchCountMathf.CeilToInt((float)grassCount/batchSize);batchesnewMatrix4x4[batchCount][];intcreated0;for(intb0;bbatchCount;b){intsizeMathf.Min(batchSize,grassCount-created);batches[b]newMatrix4x4[size];for(inti0;isize;i){Vector3posnewVector3(Random.Range(-fieldSize,fieldSize),0,Random.Range(-fieldSize,fieldSize));QuaternionrotQuaternion.Euler(0,Random.Range(0,360f),0);batches[b][i]Matrix4x4.TRS(pos,rot,Vector3.one);}createdsize;}}voidUpdate(){// 每帧画所有批次(数组已缓存,无GC)foreach(varbatchinbatches){Graphics.DrawMeshInstanced(grassMesh,0,grassMat,batch);}}}✅ 要点 - 预先分好批,缓存数组(无GC) - 每帧只调用绘制(不重新生成数据) - 材质勾了Instancing、Shader支持 ↓ 5000棵草,极少DrawCall,CPU轻松!✅ GPU Instancing 使用检查清单开启方式 □ 会材质勾选Enable GPU Instancing⭐ □ 会用DrawMeshInstanced代码 □ 知道有DrawMeshInstancedIndirect 前提条件 □ Shader支持Instancing □ 相同网格相同材质 □ 自定义Shader加了multi_compile_instancing 每实例属性 □ 会用MaterialPropertyBlock传每实例数据 □ Shader里用UNITY_ACCESS_INSTANCED_PROP 注意事项 □ 知道DrawMeshInstanced单次≤1023 □ 数组缓存不每帧new(避免GC) □ ComputeBuffer记得Release □ 用Frame Debugger验证真Instancing了 选型 □ 场景摆放→材质勾选 □ 程序生成→DrawMeshInstanced □ 超大规模→Indirect 一句话总结GPU Instancing 怎么用它用一次 DrawCall 画大量相同网格专治树、草、子弹、敌人群这类大量重复物体。三种开启方式① 材质勾选 “Enable GPU Instancing”最简单适合场景摆放的相同物体② 代码Graphics.DrawMeshInstanced适合程序生成单次上限 1023 个超过要分批③DrawMeshInstancedIndirect超大规模几万几十万实例数据放 GPU 缓冲配合 GPU 剔除。想让每个实例不同如颜色用 MaterialPropertyBlock 传每实例数据Shader 里用 UNITY_ACCESS_INSTANCED_PROP 读取。关键注意Shader 必须支持自定义 Shader 加#pragma multi_compile_instancing、数组别每帧 newGC、ComputeBuffer 要 Release、用 Frame Debugger 验证真的 Instancing 了核心口诀Instancing一次画一堆相同物体材质勾选最简单代码DrawMeshInstanced上限1023要分批超大量用Indirect每实例差异用PropertyBlockShader要支持数组缓存别GC GPU Instancing 使用速查表方式数量难度适用材质勾选中⭐最易场景摆放物体DrawMeshInstanced≤1023/次中程序生成物体DrawMeshInstancedIndirect几乎无限高超大规模/GPU驱动PropertyBlock-中每实例差异化 一句话记住核心场景摆放勾材质、程序生成用 DrawMeshInstanced记得分批 1023、超大规模用 Indirect。Shader 必须支持、数组要缓存、Buffer 要释放——写完一定用 Frame Debugger 看到 “instanced” 才算成功 延伸Instancing 的进阶方向【GPU Instancing的进阶玩法】 基础Instancing → 更强的组合 ① GPU剔除(Compute Shader): GPU算哪些实例可见 → 只画可见的 → DrawMeshInstancedIndirect动态数量 ② LOD: 远处实例用低模,近处高模 → 分组Instancing ③ 动画: 顶点动画烘焙到纹理(VAT) → 大量动画角色也能Instancing! ④ 结合SRP Batcher: URP下两者配合优化 ↓ 从静态草地到十万动画大军 Instancing是大规模渲染的核心!

相关新闻

从检索到生成:统一外部与参数知识,小白也能掌握的大模型医疗问答秘籍!收藏学习,轻松提升!

从检索到生成:统一外部与参数知识,小白也能掌握的大模型医疗问答秘籍!收藏学习,轻松提升!

本文探讨了医疗问答中模型应如何结合外部检索文档与自身生成背景知识。传统方法如RAG和GAG各有优劣,前者证据可追溯但信息可能不完整,后者解释贴合问题但易生成错误。为解决此问题,本文提出了MedRGAG框架,通过均衡检索、知识引导补…

2026/8/18 9:11:32 阅读更多 →
Switch手柄连接电脑,5分钟上手BetterJoy:让Pro手柄和Joy-Con在PC上满血复活

Switch手柄连接电脑,5分钟上手BetterJoy:让Pro手柄和Joy-Con在PC上满血复活

Switch手柄连接电脑,5分钟上手BetterJoy:让Pro手柄和Joy-Con在PC上满血复活 【免费下载链接】BetterJoy Allows the Nintendo Switch Pro Controller, Joycons and SNES controller to be used with CEMU, Citra, Dolphin, Yuzu and as generic XInput …

2026/8/18 9:11:32 阅读更多 →
小白程序员必学:三大经典Agent设计范式,彻底搞懂大模型执行逻辑

小白程序员必学:三大经典Agent设计范式,彻底搞懂大模型执行逻辑

本文深入剖析了ReAct、Plan-and-Execute、Reflection三大经典Agent设计范式,阐述了它们的核心原理、优劣势及适用场景。文章强调这三大范式是构建智能体的基础,并澄清了常见的认知误区,如将Reflection误认为调试工具或将多智能体模式视为独立…

2026/8/19 11:09:21 阅读更多 →

最新新闻

EFLUX:基于Agentic LLM的弹性多机器人协同导航系统解析

EFLUX:基于Agentic LLM的弹性多机器人协同导航系统解析

1. 从“编队”到“弹性”:多机器人协同导航的范式转变 在机器人研究领域,让多个机器人像雁群一样保持特定队形移动,即“多机器人编队导航”,已经是一个被深入探索了数十年的经典问题。传统的解决方案,无论是基于领航-跟…

2026/8/19 11:08:54 阅读更多 →
AI智能体如何实现人机协同深度研究:从任务规划到信息整合

AI智能体如何实现人机协同深度研究:从任务规划到信息整合

1. 项目概述:当人类与AI共同“深潜”信息海洋 “InterDeepResearch”这个项目标题,初看有些学术化,但它的核心愿景非常清晰: 让人类与AI智能体(Agent)能够像搭档一样,协同进行深度信息调研&…

2026/8/19 11:08:54 阅读更多 →
免费二维码接口梳理:生成与识别方案怎么选

免费二维码接口梳理:生成与识别方案怎么选

二维码生成与识别是开发里的高频需求——活动页分享、登录扫码、设备配网都会用到。本文围绕万维易源(showapi)的「二维码生成与识别」接口(gateway 887,官方自营、免费可用)展开,同时梳理社区里常被提到的…

2026/8/19 11:08:54 阅读更多 →
SageMaker Canvas 拖拽建模:我以为神经网络是黑箱,直到看到特征重要性图谱

SageMaker Canvas 拖拽建模:我以为神经网络是黑箱,直到看到特征重要性图谱

SageMaker Canvas 拖拽建模:我以为神经网络是黑箱,直到看到特征重要性图谱 从Excel到神经网络预测的魔幻之旅 上周三产品会上,当业务方第N次问『下个月客户流失率会是多少』时,我盯着自己手工维护的Excel预测模型突然意识到--这套用历史平均值乘以系数的土办法,误差率已经飙升…

2026/8/19 11:08:54 阅读更多 →
免费地址与经纬度互转接口盘点:含国内精准到县区方案

免费地址与经纬度互转接口盘点:含国内精准到县区方案

本文基于 2026-08-19 通过浏览器直连真实请求所做的可用性实测,对社区里流传的免费地址↔经纬度(地理编码 / 逆地理编码)方案做了逐一核验。免费接口普遍限流,正式接入前建议再自测一次。背景地址与经纬度互转(正向地理…

2026/8/19 11:08:54 阅读更多 →
Go对比Python asyncio,GPT-Live语音p95降至p50

Go对比Python asyncio,GPT-Live语音p95降至p50

将媒体前端用Go进行重写, GPT - Live语音的p95延迟直接降低到原系统的p50水平。历经六个月开发出第三代语音系统, 这第三代语音系统把turn从音频链路里完全剔除出去。下面这套架构成功地将推理延迟压制到了亚秒这个级别, 你到下半年通过使得 Agent 去运行长任务或者充当开展实时…

2026/8/19 11:07:53 阅读更多 →

日新闻

【单片机课程设计/毕业设计】基于 STM32 与 WiFi 模块的室内通风智能管控系统设计 基于 STM32 的人体存在感知自适应风扇控制系统设计(018503)

【单片机课程设计/毕业设计】基于 STM32 与 WiFi 模块的室内通风智能管控系统设计 基于 STM32 的人体存在感知自适应风扇控制系统设计(018503)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/8/19 0:00:30 阅读更多 →
AI如何驱动数学猜想生成:从大语言模型到自动化数学发现

AI如何驱动数学猜想生成:从大语言模型到自动化数学发现

1. 项目概述:当AI开始“猜”数学定理 最近在AI研究圈里,一个名为“Moonshine”的项目引起了不小的讨论。这名字本身就挺有意思,直译是“月光”,但在数学史上,它特指一个神秘而美丽的联系——魔群月光猜想,连…

2026/8/19 0:00:30 阅读更多 →
WarcraftHelper 魔兽争霸3优化实战指南

WarcraftHelper 魔兽争霸3优化实战指南

WarcraftHelper 魔兽争霸3优化实战指南 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 一台刚配的新电脑,跑《魔兽争霸3》却卡成 PPT——这…

2026/8/19 0:02:31 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/18 9:15:35 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/19 9:46:27 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/18 9:04:56 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/19 5:04:55 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/19 7:42:22 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/17 18:55:55 阅读更多 →