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

ignore a shader PASS under certain conditions (variable value)

Discussion in 'Shaders' started by badescuga9, Mar 7, 2014.

  1. badescuga9

    badescuga9

    Joined:
    Dec 11, 2012
    Posts:
    37
    I have an outline shader that has 2 passes, thus for every game object i have 2 draw calls.

    The first call is used only for outline purposes, but my object is not always outlined, so i would wish to enable that pass only when a certain variable is greater than 0. Is it possible?

    Here is the shader:

    Code (csharp):
    1.     Shader "Outlined/Silhouetted Diffuse" {
    2.         Properties {
    3.             _Color ("Main Color", Color) = (.5,.5,.5,1)
    4.             _OutlineColor ("Outline Color", Color) = (0,0,0,1)
    5.             _Outline ("Outline width", Range (0.0, 0.3)) = 0
    6.             _MainTex ("Base (RGB)", 2D) = "white" { }
    7.         }
    8.        
    9.         SubShader {
    10.             Tags { "Queue" = "Transparent" }
    11.    
    12.             Pass {
    13.                 Name "OUTLINE"
    14.                 Tags { "LightMode" = "Always" }
    15.                 Cull Back
    16.                 ZWrite Off
    17.                 ZTest Always
    18.                 ColorMask RGB
    19.            
    20.                 CGPROGRAM
    21.                 #pragma only_renderers gles opengl
    22.                 #pragma vertex vert
    23.                 #pragma fragment frag
    24.                
    25.                 #include "UnityCG.cginc"
    26.                
    27.                 struct appdata {
    28.                     half4 vertex : POSITION;
    29.                     half3 normal : NORMAL;
    30.                 };
    31.                
    32.                 struct v2f {
    33.                     half4 pos : POSITION;
    34.                     half4 color : COLOR;
    35.                 };
    36.                
    37.                 uniform half _Outline;
    38.                 uniform half4 _OutlineColor;
    39.                
    40.                 v2f vert(appdata v) {
    41.                     v2f o;
    42.                    
    43.                     o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    44.                
    45.                     half3 norm   = mul ((half3x3)UNITY_MATRIX_IT_MV, v.normal);
    46.                     half2 offset = TransformViewToProjection(norm.xy);
    47.                
    48.                     o.pos.xy += offset * _Outline;
    49.                     o.color = _OutlineColor;
    50.                     return o;
    51.                 }
    52.                
    53.                 half4 frag(v2f i) :COLOR {
    54.                     return i.color;
    55.                 }
    56.                 ENDCG
    57.             }
    58.    
    59.             Pass {
    60.                 Name "BASE"
    61.                 ZWrite On
    62.                 ZTest LEqual
    63.                 Blend SrcAlpha OneMinusSrcAlpha
    64.                 Material {
    65.                     //Diffuse [_Color]
    66.                     //Ambient [_Color]
    67.                 }
    68.                 Lighting On
    69.                 SetTexture [_MainTex] {
    70.                     //ConstantColor [_Color]
    71.                     //Combine texture * constant
    72.                 }
    73.             }
    74.         }
    75.        
    76.         Fallback "Diffuse"
    77.     }
    78.  
    When "_Outline" is equal to 0, i would like to ignore the first PASS. Is this possible?
     
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    The simplest way to do this is to have two shaders and switch between them using a script.
     
  3. pachash

    pachash

    Joined:
    Apr 2, 2014
    Posts:
    55
    But from the maintenance point of view it becomes _very_ inconvenient. Several files, code duplication, etc... Is there any other alternative?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Put more code into cginc files so there's less duplicate work, or use UsePass. Still needs multiple files though. In 5.6 and later there's a way to disable certain passes using SetShaderPassEnabled, but you can only control it via existing "LightMode" tags and not by name or arbitrary tag.
     
  5. GearKlik

    GearKlik

    Joined:
    Sep 21, 2015
    Posts:
    58
  6. pachash

    pachash

    Joined:
    Apr 2, 2014
    Posts:
    55
  7. pachash

    pachash

    Joined:
    Apr 2, 2014
    Posts:
    55
    Maybe you have a simple usage example?

    Meanwhile, docs say the following:

    Sounds too advanced and obscured too me...