Unity中Batching优化的GPU实例化整理总结


前言

我们在之前的文章中,实现了GPU实例化的支持,我们在这篇文章中来整理总结一下


一、GPU Instancing的支持

1、硬件支持

2、Shader支持

3、脚本支持


二、我们来顺着理一下GPU实例化的使用步骤

1、GPU实例化前的C#代码准备

2、在 appdata 和 v2f 中定义GPU实例化ID

3、在顶点着色 和 片元着色器 设置GPU Instance ID,使实例化对象顶点位置正确(设置后坐标变换矩阵就生效)

4、如果GPU实例化后,需要不同对象使用不同属性,Shader中GPU实例化怎么定义和使用属性。以及在C#脚本中使用材质属性块来修改材质属性


三、最终代码

请添加图片描述

Shader代码:

Shader "MyShader/P2_6_5"
{
    Properties
    {
        _Color("Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_instancing
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                //1、定义GPU实例化 ID
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                float3 worldPos : TEXCOORD4;
                //1、定义GPU实例化 ID
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };
            
	        UNITY_INSTANCING_BUFFER_START(prop)
	        UNITY_DEFINE_INSTANCED_PROP(fixed4,_Color)
	        UNITY_INSTANCING_BUFFER_END(prop)
            
            v2f vert (appdata v)
            {
	            //2、设置GPU实例化ID,使实例化对象顶点位置正确
                UNITY_SETUP_INSTANCE_ID(v);
                v2f o;
	            UNITY_TRANSFER_INSTANCE_ID(v, o);
                o.pos = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld,v.vertex);
                o.uv = v.uv;
               
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //2、设置GPU实例化ID,使实例化对象顶点位置正确
                UNITY_SETUP_INSTANCE_ID(i);
                return i.worldPos.y * 0.15 + UNITY_ACCESS_INSTANCED_PROP(prop,_Color);
            }
            ENDCG
        }
    }
}

C#代码:

using UnityEngine;

public class P2_6_5 : MonoBehaviour
{
    public GameObject Prefab;
    public int Count = 1;
    public int Range = 10;
    // Start is called before the first frame update
    void Start()
    {
        
        
        for (int i = 0;i < Count;i++)
        {
            Vector3 pos = Random.insideUnitCircle * Range;
            GameObject chair = Instantiate(Prefab,new Vector3(pos.x,0,pos.y),Quaternion.identity);
            Color color = new Color(Random.value,Random.value,Random.value);
            
            MaterialPropertyBlock prop = new MaterialPropertyBlock();
            prop.SetColor("_Color",color);
            chair.GetComponentInChildren<MeshRenderer>().SetPropertyBlock(prop);
        }
    }
}

  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
GPU实例化是一种在GPU上生成和渲染大量相似物体的技术。在UnityGPU实例化可以用于大规模的场景渲染,例如草地、树木、岩石等自然物体。 GPU实例化的实现方式是使用一个网格和一个材质,然后通过修改网格的变换矩阵来渲染大量相似的物体。在Unity,可以通过以下步骤来使用GPU实例化: 1. 创建一个网格对象,包含一个或多个子网格。 2. 创建一个材质对象,并将其设置为支持GPU实例化。 3. 在脚本,使用Graphics.DrawMeshInstanced来渲染实例化的网格对象。 4. 在渲染之前,需要将实例化的属性发送给GPU,例如变换矩阵、颜色等。 例如,以下代码演示如何在Unity使用GPU实例化: ```csharp public class InstancedObject : MonoBehaviour { public Mesh mesh; public Material material; public int instanceCount; private Matrix4x4[] matrices; private Vector4[] colors; private void Start() { matrices = new Matrix4x4[instanceCount]; colors = new Vector4[instanceCount]; for (int i = 0; i < instanceCount; i++) { matrices[i] = Matrix4x4.TRS(Random.insideUnitSphere * 10f, Quaternion.identity, Vector3.one); colors[i] = new Vector4(Random.value, Random.value, Random.value, 1f); } } private void Update() { for (int i = 0; i < instanceCount; i++) { matrices[i] = Matrix4x4.TRS(Random.insideUnitSphere * 10f, Quaternion.identity, Vector3.one); colors[i] = new Vector4(Random.value, Random.value, Random.value, 1f); } } private void OnRenderObject() { material.SetVectorArray("_Color", colors); Graphics.DrawMeshInstanced(mesh, 0, material, matrices, instanceCount); } } ``` 在这个例子,我们创建了一个InstancedObject类,并在Start方法初始化了变换矩阵和颜色数组。在Update方法,我们每帧更新变换矩阵和颜色数组,以模拟物体的运动。在OnRenderObject方法,我们将变换矩阵和颜色数组发送给GPU,并使用Graphics.DrawMeshInstanced方法渲染了实例化的网格对象。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠溪泽岸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值