{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/gpu-instancing-applications/",
  "atlas": "https://www.pystone.net/?node=gpu-instancing-applications#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/gpu-instancing-applications.md",
  "context": "https://www.pystone.net/notes/gpu-instancing-applications.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:gpu-instancing-applications",
  "slug": "gpu-instancing-applications",
  "title": "GPU Instancing及其应用",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "GPU Instancing及其应用",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "843390c729eb981362bf6cb23e9ae1754032c99ae6ec7feb70b01180a9aa9bb7",
  "assets": [
    {
      "reference": "assets/1621260332344.png",
      "url": "/media/0cbbb3effb571c0f8890.png",
      "mediaType": "image/png",
      "contentHash": "0cbbb3effb571c0f88909a645011d3c3d9f282c5a1a2cf722ca3eb52ef01211f",
      "byteLength": 49814,
      "width": 1213,
      "height": 245
    },
    {
      "reference": "assets/0026 - GPU Instancing及其应用__1621260332344.png",
      "url": "/media/0cbbb3effb571c0f8890.png",
      "mediaType": "image/png",
      "contentHash": "0cbbb3effb571c0f88909a645011d3c3d9f282c5a1a2cf722ca3eb52ef01211f",
      "byteLength": 49814,
      "width": 1213,
      "height": 245
    },
    {
      "reference": "assets/0026 - GPU Instancing及其应用__1621164352833.png",
      "url": "/media/832cb9717d81b09610aa.png",
      "mediaType": "image/png",
      "contentHash": "832cb9717d81b09610aae32abdb826c87348ad07a331e7c66a081311597a7c15",
      "byteLength": 68436,
      "width": 981,
      "height": 376
    },
    {
      "reference": "assets/0026 - GPU Instancing及其应用__1621233806722.png",
      "url": "/media/c106c312262ef25a2e45.png",
      "mediaType": "image/png",
      "contentHash": "c106c312262ef25a2e45cc116023b95225c322c8e2812480b6525efd02225138",
      "byteLength": 78829,
      "width": 955,
      "height": 382
    }
  ],
  "headings": [
    {
      "depth": 1,
      "text": "GPU Instancing及其应用",
      "anchor": "gpu-instancing及其应用",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#gpu-instancing%E5%8F%8A%E5%85%B6%E5%BA%94%E7%94%A8"
    },
    {
      "depth": 2,
      "text": "相关知识点",
      "anchor": "相关知识点",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86%E7%82%B9"
    },
    {
      "depth": 3,
      "text": "ComputeBuffer",
      "anchor": "computebuffer",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#computebuffer"
    },
    {
      "depth": 4,
      "text": "Append-consume ComputeBuffer",
      "anchor": "append-consume-computebuffer",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#append-consume-computebuffer"
    },
    {
      "depth": 4,
      "text": "ComputeBuffer.CopyCount",
      "anchor": "computebuffercopycount",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#computebuffercopycount"
    },
    {
      "depth": 4,
      "text": "Other ComputeBuffer",
      "anchor": "other-computebuffer",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#other-computebuffer"
    },
    {
      "depth": 2,
      "text": "Graphics:DrawMeshInstanced",
      "anchor": "graphicsdrawmeshinstanced",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#graphicsdrawmeshinstanced"
    },
    {
      "depth": 3,
      "text": "DrawMeshInstanced",
      "anchor": "drawmeshinstanced",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#drawmeshinstanced"
    },
    {
      "depth": 3,
      "text": "DrawMeshInstancedIndirect",
      "anchor": "drawmeshinstancedindirect",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#drawmeshinstancedindirect"
    },
    {
      "depth": 3,
      "text": "DrawMeshInstancedProcedural",
      "anchor": "drawmeshinstancedprocedural",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#drawmeshinstancedprocedural"
    },
    {
      "depth": 3,
      "text": "Benchmark",
      "anchor": "benchmark",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#benchmark"
    },
    {
      "depth": 4,
      "text": "不同方式绘制的性能",
      "anchor": "不同方式绘制的性能",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#%E4%B8%8D%E5%90%8C%E6%96%B9%E5%BC%8F%E7%BB%98%E5%88%B6%E7%9A%84%E6%80%A7%E8%83%BD"
    },
    {
      "depth": 4,
      "text": "关于剔除",
      "anchor": "关于剔除",
      "citation": "https://www.pystone.net/notes/gpu-instancing-applications/#%E5%85%B3%E4%BA%8E%E5%89%94%E9%99%A4"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:game-graphics-and-runtime",
      "title": "游戏图形与运行时",
      "url": "https://www.pystone.net/notes/game-graphics-and-runtime/",
      "atlas": "https://www.pystone.net/?node=game-graphics-and-runtime#knowledge-atlas",
      "label": "游戏图形与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "渲染基础中的“GPU Instancing及其应用”导航项",
      "citation": "https://www.pystone.net/notes/game-graphics-and-runtime/#%E6%B8%B2%E6%9F%93%E5%9F%BA%E7%A1%80"
    }
  ],
  "contentMarkdown": "# GPU Instancing及其应用\n\n> 创建时间：2021/5/17 21:44\n\n  * GPU Instancing及其应用\n    * 相关知识点\n      * ComputeBuffer\n        * Append-consume ComputeBuffer\n        * ComputeBuffer.CopyCount\n        * Other ComputeBuffer\n    * Graphics:DrawMeshInstanced\n      * DrawMeshInstanced\n      * DrawMeshInstancedIndirect\n      * DrawMeshInstancedProcedural\n      * Benchmark\n        * 不同方式绘制的性能\n        * 关于剔除\n\n## 相关知识点\n\n### ComputeBuffer\n\n心得：\n\n  * ComputeBuffer种类多，操作相关的API类型多，其根本原因在于，GPU的智能化程度低，CPU去访问现存操作数据不方便，效率低，因此，指令种类复杂，可定制程度低。\n\n  * ComputeBuffer可以由ComputeShader使用，也可以有Shader使用，作为 ComputeShader与常规渲染Shader的桥梁，使得两者之间传递信息的效率较高，Shader功能的可定制性、可扩展性增强，ComputeShader与Shader可以灵活地结合使用。\n\n  * ComputeShader的优势在于\n\n    * GPU计算，擅长处理大量并行化的任务，效率高\n\n    * 计算得到的结果不需要用CPU获取，可以直接用于渲染，数据传递效率高。\n\n#### Append-consume ComputeBuffer\n\n  * AppendStructuredBuffer - Output buffer that appears as a stream the shader may append to.\n\n  * ConsumeStructuredBuffer - An input buffer that appears as a stream the shader may pull values from.\n\n#### ComputeBuffer.CopyCount\n\nCopy counter value of append/consume buffer into another buffer.\n\nAppend/consume and counter buffers keep track of the number of elements in them with a special counter variable. CopyCount takes a buffer as src, and copies its counter value into dst buffer at given **byte offset**.\n\nThis is most commonly used in conjunction with Graphics.DrawProceduralIndirect, to render arbitrary number of primitives **without reading their count back to the CPU**.\n\n> On DX11 there is a restriction on the dst buffer - it must have been created with ComputeBufferType.Raw or ComputeBufferType.IndirectArguments type. On other platforms dst can be any type.\n\n#### Other ComputeBuffer\n\n![Alt text](assets/1621260332344.png)\n\n## Graphics:DrawMeshInstanced\n\n### DrawMeshInstanced\n\ndraws meshes for one frame without the overhead of creating unnecessary game objects.\n\n用处：\nUse this function in situations where you want to draw the same mesh for a particular amount of times using an instanced shader.\n\n包围盒计算：\nIt **creates an axis-aligned bounding box that contains all the Meshes** , calculates the center point, then uses this information to cull and sort the Mesh instances.\n\n关于剔除：\nUnity culls and sorts instanced Meshes as a **group**.\n粗粒度剔除：对于 **combined instances** ，要么 **整体都画，要么都不画** 。\nIt creates an axis-aligned bounding box that contains all the Meshes, calculates the center point, then uses this information to cull and sort the Mesh instances.\n\n![Alt text](assets/0026 - GPU Instancing及其应用__1621260332344.png)\n\n参数特征：\n**传入矩阵和矩阵的数量** 来进行绘制。\n\n限制: You can only draw a maximum of 1023 instances at once.\n\n### DrawMeshInstancedIndirect\n\n![Alt text](assets/0026 - GPU Instancing及其应用__1621164352833.png)\n\n与`DrawMeshInstanced`的不同：\n\n  * 参数传递方式不同 - ComputeBuffer\n\n  * 需要指定bounds\n\n  * 没有画多少个的限制\n\nbufferWithArgs：\nindex count per instance\ninstance count\nstart index location\nbase vertex location\nstart instance location\n\n### DrawMeshInstancedProcedural\n\nThis is similar to Graphics.DrawMeshInstancedIndirect, except that the instance count can be supplied directly using this method.\n\n### Benchmark\n\n#### 不同方式绘制的性能\n\n![Alt text](assets/0026 - GPU Instancing及其应用__1621233806722.png)\n\n来源：<https://www.xuanyusong.com/archives/4488>\n\n大量mesh绘制时的性能：\n\nDrawMeshInstancedIndirect（帧率 60） > 自定义Shader中勾选Enable GPU Instancing（帧率 30-40） > 勾选static静态合并批次（40-50帧率）\n\n#### 关于剔除\n\nDrawInstanced接口做的视锥体裁剪，会要么全部剔除，要么全部画出来。而调用之前，所用的矩阵或者是PositionBuffer都可以使用CPU或者ComputeShader算出来，绘制的数量也可以自己决定，因此，可以在绘制之前先做裁剪。\n"
}
