GPU Instancing

// 1.渲染相同材质,仅使用少量drawCalls,适用于重复的建筑,植被,石头等
// 2.每个实例,可以有不同的参数,如位置,缩放,颜色等等
// 3.需勾选材质上的EnableInstancing,并且使用相关的宏,此时内部会自动执行instancing
// 4.可以使用SetPropertyBlock设置相关属性,达到同材质不同的效果
// 5.可以使用Graphics.DrawMesh....创建对象,达到同材质不同的效果

// tips:
// 1.unity会优先处理static batching,如果处理过sb,unity会禁用instancing,系统会建议禁用sb,在设置界面
// 2.unity处理instancing的优先级高于dynamic batching,如果处理过instance,会禁用这个mesh的动态批处理
// 3.Graphics.DrawMeshInstanced
// 有些因素可能会阻止对象自动instanced,比如材质变化,深度排序等
// 使用Graphics.DrawMeshInstanced可以每帧强制GPU instancing绘制这些物体,最多1023个。
// 4.Graphics.DrawMeshInstancedIndirect
// 无限制,适合PC用
// 5.UnityObjectToClipPos
// 当写shader时用UnityObjectToClipPos(v.vertex)而不是mul(UNITY_MATRIX_MVP,v.vertex)
// 尽管可以继续在instanced Shaders中正常使用UNITY_MATRIX_MVP,
// 但是UnityObjectToClipPos是把顶点位置从对象空间(object sapce)转换到裁剪空间(clip space)的最高效的方式。
// 6.Surface Shaders默认开启instancing varianats,除非指定noinstancing,其他shader定义#pragma multi_compile_instancing 
Shader "SimplestInstancedShader"
{
    Properties
    {
        _Color ("Color", Color) = (1, 1, 1, 1)

        [HDR]_EmissionColor ("EmissionColor", Color) = (0.0,0.0,0.0,0.0)
        _EmissionSpeed("EmissionSpeed",float) = 0
        _EmissionFadeIn("EmissionFadeIn",Range(0 , 1)) = 0
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_instancing // 使用设置unity生成instancing variants
            #include "UnityCG.cginc"

            // 假如_Color不作为instancing参数,一旦_Color值不一样时,就会构建新的drawcal
            //float4 _Color;

            struct appdata
            {
                float4 vertex : POSITION;
                // 如果你想在【顶点函数】中使用实例化参数,则需要在这里定义实例化id
                UNITY_VERTEX_INPUT_INSTANCE_ID  
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 color : TEXCOORD1;
                // 如果你想在【像素函数】中使用实例化参数,则需要在这里定义实例化id
                UNITY_VERTEX_INPUT_INSTANCE_ID 
            };

            // 每一帧的实例属性必须定义在这两个宏中间
            // 包装那些你想在不同实例中值不同的属性
            UNITY_INSTANCING_BUFFER_START(Props)
                // 指定类型和属性名,这些参数可以被外部修改
                UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
                UNITY_DEFINE_INSTANCED_PROP(half, _EmissionFadeIn)
                UNITY_DEFINE_INSTANCED_PROP(half, _EmissionSpeed)
                UNITY_DEFINE_INSTANCED_PROP(half4, _EmissionColor)
            UNITY_INSTANCING_BUFFER_END(Props)
           
            v2f vert(appdata v)
            {
                v2f o;
                // 如果你想在【顶点函数】中访问参数,则需要在这里使用UNITY_SETUP_INSTANCE_ID
                UNITY_SETUP_INSTANCE_ID(v);     
                // 如果你想在【像素函数】中使用实例化参数,则需要在这里传输参数    
                UNITY_TRANSFER_INSTANCE_ID(v, o);  

                o.vertex = UnityObjectToClipPos(v.vertex);
                // 在顶点阶段使用实例化参数
                float _EmissionFadeIn_Instance = UNITY_ACCESS_INSTANCED_PROP(Props, _EmissionFadeIn);
                float _EmissionSpeed_Instance = UNITY_ACCESS_INSTANCED_PROP(Props, _EmissionSpeed);
                float4 _EmissionColor_Instance = UNITY_ACCESS_INSTANCED_PROP(Props, _EmissionColor);
                o.color = ( _EmissionFadeIn_Instance + ( ( 1.0 - abs( sin( ( _Time.y * _EmissionSpeed_Instance ) ) ) ) * ( 1.0 - _EmissionFadeIn_Instance ) ) ) * _EmissionColor_Instance;
                return o;
            }
           
            float4 frag(v2f i) : SV_Target
            {
                // 如果你想在【像素函数】中访问参数,则需要在这里使用UNITY_SETUP_INSTANCE_ID
                UNITY_SETUP_INSTANCE_ID(i);     
                // 使用实例化id在实例化数据数组中访问参数
                //float4 color = _Color;
                float4 color = UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
                float4 col = i.color * color;
                return col;
            }
            ENDCG
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值