利用GPU Instance 配合PropertyBlock优化DrawCall

GPU Instance

1.未开启GPU Instance:
利用GPU Instance 配合PropertyBlock优化DrawCall_第1张图片
2.开启GPU Instance:
利用GPU Instance 配合PropertyBlock优化DrawCall_第2张图片

Shader "Shader_InstanceTest"{
	Properties{
		_Diffuse("Diffuse", Color) = (1,1,1,1)
	}

	SubShader{
		Pass{
			Tags {"LightMode" = "ForwardBase"}
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "Lighting.cginc"
			#pragma multi_compile_instancing
			#include "UnityCG.cginc"

			struct a2v {
				float4 vertex: POSITION;
				float3 normal: NORMAL;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			struct v2f {
				float4 pos: SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			UNITY_INSTANCING_CBUFFER_START(MyProperties)
			UNITY_DEFINE_INSTANCED_PROP(fixed4, _Diffuse)
			UNITY_INSTANCING_CBUFFER_END

			v2f vert(a2v v) {
				v2f o;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				o.pos = UnityObjectToClipPos(v.vertex);
				o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
				return o;
			}

			fixed4 frag(v2f i) : SV_TARGET{
				UNITY_SETUP_INSTANCE_ID(i);
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
				fixed3 diffuse = _LightColor0.rgb * UNITY_ACCESS_INSTANCED_PROP(_Diffuse).rgb * saturate(dot(worldNormal, worldLightDir));
				fixed3 color = ambient + diffuse;
				return fixed4(color, 1.0);
			}

			ENDCG
		}
	}
}

PropertyBlock

1.使用propertyBlock更换颜色
利用GPU Instance 配合PropertyBlock优化DrawCall_第3张图片
2.使用材质更换颜色
利用GPU Instance 配合PropertyBlock优化DrawCall_第4张图片

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PropertyBlockTest : MonoBehaviour
{

    public GameObject template;
    private List list = new List();

    void Start()
    {
        CreateGoList();
    }

    private void CreateGoList()
    {
        for (int i = 0; i < 100; i++)
        {
            GameObject go = Instantiate(template);
            go.transform.localPosition = new Vector3(Random.Range(0f, 10f), Random.Range(0f, 10f), Random.Range(0f, 10f));
            list.Add(go);
        }
    }

    private void DestoryGoList()
    {
        for (int i = 0; i < list.Count; i++)
        {
            GameObject.Destroy(list[i]);
        }
        list.Clear();
    }

    private void OnGUI()
    {
        if (GUI.Button(new Rect(10, 150, 120, 40), "ByMaterial"))
        {
            for (int i = 0; i < list.Count; i++)
            {
                Material mat = list[i].GetComponentInChildren().material;
                mat.SetColor("_Diffuse", new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f)));
            }
        }
        else if (GUI.Button(new Rect(10, 250, 120, 40), "ByPropertyBlock"))
        {
            for (int i = 0; i < list.Count; i++)
            {
                MaterialPropertyBlock block = new MaterialPropertyBlock();
                list[i].GetComponentInChildren().GetPropertyBlock(block);
                block.SetColor("_Diffuse", new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f)));
                list[i].GetComponentInChildren().SetPropertyBlock(block);
            }
        }
        else if (GUI.Button(new Rect(10, 350, 120, 40), "Reset"))
        {
            DestoryGoList();
            CreateGoList();
        }
    }

}

Demo地址: https://download.csdn.net/download/piratecode/11904599

你可能感兴趣的:(Unity3D)