InstancedSurfaceShader

本文介绍了Unity中的GPU实例化技术,该技术可在场景中有大量相同材质的物体时减少DrawCall数量,提高渲染效率。文中详细讲解了如何在Shader中启用GPU实例化,包括必要的预处理器指令和宏使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

官网:https://docs.unity3d.com/Manual/GPUInstancing.html.

原文:http://hololens8.cn/thread-7463-1-1.html

Unity5.4 Beta版本中引入了一种新的Draw Call Batching方式——GPU Instancing。当场景中有大量使用相同材质和网格的物体时,通过GPU Instancing可以大幅降低Draw Call数量。本文将由Unity官方开发工程师蔡元星,为大家简单介绍GPU Instancing的原理并引导读者修改已有的Shader来开启Instancing

multi_compile_instancing会使你的Shader生成两个Variant,其中一个定义了Shader关键字INSTANCING_ON,另外一个没有定义此关键字

除了这个#pragma指令,下面所列其他的修改都是使用了在UnityInstancing.cginc里定义的宏(此cginc文件位于Unity_Install_Dir\Editor\Data\CGIncludes)。取决于关键字INSTANCING_ON是否被定义,这些宏将展开为不同的代码。

 

使用Instancing的限制

·         下列情况不能使用Instancing

·         使用Lightmap的物体

·         受不同Light Probe / Reflection Probe影响的物体

·         使用包含多个PassShader的物体,只有第一个Pass可以Instancing前向渲染时,受多个光源影响的物体只有Base Pass可以instancingAdd Passes不行

 另外,由于Constant Buffer的尺寸限制,一个Instanced Draw Call能画的物体数量是有上限的(参见UnityInstancing.cginc中的UNITY_MAX_INSTANCE_COUNT



最后需要再次强调的是,InstancingShader上有额外的开销,并不是总能提高帧率。永远要以实际Profiling的结果为准!

 

Shader "SimplestInstancedShader"
{
    Properties
    {
        _Color ("Color"Color) = (1111)
    }

    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;
                UNITY_INSTANCE_ID    //用于在Vertex Shader输入 / 输出结构中定义一个语义为SV_InstanceID的元素。 
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                UNITY_INSTANCE_ID
            };
            //UNITY_INSTANCING_CBUFFER_START(name) / UNITY_INSTANCING_CBUFFER_END
            //每个Instance独有的属性必须定义在一个遵循特殊命名规则的Constant Buffer中。使用这对宏来定义这些Constant Buffer“name”参数可以是任意字符串。
            UNITY_INSTANCING_CBUFFER_START (MyProperties)
            //定义一个具有特定类型和名字的每个Instance独有的Shader属性。这个宏实际会定义一个Uniform数组。
            UNITY_DEFINE_INSTANCED_PROP (float4, _Color)
            UNITY_INSTANCING_CBUFFER_END
           
            v2f vert (appdata v)
            {
                v2f o;
                //Instance IDShader函数里也能够被访问到
                UNITY_SETUP_INSTANCE_ID (v);
                //Vertex Shader中把Instance ID从输入结构拷贝至输出结构中
                UNITY_TRANSFER_INSTANCE_ID (v, o);
                o.vertex = UnityObjectToClipPos (v.vertex);
                return o;
            }
           
            fixed4 frag (v2f i) : SV_Target
            {
                UNITY_SETUP_INSTANCE_ID (i);
                //访问每个Instance独有的属性。这个宏会使用Instance ID作为索引到Uniform数组中去取当前Instance对应的数据。
                return UNITY_ACCESS_INSTANCED_PROP (_Color);
            }
            ENDCG
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值