Search Unity

Off alpha testing in script

Discussion in 'Scripting' started by jitwtttl, May 27, 2015.

  1. jitwtttl

    jitwtttl

    Joined:
    Aug 29, 2014
    Posts:
    8
    Is there any way to turn on/off shader's alpha test function in a C# script?

    This is the shader sample.
    I want to set off and on the alpha test in script.
    (* The alpha test is added using pragma keywords. *)

    Code (CSharp):
    1. Shader "Alpharized Shadow" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1, 1, 1, 1)
    4.     _MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
    5.     _Cutoff ("Base Alpha cutoff", Range (0,.9)) = .5
    6.     _Multiplier("Color Multiplier",Range(1,10)) = 1.0
    7. }
    8. SubShader {
    9.     Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" }
    10.     LOD 200
    11.     Cull Off Lighting Off
    12.  
    13. CGPROGRAM
    14. #pragma surface surf Lambert alphatest:_Cutoff
    15.  
    16. sampler2D _MainTex;
    17. fixed4 _Color;
    18. float _Multiplier;
    19.  
    20. struct Input {
    21.     float2 uv_MainTex;
    22. };
    23.  
    24. void surf (Input IN, inout SurfaceOutput o) {
    25.     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color * _Multiplier;
    26.     o.Albedo = c.rgb;
    27.     o.Alpha = c.a;
    28. }
    29.  
    30. ENDCG
    31. }
    32.  
    33. Fallback "Transparent/Cutout/VertexLit"
    34. }
     
  2. WheresMommy

    WheresMommy

    Joined:
    Oct 4, 2012
    Posts:
    890
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    @asd234w4r5 that thread is from late 2005. It's so outdated it's not even funny.

    @jitwtttl I found a way, though you'll have to move the alphatest to the surf function and use discard. What you do is to use #pragma shader_feature to create a variant with alphatest. I'll include the altered CGPROGRAM, as everything else is the same. Bolded lines are changed.

    Code (csharp):
    1. CGPROGRAM
    2. #pragma shader_feature ALPHATEST
    3. #pragma surface surf Lambert
    4.  
    5. sampler2D _MainTex;
    6. fixed4 _Color;
    7. float _Multiplier;
    8. float _Cutoff;
    9.  
    10. struct Input {
    11.     float2 uv_MainTex;
    12. };
    13.  
    14. void surf (Input IN, inout SurfaceOutput o) {
    15.     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color * _Multiplier;
    16.    
    17.     #if defined (ALPHATEST)
    18.     if(c.a < _Cutoff)
    19.         discard;
    20.     #endif
    21.    
    22.     o.Albedo = c.rgb;
    23.     o.Alpha = c.a;
    24. }
    25.      
    26. ENDCG
    To activate the ALPHATEST stuff, use material.EnableKeyword to turn it on, and material.DisableKeyword to turn it off.

    The reason for why I'm using discard instead of alphatest:_Cutoff is that it seems like you can't wrap #pragma statements in an #if defined-block, if I try to do this:

    Code (csharp):
    1. #if defined (ALPHATEST)
    2.     #pragma surface surf Lambert alphatest:_Cutoff
    3. #else
    4.     #pragma surface surf Lambert
    5. #endif
    I get the error message "Duplicate #pragma surface found" on the statement without the alphatest.

    The discard should do the same thing, though it might be a bit slower, as it contains an if-statement, though there's a good chance that it's optimized away in the compiled shader.
     
  4. jitwtttl

    jitwtttl

    Joined:
    Aug 29, 2014
    Posts:
    8
    Great Idea! Baste. Thank you. : )

    And I think shader's multi_compile can be another alternatives.
    Official Document Link
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    Yup. I based my advice on shader_feature instead of multi_compile because the docs says that "shader_feature makes most sense for keywords that will be set on the materials, while multi_compile for keywords that will be set from code globally."

    In addition, I think this:

    Code (csharp):
    1. #pragma shader_feature ALPHATEST
    is prettier than this:

    Code (csharp):
    1. #pragma multi_compile __ ALPHATEST
    Where "__" means "if ALPHATEST is not defined"