Search Unity

Multiple Textures being applied to a Vertex shader with an alpha cutout on one texture

Discussion in 'Shaders' started by Galactic_Muffin, Jan 26, 2020.

  1. Galactic_Muffin

    Galactic_Muffin

    Joined:
    Aug 14, 2013
    Posts:
    67
    Hello I am just learning shaders atm and it would seem most of the shader tutorials out there are surface shaders. However I'm trying to create a Vertex shader in this case because my scene has no lights and is meant for low end devices.

    I would like to add multiple textures using multiple UV sets in this shader. I followed this tutorial for a surface shader but obviously somethings will be different for me:


    This is what i have, i just don't really know where to go from here and my research so far hasn't come up with a clear answer.

    Code (CSharp):
    1. Shader "Unlit/unlit_colorDoubleTexture2"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("Albedo (RGB)", 2D) = "white" {}
    6.         _Color("Main Color", Color) = (1,1,1,1)
    7.         _SecondTex("Albedo (RGB)", 2D) = "white" {}
    8.         _Color2("Second Color", Color) = (1,1,1,1)
    9.         _SplashTex("Albedo (RGB)", 2D) = "white" {}
    10.     }
    11.         SubShader
    12.     {
    13.         Tags{ "RenderType" = "Opaque" }
    14.         LOD 100
    15.  
    16.         Pass
    17.         {
    18.         CGPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.             // make fog work
    22.             #pragma multi_compile_fog
    23.  
    24.             #include "UnityCG.cginc"
    25.  
    26.             struct appdata
    27.             {
    28.                 float4 vertex : POSITION;
    29.                 float2 uv : TEXCOORD0;
    30.                 float2 uv2 : TEXCOORD1;
    31.             };
    32.  
    33.             struct v2f
    34.             {
    35.                 float2 uv : TEXCOORD0;
    36.                 float2 uv2 : TEXCOORD1;
    37.                 UNITY_FOG_COORDS(1)
    38.                 float4 vertex : SV_POSITION;
    39.             };
    40.  
    41.                 sampler2D _MainTex;
    42.                 sampler2D _SecondTex;
    43.                 sampler2D _SplashTex;
    44.                 float4 _MainTex_ST;
    45.                 float4 _SecondTex_ST;
    46.                 float4 _SplashTex_ST;
    47.                 float4 _Color;
    48.  
    49.             v2f vert(appdata v)
    50.             {
    51.                 v2f o;
    52.                 o.vertex = UnityObjectToClipPos(v.vertex);
    53.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    54.                 o.uv2 = TRANSFORM_TEX(v.uv2, _SecondTex);
    55.                 UNITY_TRANSFER_FOG(o,o.vertex);
    56.                 return o;
    57.             }
    58.  
    59.             fixed4 frag(v2f i) : SV_Target
    60.             {
    61.                 // sample the texture
    62.                 fixed4 MainTextureColor = tex2D(_MainTex, i.uv) * _Color * 2;
    63.                 fixed4 SecondTextureColor = tex2D(_MainTex, i.uv) * _Color * 2;
    64.                 fixed4 SplashTextureColor = tex2D(_MainTex, i.uv) * _Color * 2;
    65.                 fixed4 c = SplashTextureColor;
    66.                 fixed4 col;
    67.                 col = (MainTextureColor.rgb * SplashTextureColor.rgb + SecondTextureColor * (1 - SplashTextureColor.rgb)) * _Color;
    68.  
    69.                 // apply fog
    70.                 UNITY_APPLY_FOG(i.fogCoord, MainTextureColor);
    71.                 return col;
    72.             }
    73.         ENDCG
    74.         }
    75.     }
    76. }
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    What's the problem you're running into?
     
  3. Galactic_Muffin

    Galactic_Muffin

    Joined:
    Aug 14, 2013
    Posts:
    67
    it gives me the error:
    Code (CSharp):
    1. Shader error in 'Unlit/unlit_colorDoubleTexture2': cannot implicitly convert from 'const float3' to 'half4' at line 67 (on d3d11)
    which if this were C# i know what that means but in this came i assume it has something to do with the fact that im following a tutorial for the math in a Surface function rather than a Fixed4 Frag.
    line 67:
    Code (CSharp):
    1. col = (MainTextureColor.rgb * SplashTextureColor.rgb + SecondTextureColor * (1 - SplashTextureColor.rgb)) * _Color;
    it would be nice if i could find some more solid and in depth tutorials for everything vertex shader related but that's proving more difficult than i thought. if you happen to know of any good ones to follow that would help too :)
     
  4. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    Thinking from a C# perspective, the values you're combining in the parenthesis there are Vector3, while the
    _Color
    you're trying to multiply by is Vector4 and the
    col
    you're assigning to is Vector4 as well. There is one value in the parenthesis that is Vector4 too though (SecondTextureColor). So imagine how that would throw errors in C#. Shader code can be good at expanding single values into larger dimension vectors, but not generally from one vector to a bigger one.

    Something like this would be what you want:
    Code (CSharp):
    1. col.rgb = (MainTextureColor.rgb * SplashTextureColor.rgb + SecondTextureColor.rgb * (1 - SplashTextureColor.rgb));
    2. col *= _Color; //We want to utilize the Alpha chanel adjustment in your _Color tint as well.
    If you don't care about having _Color adjust the Alpha value of your overall color, then simply put it back in the previous line and make it _Color.rgb so it's the same vector dimension as the rest of the math there.
     
    bgolus likes this.
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    To add to that, the error message is warning about casting from a
    const float3 to a half4
    . The
    const
    ,
    float
    , and
    half
    parts of that line are all red herrings as you can cast from a
    float
    to a
    half
    or vise versa without an issue (though there is a cost on mobile). Also it might be confusing it's complaining about a
    half
    when there aren't any in the shader, but that's because almost nothing supports
    fixed
    anymore so it just ends up as an alias for
    half
    .

    Really the only thing that matters is, as @Invertex beat me to explaining, you're trying to cast a 3 component vector to a 4 component vector, and there's no valid way to do that. Somewhat nice / annoying, on Windows casting from 4 components to 3 components (i.e.:
    float3 foo = float4(1,2,3,4);
    ) is accepted as it just throws out the fourth component, that will error on most mobile devices, consoles, and MacOS. Nice because that's usually what you want, annoying because shaders you write using Windows might crash on every other platform and sometimes it really was done in error.
     
  6. Galactic_Muffin

    Galactic_Muffin

    Joined:
    Aug 14, 2013
    Posts:
    67
    Thanks so much for the replies guys and help, it worked out great, The windows and lights now illuminate! :D



    I had one other question however, for this shader i used the multiple TEXCOORDs available

    Code (CSharp):
    1.                 float2 uv : TEXCOORD0;
    2.                 float2 uv2 : TEXCOORD1;
    3.                 float2 uv3 : TEXCOORD2;
    I noticed after reading older shader tutorials that unity only supported up to 2 TEXCOORDs however it was bumped up to 7 or 8 now. I am using 3 in this shader and i was just curious if there were any performance issues that i should be concerned about when using multiple TEXCOORDs especially on mobile devices?
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Is there a performance difference between using 1 vs 3 uvs? Yes, of course. It's more data being moved around, thus more work for the GPU. Is it a "performance issue" worthy of concern? Not remotely, especially with a relatively simple shader like this. It'll be a concern if you're already maxing out the GPU in other ways.
     
    Galactic_Muffin likes this.
  8. Galactic_Muffin

    Galactic_Muffin

    Joined:
    Aug 14, 2013
    Posts:
    67
    Thanks for the reply! I knew it would cause more work for the GPU to an extent I just wasn't sure of the severity of it. the fact that unity only supported 2 TEXCOORDs in the past is what had me suspicious as to the reason and my hunch was that it was expensive.

    This is good to know, however! I was planning on optimizing this shader further and hopefully condensing it down to using just 2 TEXCOORD inputs but sounds like i shouldn't worry about this unless I notice some performance issues.

    Thanks again!
     
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Unity has supported more than 2 uv sets since Unity 5.0’s release in early 2015.
     
    JPFly likes this.