Search Unity

Huge fps drop with shader for texture combining

Discussion in 'Shaders' started by crol, Apr 18, 2015.

  1. crol

    crol

    Joined:
    Aug 6, 2013
    Posts:
    30
    I've got this shader for combining up to 4 textures in 1:

    Code (CSharp):
    1. Shader "Custom/TexCombinations" {
    2.  
    3.     Properties {
    4.         _Cutoff ("Cutoff", Range(0,1)) = 0.5        
    5.          _Color ("Main Color", Color) = (1,1,1,1)
    6.         _MainTex ("Tex", 2D)   = ""
    7.         _MainTex1 ("Tex1", 2D) = ""
    8.         _MainTex2 ("Tex2", 2D) = ""
    9.         _MainTex3 ("Tex3", 2D) = ""
    10.     }
    11.  
    12.     SubShader {
    13.    
    14.         Tags{ "Queue"="AlphaTest" "RenderType"="TransparentCutout" }
    15.        
    16.         LOD 200
    17.  
    18.         CGPROGRAM
    19.         #pragma surface surf Lambert alphatest:_Cutoff
    20.         sampler2D _MainTex;
    21.         fixed4 _Color;
    22.        
    23.         struct Input {    float2 uv_MainTex;   };
    24.        
    25.         void surf (Input IN, inout SurfaceOutput o) {
    26.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    27.             o.Albedo = c.rgb;  
    28.             o.Alpha = c.a;
    29.         }
    30.         ENDCG
    31.  
    32.         CGPROGRAM
    33.         #pragma surface surf Lambert alphatest:_Cutoff
    34.         sampler2D _MainTex1;
    35.         fixed4 _Color;
    36.        
    37.         struct Input {    float2 uv_MainTex;   };
    38.        
    39.         void surf (Input IN, inout SurfaceOutput o) {
    40.             fixed4 c = tex2D(_MainTex1, IN.uv_MainTex) * _Color;
    41.             o.Albedo = c.rgb;  
    42.             o.Alpha = c.a;
    43.         }
    44.         ENDCG
    45.        
    46.         CGPROGRAM
    47.         #pragma surface surf Lambert alphatest:_Cutoff
    48.         sampler2D _MainTex2;
    49.         fixed4 _Color;
    50.        
    51.         struct Input {    float2 uv_MainTex;   };
    52.        
    53.         void surf (Input IN, inout SurfaceOutput o) {
    54.             fixed4 c = tex2D(_MainTex2, IN.uv_MainTex) * _Color;
    55.             o.Albedo = c.rgb;  
    56.             o.Alpha = c.a;
    57.         }
    58.         ENDCG
    59.        
    60.         CGPROGRAM
    61.         #pragma surface surf Lambert alphatest:_Cutoff
    62.         sampler2D _MainTex3;
    63.         fixed4 _Color;
    64.        
    65.         struct Input {    float2 uv_MainTex;   };
    66.        
    67.         void surf (Input IN, inout SurfaceOutput o) {
    68.             fixed4 c = tex2D(_MainTex3, IN.uv_MainTex) * _Color;
    69.             o.Albedo = c.rgb;  
    70.             o.Alpha = c.a;
    71.         }
    72.         ENDCG
    73.  
    74.  
    75.     }
    76.  
    77.     Fallback "TransparentDiffuse"
    78. }
    Code (CSharp):
    1. Shader "TransparentDiffuse"
    2. {
    3.         Properties
    4.         {
    5.                 _Color ("Main Color", Color) = (1,1,1,1)
    6.                 _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    7.         }
    8.         SubShader
    9.         {
    10.                 Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    11.                 blend SrcAlpha OneMinusSrcAlpha
    12.              
    13.                 LOD 200
    14.                 ZWrite Off
    15.                 CGPROGRAM
    16.                 #pragma surface surf Lambert exclude_path:prepass
    17.              
    18.                 sampler2D _MainTex;
    19.                 fixed4 _Color;
    20.              
    21.                 struct Input
    22.                 {
    23.                         float2 uv_MainTex;
    24.                 };
    25.              
    26.                 void surf (Input IN, inout SurfaceOutput o)
    27.                 {
    28.                         fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    29.                         o.Albedo = c.rgb;
    30.                         o.Alpha = c.a;
    31.                 }
    32.                 ENDCG
    33.         }
    34.      
    35.      
    36.         SubShader
    37.         {
    38.                 Pass
    39.                 {
    40.                         Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    41.                         ZWrite Off
    42.                         Blend SrcAlpha OneMinusSrcAlpha
    43.                         Material
    44.                         {
    45.                                 Diffuse [_Color]
    46.                                 Ambient [_Color]    
    47.                         }
    48.                         Lighting On
    49.                         SetTexture [_MainTex]
    50.                         {
    51.                                 Combine texture * primary DOUBLE, texture * primary
    52.                         }
    53.                 }
    54.         }
    55. Fallback "VertexLit"
    56. }

    For this result (two planes. one with this shader):
    result.png
    result2.png

    Any idea about how to do this faster? Im noob at shading so I feel like doing something is wrong here.
     
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    You could get it a bit faster with CG/Frag instead of surface shader but it's probably not much faster. Essentially, you are bottlenecked by texture reads and from the lower screenshot, probably draw calls. In all, this is a terrible way to work.

    A better way may be a 4-texture vertex splat shader, where each vertex colour on the mesh dictates how much of that texture is shown. You can apply something like this to one large mesh, instead of your current approach on loads of little quads.
     
  3. zoran404

    zoran404

    Joined:
    Jan 11, 2015
    Posts:
    520
    @crol you do realize you can just add all of the textures in a single surface shader?
    Just use max() to get the brightest color...
     
  4. crol

    crol

    Joined:
    Aug 6, 2013
    Posts:
    30
    Could this run faster than using 4 additional "layers" of quads with cutout shader on each? (currently using this)

    Ive got procedural world but probably if I will split it to big chunks like 10x10 with splat shader this will run much faster cause 1 quad will replace 50...

    @zoran404 , @hippocoder thanks!
     
  5. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Well firstly we don't have profiler information so that would help. Secondly, if you combine all these into one large mesh and atlas the different texture combinations it might be fastest of all.