1. summary

In the previous article , A material corresponds to a drawing call instruction . Even in this case , Two 3D objects use the same material , But they use different material parameters , Then it will still cause two drawing instructions . The reason lies in , Graphics work is a state machine , The state has changed , You must perform a drawing call instruction .

GPU Instantiation is used to solve such problems : For things like grass 、 Objects like trees , They often have a large amount of data , But at the same time, there are only minor differences, such as location 、 Posture 、 Color, etc. . If you render like a regular object , There must be many drawing instructions used , Resource occupation is bound to be large . A reasonable strategy is , We specify an object that needs to be drawn , And a large number of different parameters of the object , Then draw it in a drawing call according to the parameters —— That's what's called GPU Instantiation .

2. Detailed discussion

First , We create an empty GameObject object , And attach the following script :

using UnityEngine;

// Instantiate parameters 
public struct InstanceParam
{
public Color color;
public Matrix4x4 instanceToObjectMatrix; // Instantiate to the matter matrix
} [ExecuteInEditMode]
public class Note6Main : MonoBehaviour
{
public Mesh mesh;
public Material material; int instanceCount = 200;
Bounds instanceBounds; ComputeBuffer bufferWithArgs = null;
ComputeBuffer instanceParamBufferData = null; // Start is called before the first frame update
void Start()
{
instanceBounds = new Bounds(new Vector3(0, 0, 0), new Vector3(100, 100, 100)); uint[] args = new uint[5] { 0, 0, 0, 0, 0 };
bufferWithArgs = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
int subMeshIndex = 0;
args[0] = mesh.GetIndexCount(subMeshIndex);
args[1] = (uint)instanceCount;
args[2] = mesh.GetIndexStart(subMeshIndex);
args[3] = mesh.GetBaseVertex(subMeshIndex);
bufferWithArgs.SetData(args); InstanceParam[] instanceParam = new InstanceParam[instanceCount]; for (int i = 0; i < instanceCount; i++)
{
Vector3 position = Random.insideUnitSphere * 5;
Quaternion q = Quaternion.Euler(Random.Range(0.0f, 90.0f), Random.Range(0.0f, 90.0f), Random.Range(0.0f, 90.0f));
float s = Random.value;
Vector3 scale = new Vector3(s, s, s); instanceParam[i].instanceToObjectMatrix = Matrix4x4.TRS(position, q, scale);
instanceParam[i].color = Random.ColorHSV();
} int stride = System.Runtime.InteropServices.Marshal.SizeOf(typeof(InstanceParam));
instanceParamBufferData = new ComputeBuffer(instanceCount, stride);
instanceParamBufferData.SetData(instanceParam);
material.SetBuffer("dataBuffer", instanceParamBufferData);
material.SetMatrix("ObjectToWorld", Matrix4x4.identity);
} // Update is called once per frame
void Update()
{
if(bufferWithArgs != null)
{
Graphics.DrawMeshInstancedIndirect(mesh, 0, material, instanceBounds, bufferWithArgs, 0);
}
} private void OnDestroy()
{
if (bufferWithArgs != null)
{
bufferWithArgs.Release();
} if(instanceParamBufferData != null)
{
instanceParamBufferData.Release();
}
}
}

This script means , Set a mesh and a material , Through randomly obtained instantiation parameters , Render multiple instances of this mesh :

GPU The key interface of instantiation is Graphics.DrawMeshInstancedIndirect().Graphics A series of interfaces of an object are Unity The bottom of the API, It needs to be called every frame .Graphics.DrawMeshInstanced() You can also draw instances , But at most, you can only draw 1023 An example . So still Graphics.DrawMeshInstancedIndirect() better .

Instantiate parameters InstanceParam and GPU Buffer parameters bufferWithArgs Are stored in one ComputeBuffer In the object .ComputeBuffe Defined a GPU Data buffer object , Ability to map to Unity Shader Medium StructuredBuffer in . Instantiate parameters InstanceParam Stores the location of each instantiated object , Posture 、 Zoom and color information , adopt Material.SetBuffer(), Pass to shader :

