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

How add support to alpha on this shader ?

Discussion in 'Shaders' started by mcunha98, Sep 9, 2017.

  1. mcunha98

    mcunha98

    Joined:
    Jun 13, 2010
    Posts:
    261
    I got this shader from asset store, but need to change it to support alpha, it is possible someone help me ?


    Shader "Toon/Lit" {
    Properties {
    _Color ("Main Color", Color) = (0.5,0.5,0.5,1)
    _MainTex ("Base", 2D) = "white" {}
    _Ramp ("Ramp", 2D) = "gray" {}
    }

    SubShader {
    Tags { "RenderType"="Opaque" }
    LOD 200

    CGPROGRAM
    #pragma surface surf ToonRamp

    sampler2D _Ramp;

    // custom lighting function that uses a texture ramp based
    // on angle between light direction and normal
    #pragma lighting ToonRamp exclude_path:prepass
    inline half4 LightingToonRamp (SurfaceOutput s, half3 lightDir, half atten)
    {
    #ifndef USING_DIRECTIONAL_LIGHT
    lightDir = normalize(lightDir);
    #endif

    half d = dot (s.Normal, lightDir) * 0.5 + 0.5;
    half3 ramp = tex2D (_Ramp, float2(d,d)).rgb;

    half4 c;
    c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
    c.a = 0;
    return c;
    }


    sampler2D _MainTex;
    float4 _Color;

    struct Input {
    float2 uv_MainTex : TEXCOORD0;
    };

    void surf (Input IN, inout SurfaceOutput o) {
    half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    o.Albedo = c.rgb;
    o.Alpha = c.a;
    }
    ENDCG

    }

    Fallback "Diffuse"
    }
     
  2. ellioman

    ellioman

    Joined:
    Mar 14, 2013
    Posts:
    19
    Give this a try

    Code (csharp):
    1. Shader "Toon/Lit"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Main Color", Color) = (0.5,0.5,0.5,1)
    6.         _MainTex ("Base", 2D) = "white" {}
    7.         _Ramp ("Ramp", 2D) = "gray" {}
    8.         _Alpha ("Alpha", range(0.0, 1.0)) = 1.0
    9.     }
    10.     SubShader
    11.     {
    12.         Tags
    13.         {
    14.             "RenderType"="Transparent"
    15.             "Queue" = "Transparent"
    16.         }
    17.         LOD 200
    18.  
    19.         CGPROGRAM
    20.             #pragma surface surf ToonRamp alpha:fade
    21.  
    22.             // Input Properties
    23.             uniform float _Alpha;
    24.             uniform float4 _Color;
    25.             uniform sampler2D _Ramp;
    26.             uniform sampler2D _MainTex;
    27.  
    28.             // Input Structs
    29.             struct Input
    30.             {
    31.                 float2 uv_MainTex : TEXCOORD0;
    32.             };
    33.  
    34.             // Lighting function
    35.             inline half4 LightingToonRamp (SurfaceOutput s, half3 lightDir, half atten)
    36.             {
    37.                 #ifndef USING_DIRECTIONAL_LIGHT
    38.                 lightDir = normalize(lightDir);
    39.                 #endif
    40.  
    41.                 half d = dot (s.Normal, lightDir) * 0.5 + 0.5;
    42.                 half3 ramp = tex2D (_Ramp, float2(d,d)).rgb;
    43.  
    44.                 half4 c;
    45.                 c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
    46.                 c.a = _Alpha;
    47.                 return c;
    48.             }
    49.  
    50.             // Surface shader
    51.             void surf (Input IN, inout SurfaceOutput o)
    52.             {
    53.                 o.Albedo = (tex2D(_MainTex, IN.uv_MainTex) * _Color).rgb;
    54.             }
    55.         ENDCG
    56.     }
    57.     Fallback "Diffuse"
    58. }
    59.  
     
    bowserscastle likes this.
  3. mcunha98

    mcunha98

    Joined:
    Jun 13, 2010
    Posts:
    261
    @ellioman

    Really thanks for your time and for the change.
    This shader work as I need, but it has one thing that I can change if is possible.



    The pink cube works fine, the first requirement was draw the entire mesh with alpha support.

    The selected mesh has a texture with alpha support (transparent), it is possible do this shader has support for alpha channel from 2D texture used on 'base' map ?
     
  4. ellioman

    ellioman

    Joined:
    Mar 14, 2013
    Posts:
    19
    Most certainly :)

    See if this works for you.
    I changed the Alpha slider to be a Alpha multiplier so you can have a little bit more control over the output.

    Code (csharp):
    1. Shader "Toon/Lit"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Main Color", Color) = (0.5,0.5,0.5,1)
    6.         _MainTex ("Base", 2D) = "white" {}
    7.         _Ramp ("Ramp", 2D) = "gray" {}
    8.         _AlphaMultiplier("Alpha Multiplier", range(0.0, 10.0)) = 1.0
    9.     }
    10.  
    11.     SubShader
    12.     {
    13.         Tags
    14.         {
    15.             "RenderType" = "Transparent"
    16.             "Queue" = "Transparent"
    17.         }
    18.         LOD 200
    19.  
    20.         CGPROGRAM
    21.             #pragma surface surf ToonRamp alpha:fade
    22.  
    23.             // Input Properties
    24.             uniform float _AlphaMultiplier;
    25.             uniform float4 _Color;
    26.             uniform sampler2D _Ramp;
    27.             uniform sampler2D _MainTex;
    28.  
    29.             // Input Structs
    30.             struct Input
    31.             {
    32.                 float2 uv_MainTex : TEXCOORD0;
    33.             };
    34.  
    35.             inline half4 LightingToonRamp(SurfaceOutput s, half3 lightDir, half atten)
    36.             {
    37.                 #ifndef USING_DIRECTIONAL_LIGHT
    38.                 lightDir = normalize(lightDir);
    39.                 #endif
    40.  
    41.                 half d = dot (s.Normal, lightDir) * 0.5 + 0.5;
    42.                 half3 ramp = tex2D (_Ramp, float2(d,d)).rgb;
    43.  
    44.                 half4 c;
    45.                 c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
    46.                 c.a = s.Alpha;
    47.                 return c;
    48.             }
    49.  
    50.             void surf (Input IN, inout SurfaceOutput o)
    51.             {
    52.                 fixed4 mainTexColor = tex2D(_MainTex, IN.uv_MainTex);
    53.                 o.Albedo = mainTexColor.rgb * _Color;
    54.                 o.Alpha = mainTexColor.a * _AlphaMultiplier;
    55.             }
    56.         ENDCG
    57.     }
    58.  
    59.     Fallback "Diffuse"
    60. }
     
  5. mcunha98

    mcunha98

    Joined:
    Jun 13, 2010
    Posts:
    261
    @ellioman
    Men, really, I don't have words to express myself !
    Thanks thanks thanks thanks !!!

    Now I have two options for shader toon, alpha for the model or to mask texture, thanks again !
     
  6. mcunha98

    mcunha98

    Joined:
    Jun 13, 2010
    Posts:
    261
    @ellioman during my tests I notice that alpha component (when 100%) not receive shadows, is possible change this (the first shader that you sent) ?

     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,265
    Nope.

    You can search the forums if you want for the multitude of threads complaining about this. TLDR; It's possible for transparent objects to receive shadows, but Unity doesn't support it with their built in lighting systems.

    The "easy fixes" are all bad hacks that have unintended consequences, like setting your shader to use "Queue"="AlphaTest" and "RenderType"="Opaque". That will make them receive shadows, but stop objects behind them from receiving shadows and cause those transparent objects to render in the wrong order.

    The only real solution, apart from completely replacing Unity's lighting system, is to swap your materials from transparent to opaque once the alpha is at 100%.
     
  8. mcunha98

    mcunha98

    Joined:
    Jun 13, 2010
    Posts:
    261
    @bgolus in this case, can I use something like renderer.material.SetFloat("_Alpha", f); (ok setFloat is only an example) for change it at runtime after detect collision ?



    I don't now if is possible (or there is a method to call on material that change the shader at runtime for this case), what you think ?
     
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,265
    I mean you can do material.shader = theTransparentShader, but I wouldn't necessarily suggest that. It is easier to have two separate materials and swap between them, one opaque and one transparent.
    Code (CSharp):
    1. public Material transparentMaterial;
    2. private Material originalMaterial;
    3.  
    4. void Start() {
    5.   originalMaterial = renderer.sharedMaterial;
    6. }
    7.  
    8. void OnEnable() {
    9.   renderer.sharedMaterial = transparentMaterial;
    10. }
    11.  
    12. void OnDisable() {
    13.   renderer.sharedMaterial = originalMaterial;
    14. }
    This is the best option to keep batching working too. For something similar that I do on my current project I copy the material parameters of the original material onto the transparent material. I do this manually (just the _MainTex and a few other custom settings) since there aren't any runtime functions for listing the variables.

    The other option is do what the Standard shader does and toggle transparency using SetOverrideTag() along with the material queue, zwrite, and blend mode at runtime. That's not necessarily any easier or better than shader or material swapping, but could let you use one shader for everything.
     
    Last edited: Sep 14, 2017
  10. mcunha98

    mcunha98

    Joined:
    Jun 13, 2010
    Posts:
    261

    Thanks a lot for share your idea, I did something as you suggest, using the events to replace the material at runtime, works fine !

    Thanks again for share ideas !
     
  11. BrokenSatellite

    BrokenSatellite

    Joined:
    May 14, 2019
    Posts:
    1
    Any way you can add transparency for the main texture on this shader?

    Code (CSharp):
    1. Shader "poiyomi/Rainbow"
    2. {
    3.  
    4.     Properties
    5.     {
    6.         _Color ("Color", Color) = (1,1,1,1)
    7.         _MainTex ("Texture", 2D) = "white" {}
    8.         _Mask ("Red Mask", 2D) = "white" {}
    9.         _Saturation("Saturation", Range(0.0, 2.0)) = 0.8
    10.         _Luminosity("Luminosity", Range(0.0, 1.0)) = 0.5
    11.         _RainbowEmission("Rainbow Emission", Range(0,5)) = 0
    12.         _XWiggle("XWiggle", Range(0.0, 1000.0)) = 1.0
    13.         _ZWiggle("ZWiggle", Range(0.0, 1000.0)) = 1.0
    14.         _Spread("Spread", Range(0.1, 10.0)) = 3.8
    15.         _Speed("Speed", Range(-10.0, 10.0)) = 2.4
    16.         _TimeOffset("TimeOffset", Range(0.0, 6.28318531)) = 0.0
    17.      
    18.     }
    19.     SubShader
    20.     {
    21.     Cull Off
    22.     Pass
    23.     {
    24.         Tags {
    25.         "LightMode"="ForwardBase"
    26.         }
    27.  
    28.         ZWrite On
    29.  
    30.         CGPROGRAM
    31.  
    32.         #pragma vertex vert
    33.         #pragma fragment frag
    34.         #include "UnityCG.cginc"
    35.         #include "Lighting.cginc"
    36.         #include "AutoLight.cginc"
    37.  
    38.         float4 _Color;
    39.         sampler2D _MainTex;
    40.         sampler2D _Mask;
    41.         fixed _Saturation;
    42.         fixed _Luminosity;
    43.         half _Spread;
    44.         half _Speed;
    45.         half _TimeOffset;
    46.         half _XWiggle;
    47.         half _ZWiggle;
    48.         half _RainbowEmission;
    49.  
    50.  
    51.  
    52.         inline fixed4 RGBtoHSL(fixed4 rgb)
    53.         {
    54.             fixed4 hsl = fixed4(0.0, 0.0, 0.0, rgb.w);
    55.          
    56.             fixed vMin = min(min(rgb.x, rgb.y), rgb.z);
    57.             fixed vMax = max(max(rgb.x, rgb.y), rgb.z);
    58.             fixed vDelta = vMax - vMin;
    59.          
    60.             hsl.z = (vMax + vMin) / 2.0;
    61.          
    62.             if (vDelta == 0.0)
    63.             {
    64.                 hsl.x = hsl.y = 0.0;
    65.             }
    66.             else
    67.             {
    68.                 if (hsl.z < 0.5) hsl.y = vDelta / (vMax + vMin);
    69.                 else hsl.y = vDelta / (2.0 - vMax - vMin);
    70.              
    71.                 float rDelta = (((vMax - rgb.x) / 6.0) + (vDelta / 2.0)) / vDelta;
    72.                 float gDelta = (((vMax - rgb.y) / 6.0) + (vDelta / 2.0)) / vDelta;
    73.                 float bDelta = (((vMax - rgb.z) / 6.0) + (vDelta / 2.0)) / vDelta;
    74.              
    75.                 if (rgb.x == vMax) hsl.x = bDelta - gDelta;
    76.                 else if (rgb.y == vMax) hsl.x = (1.0 / 3.0) + rDelta - bDelta;
    77.                 else if (rgb.z == vMax) hsl.x = (2.0 / 3.0) + gDelta - rDelta;
    78.              
    79.                 if (hsl.x < 0.0) hsl.x += 1.0;
    80.                 if (hsl.x > 1.0) hsl.x -= 1.0;
    81.             }
    82.             return hsl;
    83.         }
    84.  
    85.         inline fixed hueToRGB(float v1, float v2, float vH)
    86.         {
    87.             if (vH < 0.0) vH+= 1.0;
    88.             if (vH > 1.0) vH -= 1.0;
    89.             if ((6.0 * vH) < 1.0) return (v1 + (v2 - v1) * 6.0 * vH);
    90.             if ((2.0 * vH) < 1.0) return (v2);
    91.             if ((3.0 * vH) < 2.0) return (v1 + (v2 - v1) * ((2.0 / 3.0) - vH) * 6.0);
    92.             return v1;
    93.         }
    94.  
    95.         inline fixed4 HSLtoRGB(fixed4 hsl)
    96.         {
    97.             fixed4 rgb = fixed4(0.0, 0.0, 0.0, hsl.w);
    98.      
    99.             if (hsl.y == 0) {
    100.                 rgb.xyz = hsl.zzz;
    101.             }
    102.             else
    103.             {
    104.                 float v1;
    105.                 float v2;
    106.              
    107.                 if (hsl.z < 0.5) v2 = hsl.z * (1 + hsl.y);
    108.                 else v2 = (hsl.z + hsl.y) - (hsl.y * hsl.z);
    109.              
    110.                 v1 = 2.0 * hsl.z - v2;
    111.              
    112.                 rgb.x = hueToRGB(v1, v2, hsl.x + (1.0 / 3.0));
    113.                 rgb.y = hueToRGB(v1, v2, hsl.x);
    114.                 rgb.z = hueToRGB(v1, v2, hsl.x - (1.0 / 3.0));
    115.             }
    116.             return rgb;
    117.         }
    118.  
    119.         float3 LightingFunction( float3 normal )
    120.         {
    121.             return ShadeSH9(half4(normal, 1.0));
    122.         }
    123.  
    124.  
    125.         struct vertexInput
    126.         {
    127.             float4 vertex : POSITION;
    128.             float4 texcoord0 : TEXCOORD0;
    129.         };
    130.  
    131.         struct fragmentInput
    132.         {
    133.             float4 position : SV_POSITION;
    134.             float4 texcoord0 : TEXCOORD0;
    135.             fixed3 localPosition : TEXCOORD1;
    136.         };
    137.  
    138.         fragmentInput vert(vertexInput i)
    139.         {
    140.             fragmentInput o;
    141.             o.position = UnityObjectToClipPos(i.vertex);
    142.             o.texcoord0 = i.texcoord0;
    143.             o.localPosition = i.vertex.xyz; +fixed3(0.5, 0.5, 0.5);
    144.             return o;
    145.         }
    146.  
    147.  
    148.         fixed4 frag(fragmentInput i) : SV_TARGET
    149.         {
    150.  
    151.  
    152.             half time = (_Time.y * _Speed + sin(sin(i.localPosition.x*_XWiggle) + sin(i.localPosition.z * _ZWiggle))) / _Spread;
    153.             half timeWithOffset = time + _TimeOffset;
    154.             fixed2 lPos = fixed2(i.localPosition.x / _Spread, i.localPosition.y / _Spread);
    155.             fixed sine = sin(timeWithOffset);
    156.             fixed cosine = cos(timeWithOffset);
    157.             fixed hue = (-lPos.y) / 2.0;
    158.             hue += time;
    159.             while (hue < 0.0) hue += 1.0;
    160.             while (hue > 1.0) hue -= 1.0;
    161.             fixed4 hsl = fixed4(hue, _Saturation, _Luminosity, 1.0);
    162.             //hsl *= tex2D(_Mask, i.texcoord0);
    163.             //return HSLtoRGB(hsl);
    164.             half mask = tex2D(_Mask, i.texcoord0).r;
    165.             fixed4 col = lerp(tex2D(_MainTex, i.texcoord0) * _Color, HSLtoRGB(hsl), mask);
    166.  
    167.          
    168.             float attenuation = LIGHT_ATTENUATION(i) / SHADOW_ATTENUATION(i);
    169.             float3 FlatLighting = saturate((LightingFunction( float3(0,1,0) )+(_LightColor0.rgb*attenuation))) + mask*_RainbowEmission;
    170.             col.rgb *= FlatLighting;
    171.  
    172.             return col;
    173.         }
    174.         ENDCG
    175.     }
    176.     }
    177.         FallBack "Diffuse"
    178. }