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

Reveal by light Alpha Test Shader

Discussion in 'Shaders' started by Slobade, Jan 5, 2014.

  1. Slobade

    Slobade

    Joined:
    Jan 4, 2014
    Posts:
    1
    Hi everyone,
    Long time reading, first time posting, blablabla...

    I try to make a shader that is invisible when not lit directly by any light source. I almost have something but now I have reach my limit of understanding.

    Code (csharp):
    1. Shader "Custom/RevealAlpha" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
    5.     _MainTex("MainTex", 2D) = "white" {}
    6.     _lerper ("lerper", range (0,1)) = 0
    7.     _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    8.     _Ramp("Shading Ramp", 2d) = "white"{}
    9.                 }
    10.                 SubShader {
    11.                     Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    12.                     LOD 300
    13.                    
    14.                         CGPROGRAM
    15.                         #pragma surface surf CustomDiffuse alphatest:_Cutoff
    16.                         #include "UnityCG.cginc"
    17.                         #include "Autolight.cginc"
    18.                        
    19.                         sampler2D _MainTex;
    20.                         fixed4 _Color;
    21.                         half _lerper;
    22.                         sampler2D _Ramp;
    23.                        
    24.                         half4 LightingCustomDiffuse(SurfaceOutput s, half3 lightDir,half atten){
    25.                    
    26.                                 half NdotL =dot(s.Normal, lightDir);
    27.                                 half diff = NdotL * 0.5 + 0.5;
    28.                                 half3 ramp = tex2D(_Ramp, float2(diff)).rgb;
    29.                                 half4 c;
    30.                                 c.rgb = s.Albedo * _LightColor0.rgb * (step(_lerper,ramp) * atten * 2);
    31.                                 c.a = s.Alpha;
    32.                                 return c;
    33.                             }
    34.                        
    35.                         struct Input {
    36.                             float2 uv_MainTex;
    37.                         };
    38.                        
    39.                         void surf (Input IN, inout SurfaceOutput o) {
    40.                        
    41.                             fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    42.                             fixed4 lum = (_LightColor0 * _lerper);
    43.                                     lum = step (0.2, lum);
    44.                                
    45.                             o.Albedo =tex.rgb * _Color.rgb * lum.rgb * 2 ;
    46.                             o.Alpha =  lum.r  * 10;
    47.                         }
    48.                         ENDCG
    49. }
    50. Fallback "Transparent/Cutout/VertexLit"
    51. }
    And this is the result:


    I use a ramp and a custom lighting model because it was the only way to make the transition sharper.Witch is driving me insane because I specifically use Alpha Test.

    I also multiply the Albedo by 2 to make it more visible. Yes the Albedo and not the Alpha were the "*10" has no effect.

    The problem for me come from "_LightColor0", but it's also my key element here.(The documentation is quite light on the subject.)

    So, since now I don't know what i'm doing anymore. I will be grateful if someone can tell me what I'm doing wrong.


    Thank in advance. :)
     

    Attached Files:

  2. oleprinds

    oleprinds

    Joined:
    Mar 29, 2013
    Posts:
    4
    Hi Slobade,

    I don't know if this will help you or future searchers on the forum, but I managed to put together a simple shader using a custom lighting model and the finalcolor surface shader option.

    The shader is based on Transparent Diffuse, but I don't worry about normals, because the object I'm shading is always facing the camera.

    The shader takes the brightness (max color value) from the light color, multiplies by attenuation and then uses that value as alpha. The key is, that the finalcolor function needs to store the alpha value because you apparently can't manipulate alpha values from the lighting function.

    Code (CSharp):
    1. Shader "Custom/DarkIsInvisible" {
    2.     Properties {
    3.         _Color ("Main Color", Color) = (1,1,1,1)
    4.         _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    5.     }
    6.  
    7.     SubShader {
    8.         Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    9.         LOD 200
    10.  
    11.     CGPROGRAM
    12.     #pragma surface surf AlphaLambert noambient alpha finalcolor:setalpha
    13.  
    14.     sampler2D _MainTex;
    15.     fixed4 _Color;
    16.  
    17.     struct Input {
    18.         float2 uv_MainTex;
    19.     };
    20.    
    21.     float lightAlpha;
    22.     half4 LightingAlphaLambert (SurfaceOutput s, half3 lightDir, half atten) {
    23.         half4 c;
    24.         c.rgb = _LightColor0.rgb * atten;
    25.         c.a = s.Alpha;
    26.         lightAlpha = max(_LightColor0.r, max(_LightColor0.g, _LightColor0.b)) * atten;
    27.        
    28.         return c;
    29.     }
    30.    
    31.     void setalpha(Input IN, SurfaceOutput o, inout fixed4 color)
    32.     {
    33.         color.a = lightAlpha;
    34.         return;
    35.     }
    36.  
    37.     void surf (Input IN, inout SurfaceOutput o) {
    38.         fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    39.         o.Albedo = c.rgb;
    40.         o.Alpha = c.a;
    41.     }
    42.     ENDCG
    43.     }
    44.  
    45.     Fallback "Transparent/VertexLit"
    46. }
    47.  
    this post lead me in the right direction...
     
    Lorefold likes this.
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Don't do anything special in the surf function, just pass on the texture parameters etc straight. All you need to do is change one line in your light model.

    c.a = s.Alpha;
    to
    c.a = s.Alpha * atten;
    or
    c.a = s.Alpha - (1.0 - atten);

    The reason why is the light color is the color and intensity of the light with out any shadows or falloff. Essentially it's the color of the light bulb if there was one. That "atten" variable is the result of falloff and shadowing combined.
     
  4. Lorefold

    Lorefold

    Joined:
    Jul 14, 2013
    Posts:
    1
    @oleprinds , Thank you so much for your example there! It saved me a lot of trial and (mostly) error.