Search Unity

Adding Instancing Support to Mobile/VertexLit Shader?

Discussion in 'Shaders' started by hungrybelome, Apr 28, 2017.

  1. hungrybelome

    hungrybelome

    Joined:
    Dec 31, 2014
    Posts:
    336
    Hi,

    I tried adding instancing support to the Mobile/VertexLit (Directional Lights Only) by adding this pragma/code:

    Code (CSharp):
    1. #pragma multi_compile_instancing
    2.  
    3. ...
    4.  
    5. UNITY_TRANSFER_INSTANCE_ID (v, o);
    and while it has improved the batch count, the improvement is still less than the Standard shader.

    STATS (120 GameObjects):
    Standard Shader (Instancing Enabled): 10 Batches
    Custom Mobile/Vertex-Lit Shader (Instancing Enabled): ~84 Batches
    Simplest Instanced Shader (Instancing Enabled): 10 Batches
    No instancing enabled: ~157 batches

    I've tried copying the relevant parts from the example instanced shader with no effect. I have also striped down that example shader as much as possible, to see what parts might be responsible for the lesser batch count.

    Is the fog/lightmap settings somehow interferring with my custom mobile/vertexlit variant? I'm guessing not, since the Standard shader has those features yet handles the instancing as well as the simple shader.

    Any help would be greatly appreciated!

    Here is my Mobile/VertexLit (Directional Lights Only) with instancing added:

    Code (CSharp):
    1. Shader "Custom/Mobile/Instanced/VertexLit (Only Directional Lights)" {
    2.     Properties {
    3.         _MainTex ("Base (RGB)", 2D) = "white" {}
    4.     }
    5.     SubShader {
    6.         Tags { "RenderType"="Opaque" }
    7.         LOD 80
    8.  
    9.     Pass {
    10.         Name "FORWARD"
    11.         Tags { "LightMode" = "ForwardBase" }
    12.  
    13.         CGPROGRAM
    14.         #pragma vertex vert_surf
    15.         #pragma fragment frag_surf
    16.         #pragma multi_compile_fwdbase
    17.         #pragma multi_compile_fog
    18.         #pragma multi_compile_instancing
    19.         #include "HLSLSupport.cginc"
    20.         #include "UnityCG.cginc"
    21.         #include "Lighting.cginc"
    22.         #include "AutoLight.cginc"
    23.  
    24.         inline float3 LightingLambertVS (float3 normal, float3 lightDir)
    25.         {
    26.             fixed diff = max (0, dot (normal, lightDir));          
    27.             return _LightColor0.rgb * diff;
    28.         }
    29.  
    30.         sampler2D _MainTex;
    31.  
    32.         struct Input {
    33.             float2 uv_MainTex;
    34.         };
    35.  
    36.         void surf (Input IN, inout SurfaceOutput o) {
    37.             half4 c = tex2D (_MainTex, IN.uv_MainTex);
    38.             o.Albedo = c.rgb;
    39.             o.Alpha = c.a;
    40.         }
    41.         struct v2f_surf {
    42.           float4 pos : SV_POSITION;
    43.           float2 pack0 : TEXCOORD0;
    44.           #ifndef LIGHTMAP_ON
    45.           fixed3 normal : TEXCOORD1;
    46.           #endif
    47.           #ifdef LIGHTMAP_ON
    48.           float2 lmap : TEXCOORD2;
    49.           #endif
    50.           #ifndef LIGHTMAP_ON
    51.           fixed3 vlight : TEXCOORD2;
    52.           #endif
    53.           LIGHTING_COORDS(3,4)
    54.           UNITY_FOG_COORDS(5)
    55.           UNITY_VERTEX_OUTPUT_STEREO
    56.           UNITY_VERTEX_INPUT_INSTANCE_ID
    57.         };
    58.         float4 _MainTex_ST;
    59.  
    60.         v2f_surf vert_surf (appdata_full v)
    61.         {
    62.             v2f_surf o;
    63.             UNITY_SETUP_INSTANCE_ID(v);
    64.             UNITY_TRANSFER_INSTANCE_ID (v, o);
    65.             UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    66.             o.pos = UnityObjectToClipPos(v.vertex);
    67.             o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
    68.             #ifdef LIGHTMAP_ON
    69.             o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
    70.             #endif
    71.             float3 worldN = UnityObjectToWorldNormal(v.normal);
    72.             #ifndef LIGHTMAP_ON
    73.             o.normal = worldN;
    74.             #endif
    75.             #ifndef LIGHTMAP_ON
    76.  
    77.             o.vlight = ShadeSH9 (float4(worldN,1.0));
    78.             o.vlight += LightingLambertVS (worldN, _WorldSpaceLightPos0.xyz);
    79.  
    80.             #endif
    81.             TRANSFER_VERTEX_TO_FRAGMENT(o);
    82.             UNITY_TRANSFER_FOG(o,o.pos);
    83.             return o;
    84.         }
    85.  
    86.         fixed4 frag_surf (v2f_surf IN) : SV_Target
    87.         {
    88.             Input surfIN;
    89.             surfIN.uv_MainTex = IN.pack0.xy;
    90.             SurfaceOutput o;
    91.             o.Albedo = 0.0;
    92.             o.Emission = 0.0;
    93.             o.Specular = 0.0;
    94.             o.Alpha = 0.0;
    95.             o.Gloss = 0.0;
    96.             #ifndef LIGHTMAP_ON
    97.             o.Normal = IN.normal;
    98.             #else
    99.             o.Normal = 0;
    100.             #endif
    101.             surf (surfIN, o);
    102.             fixed atten = LIGHT_ATTENUATION(IN);
    103.             fixed4 c = 0;
    104.             #ifndef LIGHTMAP_ON
    105.             c.rgb = o.Albedo * IN.vlight * atten;
    106.             #endif
    107.             #ifdef LIGHTMAP_ON
    108.             fixed3 lm = DecodeLightmap (UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.lmap.xy));
    109.             #ifdef SHADOWS_SCREEN
    110.             c.rgb += o.Albedo * min(lm, atten*2);
    111.             #else
    112.             c.rgb += o.Albedo * lm;
    113.             #endif
    114.             c.a = o.Alpha;
    115.             #endif
    116.             UNITY_APPLY_FOG(IN.fogCoord, c);
    117.             UNITY_OPAQUE_ALPHA(c.a);
    118.             return c;
    119.         }
    120.  
    121.         ENDCG
    122.         }
    123.     }
    124.  
    125. FallBack "Mobile/VertexLit"
    126. }

    Here is the striped-down example instancing shader I am comparing it to:

    Code (CSharp):
    1. // Upgrade NOTE: replaced 'UNITY_INSTANCE_ID' with 'UNITY_VERTEX_INPUT_INSTANCE_ID'
    2.  
    3. Shader "Custom/SimplestInstancedShader"
    4. {
    5.     Properties
    6.     {
    7.         _Color ("Color", Color) = (1, 1, 1, 1)
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags { "RenderType"="Opaque" }
    13.         LOD 100
    14.  
    15.         Pass
    16.         {
    17.             CGPROGRAM
    18.             #pragma vertex vert
    19.             #pragma fragment frag
    20.             #pragma multi_compile_instancing
    21.             #include "UnityCG.cginc"
    22.  
    23.             struct appdata
    24.             {
    25.                 float4 vertex : POSITION;
    26.             };
    27.  
    28.             struct v2f
    29.             {
    30.                 float4 vertex : SV_POSITION;
    31.             };
    32.  
    33.             v2f vert (appdata v)
    34.             {
    35.                 v2f o;
    36.  
    37.                 o.vertex = UnityObjectToClipPos (v.vertex);
    38.                 return o;
    39.             }
    40.  
    41.             fixed4 frag (v2f i) : SV_Target
    42.             {
    43.                 return (0, 0, 0, 1);
    44.             }
    45.             ENDCG
    46.         }
    47.     }
    48. }
    49.  
    Thank you!
     
    Opeth001 likes this.
  2. eron82

    eron82

    Joined:
    Mar 10, 2017
    Posts:
    83
    Have you fixed it?
     
    Opeth001 likes this.