Shader "Custom/SimpleInstanceShader"
{
Properties
{
}
SubShader
{
Tags{"Queue" = "Geometry"} Pass
{
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
#pragma target 4.5 sampler2D _MainTex; float4x4 ObjectToWorld; struct InstanceParam
{
float4 color;
float4x4 instanceToObjectMatrix;
}; #if SHADER_TARGET >= 45
StructuredBuffer<InstanceParam> dataBuffer;
#endif // Vertex shader input
struct a2v
{
float4 position : POSITION;
float3 normal: NORMAL;
float2 texcoord : TEXCOORD0;
}; // Vertex shader output
struct v2f
{
float4 position: SV_POSITION;
float2 texcoord: TEXCOORD0;
float4 color: COLOR;
}; v2f vert(a2v v, uint instanceID : SV_InstanceID)
{
#if SHADER_TARGET >= 45
float4x4 instanceToObjectMatrix = dataBuffer[instanceID].instanceToObjectMatrix;
float4 color = dataBuffer[instanceID].color;
#else
float4x4 instanceToObjectMatrix = float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
float4 color = float4(1.0f, 1.0f, 1.0f, 1.0f);
#endif float4 localPosition = mul(instanceToObjectMatrix, v.position);
//float4 localPosition = v.position;
float4 worldPosition = mul(ObjectToWorld, localPosition); v2f o;
//o.position = UnityObjectToClipPos(v.position);
o.position = mul(UNITY_MATRIX_VP, worldPosition);
o.texcoord = v.texcoord;
o.color = color; return o;
} fixed4 frag(v2f i) : SV_Target
{
return i.color;
} ENDCG
}
} Fallback "Diffuse"
}

This is an improvement from 《Unity3D Learning notes 3——Unity Shader Preliminary use of 》 Simple instantiation shader . The position of instantiated drawing is often not fixed , It means Shader Model matrix obtained in UNITY_MATRIX_M It is generally incorrect . Therefore, the key of instantiation rendering is to recalculate the model matrix , Otherwise, the drawing position is incorrect . The instantiated data is often located close , So you can first pass in a reference position ( matrix ObjectToWorld), Then the instantiated data can only be passed into the relative matrix of this position (instanceToObjectMatrix).

The final running results are as follows , Lots of different positions are drawn 、 Different posture 、 Capsules of different sizes and colors , And the performance is basically unaffected .

3. Reference resources

  1. 《Unity3D Learning notes 3——Unity Shader Preliminary use of 》
  2. Graphics.DrawMeshInstanced

Specific implementation code

Unity3D Learning notes 6——GPU Instantiation (1) More articles about

  1. unity3d Learning notes ( One ) The realization of first person perspective and countdown

    unity3d Learning notes ( One ) The realization of first person perspective and countdown 1. First person perspective (1) Give Way mainCamera and player( Perspective objects ) Synchronized together Because of our player It's generated , So we can't put mainCa ...

  2. Unity3D Learning notes 2—— Draw a textured face

    Catalog 1. summary 2. Detailed discussion 2.1. grid (Mesh) 2.1.1. The vertices 2.1.2. Vertex Index 2.2. texture of material (Material) 2.2.1. Create materials 2.2.2. Use materials 2.3. light ...

  3. Unity3D Learning notes 3——Unity Shader Preliminary use of

    Catalog 1. summary 2. Detailed discussion 2.1. Create materials 2.2. Shaders 2.2.1. name 2.2.2. attribute 2.2.3. SubShader 2.2.3.1. label (Tags) 2.2.3.2. Rendering ...

  4. Step by step learning Unity3d Study notes department 1.3 Hero alliance server cluster architecture

    When it comes to online games, it involves servers , At present, the most popular is the hero League , I'm also a fan of it , Once a week , They say Xiao Lu is happy , Hurt yourself , Roll the ashes away , Also warn my colleagues , take care , So what is his server architecture , Let me share with you , Specifically ...

  5. Unity3D Learning notes

    It's not a technical article , It's just that I've come across some points that I think I need to pay attention to in my personal study , Take notes . 1. About debugging , stay Android The next breakpoint is not possible ,Debug Can't view it , The view log method can start adb Of log function , Or write it yourself GUI control ...

  6. Step by step learning Unity3d Study notes department 1.1

    Recently I began to learn Unity3D, I found some tutorials on the Internet and taught myself when I went home to have a rest in the evening , I am a little white , Yes Unity3D I don't know anything , May need some art skills . Just a little , Need the foundation of point programming , Well, I'm also a little , Yes C# ...

  7. Unity3D Learning notes ( Twenty-nine ):AssetBundle

    AssetBundle What is? AssetBundle? AssetBundle It is to put some resource files or scene files , Save in a file in some way . One AssetBundle Can include models . texture of material . Pictures or scenes . however A ...

  8. Unity3D Learning notes ( 13、 ... and ): entrust 、 Review the exam

    entrust : Compare when to use delegation   Case after class : No bell 1.ClassManager You need to get all the references of the classroom , Classroom managers should only be responsible for timing and informing each classroom 2. Each classroom should be in the charge of the teacher on duty whether it is necessary to finish the class , And classroom management ...

  9. Unity3D Learning notes ( One ):Unity brief introduction 、 Game objects 、 Components and lifecycle functions

    Project( engineering . project ): The project is to classify and manage the resources currently needed for game development . Console Console : journal . Report errors . debugging , Upper right corner , Message filtering Assets: resources , Store all the resources used in the game Library: In the ...

  10. Unity3D Learning notes ( One ):Unity3D brief introduction

    Unity3D Introduction I . What is? Unity.U3D? Fully integrated professional engine Two . What can this software do ?1. Content :3D2D game , education , Architecture , Webpage ,VRAR, Home entertainment system 2. The media :PC platform , host , Move ,VR 1.UE ...

