Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Question Performance of combining multiple textures in surface shader

Discussion in 'Shaders' started by Mitochondrion_LL, Jul 15, 2021.

  1. Mitochondrion_LL

    Mitochondrion_LL

    Joined:
    Apr 29, 2021
    Posts:
    3
    Dear all,

    I am a newbie in computer graphics and shader programming, here's my code for combining (concat, overlay) several 2d textures (they are all sprite sheets)

    Code (CSharp):
    1.             void surf(Input IN, inout SurfaceOutput o)
    2.             {
    3.                 fixed4 main = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    4.                 fixed4 outfit = tex2D(_OutFit, IN.uv_MainTex) * _Color;
    5.                 fixed4 bag = tex2D(_Bag, IN.uv_MainTex) * _Color;
    6.                 fixed4 head = tex2D(_Head, IN.uv_MainTex) * _Color;
    7.                 fixed4 hand = tex2D(_Hand, IN.uv_MainTex) * _Color;
    8.                 fixed4 back = tex2D(_Back, IN.uv_MainTex) * _Color;
    9.  
    10.                 fixed3 combine = lerp(main.rgb, outfit.rgb, outfit.a / 1);
    11.                 fixed3 combine1 = lerp(combine.rgb, bag.rgb, bag.a / 1);
    12.                 fixed3 combine2 = lerp(combine1.rgb, head.rgb, head.a / 1);
    13.                 fixed3 combine3 = lerp(combine2.rgb, hand.rgb, hand.a / 1);
    14.                 fixed3 combine4 = lerp(combine3.rgb, back.rgb, back.a / 1);
    15.  
    16.                 o.Albedo = combine4.rgb;
    17.                 o.Alpha = main.a + outfit.a + bag.a + head.a + hand.a + back.a;
    18.             }
    Based on the code, there are six sheets to combine (same size, same format, with perfect alignment) with certain orders. Right now this shader did what I want perfectly, but I am seeking a more efficient way to combine them.

    Previously I used several GameObjects, and each of them contains a sprite renderer to display different components. However, the old solution takes a lot of draw calls, especially after I enabled the sprite shadow.

    The game targets the mobile platform, after changing to the shader, it reduced a lot. However, I believe that I can still somehow optimize the shader code.

    Thanks for any suggestions. Cheers!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,255
    Not especially, no. That's about as optimal as you're going to get on a mobile device. Anything else you might try to do in the shader is just going to make it way, way more expensive. Even on desktop, there's not a ton more you can do.

    The "better" option would be to combine all the layers by rendering them to a render texture, and use that pre-combined single texture instead.
     
    Mitochondrion_LL likes this.
  3. Mitochondrion_LL

    Mitochondrion_LL

    Joined:
    Apr 29, 2021
    Posts:
    3
    Thank you bgolus! I will try your proposed solution.