Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Help Wanted: Combining 2 off-the-shelf Shaders: surf and frag ones

Discussion in 'Shaders' started by zrabrams, Oct 6, 2021.

  1. zrabrams

    zrabrams

    Joined:
    Jun 2, 2020
    Posts:
    2
    Hello,
    I have 2 shaders that I've found online - each works well independently - but I want to combine them, and cen't get it to work.
    It should be pretty simple: The first is a basic Chroma Key shader, and the second is a Parallax shader (using a mask).
    I have very little experience with shaders, but think that this should be do-able. I've searched online for over a day, and mostly found answers that this isn't possible, since Unity can't run another shader once you have a "surf" shader. I've tried separate passes, code blocks, subshaders - nothing works.

    The first shader is:

    Code (CSharp):
    1. Shader "Custom/shaderCK_1"
    2. // https://forum.unity.com/threads/chroma-key-in-unity-5.359119/?_ga=2.114736389.341870837.1608642344-105392366.1584566490
    3. {
    4.     Properties
    5.     {
    6.         //_Color ("Color", Color) = (1,1,1,1)
    7.         _MainTex ("Base (RGB)", 2D) = "white" {}
    8.         //_Glossiness ("Smoothness", Range(0,1)) = 0.5
    9.         //_Metallic ("Metallic", Range(0,1)) = 0.0
    10.         _thresh("Threshold", Range(0, 16)) = 0.65
    11.         _slope ("Slope", Range (0, 1)) = 0.63
    12.         _keyingColor ("KeyingColour", Color) = (1,1,1,1)
    13.     }
    14.     SubShader
    15.         {
    16.             Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
    17.             LOD 100
    18.  
    19.             Lighting Off
    20.             ZWrite Off
    21.             AlphaTest Off
    22.             Blend SrcAlpha OneMinusSrcAlpha
    23.  
    24.             Pass {
    25.             CGPROGRAM
    26.             #pragma vertex vert_img
    27.             #pragma fragment frag
    28.             #pragma fragmentoption ARB_precision_hint_fastest
    29.  
    30.         sampler2D _MainTex;
    31.         float3 _keyingColor;
    32.         float _thresh; //0.8
    33.         float _slope; //0.2
    34.  
    35.         #include "UnityCG.cginc"
    36.  
    37.         float4 frag(v2f_img i) : COLOR {
    38.         float3 input_color = tex2D(_MainTex,i.uv).rgb;  // * _Color;
    39.         float d = abs(length(abs(_keyingColor.rgb - input_color.rgb)));
    40.         float edge0 = _thresh * (1 - _slope);
    41.         float alpha = smoothstep(edge0, _thresh, d);
    42.         return float4(input_color, alpha);
    43.  
    44.  
    45.         }
    46.  
    47.             ENDCG
    48.         }
    49.         }
    50.     FallBack "Unlit/Texture"
    51. }
    52.  
    The second is just a modification of the standard Sprites-Diffuse shader:
    Code (CSharp):
    1. Shader "Sprites/DiffuseP"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    8.         [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
    9.         [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
    10.         [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
    11.         [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
    12.         // add these 2 lines:
    13.         _HeightTex("Heightmap (R)", 2D) = "gray" {}
    14.         _Scale("Scale", Vector) = (0,0,0,0)
    15.     }
    16.  
    17.     SubShader
    18.     {
    19.         Tags
    20.         {
    21.             "Queue"="Transparent"
    22.             "IgnoreProjector"="True"
    23.             "RenderType"="Transparent"
    24.             "PreviewType"="Plane"
    25.             "CanUseSpriteAtlas"="True"
    26.         }
    27.  
    28.         Cull Off
    29.         Lighting Off
    30.         ZWrite Off
    31.         Blend One OneMinusSrcAlpha
    32.  
    33.         CGPROGRAM
    34.         #pragma surface surf Lambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing
    35.         #pragma multi_compile _ PIXELSNAP_ON
    36.         #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
    37.         #include "UnitySprites.cginc"
    38.  
    39.         // add these two variables
    40.         sampler2D _HeightTex;
    41.         fixed2 _Scale;
    42.  
    43.         struct Input
    44.         {
    45.             float2 uv_MainTex;
    46.             fixed4 color;
    47.         };
    48.  
    49.         void vert (inout appdata_full v, out Input o)
    50.         {
    51.             v.vertex = UnityFlipSprite(v.vertex, _Flip);
    52.  
    53.             #if defined(PIXELSNAP_ON)
    54.             v.vertex = UnityPixelSnap (v.vertex);
    55.             #endif
    56.  
    57.             UNITY_INITIALIZE_OUTPUT(Input, o);
    58.             o.color = v.color * _Color * _RendererColor;
    59.         }
    60.  
    61.         void surf (Input IN, inout SurfaceOutput o)
    62.         {
    63.             // Displacement -- add these lines
    64.             fixed height = tex2D(_HeightTex, IN.uv_MainTex).r;
    65.             fixed2 displacement = _Scale * ((height - 0.5) * 2);
    66.             fixed4 c = SampleSpriteTexture(IN.uv_MainTex - displacement) * IN.color;
    67.             //remove the next one?
    68.             //fixed4 c = SampleSpriteTexture (IN.uv_MainTex) * IN.color;
    69.             o.Albedo = c.rgb * c.a;
    70.             o.Alpha = c.a;
    71.         }
    72.         ENDCG
    73.     }
    74.  
    75. Fallback "Transparent/VertexLit"
    76. }
    *EDIT - mistakenly copy-pasted the same shader twice

    I'd be happy for some help!
     
    Last edited: Oct 6, 2021
  2. Shane_Michael

    Shane_Michael

    Joined:
    Jul 8, 2013
    Posts:
    158
    You've posted the same shader twice, but I expect it would be possible to add this to an existing surface shader. Just convert the frag shader block to a function, call it on the value you sample from the albedo/diffuse texture, and use the return value as the alpha value for the surface shader.
     
  3. zrabrams

    zrabrams

    Joined:
    Jun 2, 2020
    Posts:
    2
    Eureka!
    Not that I actually did what you said, but you gave me the push to try and put the functions WITHIN the "surf" section.

    And I spent 4 hours trying to get it to work, until finally realizing that there was one more modification needed: The Chroma Key requires the line
    Blend SrcAlpha OneMinusSrcAlpha
    which needed to replace the original (Sprite/Diffuse)
    Blend One OneMinusSrcAlpha

    And then it works!
    Full code:
    Code (CSharp):
    1. Shader "Custom/GreenParallax"
    2. // https://forum.unity.com/threads/chroma-key-in-unity-5.359119/?_ga=2.114736389.341870837.1608642344-105392366.1584566490
    3. {
    4.     Properties
    5.     {
    6.         [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    7.         _Color("Tint", Color) = (1,1,1,1)
    8.         [MaterialToggle] PixelSnap("Pixel snap", Float) = 0
    9.         [HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1)
    10.         [HideInInspector] _Flip("Flip", Vector) = (1,1,1,1)
    11.         [PerRendererData] _AlphaTex("External Alpha", 2D) = "white" {}
    12.         [PerRendererData] _EnableExternalAlpha("Enable External Alpha", Float) = 0
    13.         // add these 2 lines:
    14.         _HeightTex("Heightmap (R)", 2D) = "gray" {}
    15.         _Scale("Scale", Vector) = (0,0,0,0)
    16.  
    17.         // add these 3 from the GreenScreen:
    18.         //_MainTex2("Base (RGB)", 2D) = "white" {}
    19.         _thresh("Threshold", Range(0, 16)) = 0.65
    20.         _slope("Slope", Range(0, 1)) = 0.63
    21.         _keyingColor("KeyingColour", Color) = (1,1,1,1)
    22.     }
    23.  
    24.         SubShader
    25.         {
    26.             Tags
    27.             {
    28.             "Queue" = "Transparent"
    29.             "IgnoreProjector" = "True"
    30.             "RenderType" = "Transparent"
    31.             "PreviewType" = "Plane"
    32.             "CanUseSpriteAtlas" = "True"
    33.             }
    34.  
    35.             Cull Off
    36.             Lighting Off
    37.             ZWrite Off
    38.             //Blend One OneMinusSrcAlpha  // NEEDS TO BE TURNED OFF!!!
    39.             //these are from the GreenScreen:
    40.             LOD 100
    41.             AlphaTest Off
    42.             Blend SrcAlpha OneMinusSrcAlpha
    43.  
    44.  
    45.                 CGPROGRAM
    46.                     #pragma surface surf Lambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing
    47.                     #pragma multi_compile _ PIXELSNAP_ON
    48.                     #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
    49.                     #include "UnitySprites.cginc"
    50.    
    51.                     // add these two variables for Parallax
    52.                     sampler2D _HeightTex;
    53.                     fixed2 _Scale;
    54.  
    55.                     ////Chroma additions:
    56.                     float3 _keyingColor;
    57.                     float _thresh; //0.8
    58.                     float _slope; //0.2
    59.                     #include "UnityCG.cginc"
    60.  
    61.                     struct Input
    62.                     {
    63.                         float2 uv_MainTex;
    64.                         fixed4 color;
    65.                         //float2 _MainTex;
    66.                     };
    67.  
    68.                     void vert(inout appdata_full v, out Input o)
    69.                     {
    70.                         v.vertex = UnityFlipSprite(v.vertex, _Flip);
    71.  
    72.                         #if defined(PIXELSNAP_ON)
    73.                                     v.vertex = UnityPixelSnap(v.vertex);
    74.                         #endif
    75.  
    76.                         UNITY_INITIALIZE_OUTPUT(Input, o);
    77.                         o.color = v.color * _Color * _RendererColor;
    78.                     }
    79.  
    80.                     void surf(Input IN, inout SurfaceOutput o)
    81.                     {
    82.                         // Displacement -- add thes lines
    83.                         fixed height = tex2D(_HeightTex, IN.uv_MainTex).r;
    84.                         fixed2 displacement = _Scale * ((height - 0.5) * 2);
    85.                         fixed4 c = SampleSpriteTexture(IN.uv_MainTex - displacement) *IN.color;
    86.  
    87.                         //remove the next one?
    88.                         //fixed4 c = SampleSpriteTexture (IN.uv_MainTex) * IN.color;
    89.  
    90.                         // now try and manually insert the Greenscreen functionality
    91.                         float d = abs(length(abs(_keyingColor.rgb - c.rgb)));
    92.                         float edge0 = _thresh * (1 - _slope);
    93.                         float alpha = smoothstep(edge0, _thresh, d);
    94.  
    95.                         o.Albedo = c.rgb*c.a;
    96.                         o.Alpha = alpha; //c.a;
    97.                     }
    98.                     ENDCG
    99.  
    100.  
    101.    
    102.  
    103.         }
    104.             Fallback "Transparent/VertexLit"
    105. }