Random recommendation

  1. Small tip: About typeof,instanceof,toString(),valueOf(),toLocaleString(),join(),reverse(),sort(),pop(),push(),shift(),unshift()

    typeof: Used to detect whether a variable is a basic data type .instanceof Used to detect what type of object a reference object is . var s = "Nicho"; var b = true; var n ...

  2. Mobile app test

    For mobile projects ( Application software ), It's mainly about system testing . System testing for mobile applications , We usually test from the following aspects : Function module test : Cross event testing : Performance testing : Security testing : Capacity test : Compatibility test : Pick up ...

  3. cocos2dx Contained in the svn

    Because I don't want to go from svn Upload the whole project , Just put Classes and Resources It's down , Appears when typing Android package WindowsError: [Error 5] : 'D:\\CocosProject\\(Proje ...

  4. Bottle Source reading notes ( One ):WSGI

    Preface Bottle It's a Python Web frame . The whole framework has only one file , Less than 4k Lines of code , No, Python Dependencies outside the standard library , But it includes routing . Templates and plug-ins, etc Web Common functions of framework . By reading Bottle Source code to understand ...

  5. Java Reading notes ( Two ) Objects and classes

    Java As an object-oriented language , The following basic concepts are supported : polymorphic Inherit closed abstract class object example Method heavy load object : Is an instance of a class , Presence and behavior . Take people for example , The yellow race . The white race . Black people are human beings , Every specific human being's ...

  6. POJ-2533.Longest Ordered Subsequence (LIS Template questions )

    The main idea of the problem is : and LIS equally Thinking of this topic : use dp[ i ] Before saving  i  The length of the longest increasing sequence in the number , Then the state transition equation can be obtained dp[ i ] = max(dp[ j ] + 1)(j < i) Reference code : # ...

  7. Jackson Tool class usage and Configuration Guide

    Catalog Preface Jackson Use tool class Jackson Configuration properties Jackson analysis JSON data Jackson serialize Java object Preface Json Data formats have developed rapidly in the past two years , Its claim is relatively XML Format has great benefits : ...

  8. SpringBoot About remote mutual calls between systems

    1.SpringBoot About remote mutual calls between systems May adopt RestTemplate To initiate Rest Http call , There are get.post Methods such as . 1.1 Remote tool class Use here Post The way , Refer to the following package ...

  9. Parcel Vs Webpack

    Born out of nowhere Parcel Recently, it has become another hot spot in the front-end circle , In just a few weeks, I got 13K Of Star. As a newcomer to the front-end construction tool Parcel Why can we get so much approval in a short time ? He and big brother Webpack What advantage does it have ...

  10. How to create Visual Studio 2017 RC Offline installer

    establish Visual Studio Offline installation plan for First, download the corresponding version of the executable , for example :vs_community.exe.vs_enterprise.exe or vs_professional stay cm ...