---
title: "GPU Instancing及其应用"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/gpu-instancing-applications/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/05-游戏图形与运行时/渲染基础/GPU Instancing及其应用.md"
content_hash: 843390c729eb981362bf6cb23e9ae1754032c99ae6ec7feb70b01180a9aa9bb7
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# GPU Instancing及其应用

> 创建时间：2021/5/17 21:44

  * GPU Instancing及其应用
    * 相关知识点
      * ComputeBuffer
        * Append-consume ComputeBuffer
        * ComputeBuffer.CopyCount
        * Other ComputeBuffer
    * Graphics:DrawMeshInstanced
      * DrawMeshInstanced
      * DrawMeshInstancedIndirect
      * DrawMeshInstancedProcedural
      * Benchmark
        * 不同方式绘制的性能
        * 关于剔除

## 相关知识点

### ComputeBuffer

心得：

  * ComputeBuffer种类多，操作相关的API类型多，其根本原因在于，GPU的智能化程度低，CPU去访问现存操作数据不方便，效率低，因此，指令种类复杂，可定制程度低。

  * ComputeBuffer可以由ComputeShader使用，也可以有Shader使用，作为 ComputeShader与常规渲染Shader的桥梁，使得两者之间传递信息的效率较高，Shader功能的可定制性、可扩展性增强，ComputeShader与Shader可以灵活地结合使用。

  * ComputeShader的优势在于

    * GPU计算，擅长处理大量并行化的任务，效率高

    * 计算得到的结果不需要用CPU获取，可以直接用于渲染，数据传递效率高。

#### Append-consume ComputeBuffer

  * AppendStructuredBuffer - Output buffer that appears as a stream the shader may append to.

  * ConsumeStructuredBuffer - An input buffer that appears as a stream the shader may pull values from.

#### ComputeBuffer.CopyCount

Copy counter value of append/consume buffer into another buffer.

Append/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**.

This is most commonly used in conjunction with Graphics.DrawProceduralIndirect, to render arbitrary number of primitives **without reading their count back to the CPU**.

> 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.

#### Other ComputeBuffer

![Alt text](/media/0cbbb3effb571c0f8890.png)

## Graphics:DrawMeshInstanced

### DrawMeshInstanced

draws meshes for one frame without the overhead of creating unnecessary game objects.

用处：
Use this function in situations where you want to draw the same mesh for a particular amount of times using an instanced shader.

包围盒计算：
It **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.

关于剔除：
Unity culls and sorts instanced Meshes as a **group**.
粗粒度剔除：对于 **combined instances** ，要么 **整体都画，要么都不画** 。
It 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.

![Alt text](/media/0cbbb3effb571c0f8890.png)

参数特征：
**传入矩阵和矩阵的数量** 来进行绘制。

限制: You can only draw a maximum of 1023 instances at once.

### DrawMeshInstancedIndirect

![Alt text](/media/832cb9717d81b09610aa.png)

与`DrawMeshInstanced`的不同：

  * 参数传递方式不同 - ComputeBuffer

  * 需要指定bounds

  * 没有画多少个的限制

bufferWithArgs：
index count per instance
instance count
start index location
base vertex location
start instance location

### DrawMeshInstancedProcedural

This is similar to Graphics.DrawMeshInstancedIndirect, except that the instance count can be supplied directly using this method.

### Benchmark

#### 不同方式绘制的性能

![Alt text](/media/c106c312262ef25a2e45.png)

来源：<https://www.xuanyusong.com/archives/4488>

大量mesh绘制时的性能：

DrawMeshInstancedIndirect（帧率 60） > 自定义Shader中勾选Enable GPU Instancing（帧率 30-40） > 勾选static静态合并批次（40-50帧率）

#### 关于剔除

DrawInstanced接口做的视锥体裁剪，会要么全部剔除，要么全部画出来。而调用之前，所用的矩阵或者是PositionBuffer都可以使用CPU或者ComputeShader算出来，绘制的数量也可以自己决定，因此，可以在绘制之前先做裁剪。
