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

Enabling and disabling a shader pass

Discussion in 'Shaders' started by MrScary, Apr 3, 2013.

  1. MrScary

    MrScary

    Joined:
    Dec 8, 2007
    Posts:
    94
    Is there a way to reliably enable and disable a shader pass in a multi-pass shader?

    I can't seem to find a way to do that without experimenting with a bunch of hacks (or I've missed the documented method which could likely be the case :D ).

    thanks..
     
  2. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    No. Please try creating a text file with a bunch of UsePass lines, and let us know if you can create a material from that. I never tried. If it works, I'd use that method. Otherwise, I'd keep a bunch of shaders around that contain the UsePass lines you want.
     
  3. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    642
    5 years later, I've run into the same question... Is there a way to enable/disable a shader pass per-material at runtime?

    I've got a shader with a lot of variants, and I'd like to add some VFX to the shader.

    Rather than doubling the (already concerning) number of shader variants by adding new #pragma multi_compiles, I could apply some of these effects with a second pass - but only if I can turn it on/off as needed. Is there any way to do this?
     
  4. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    327
    Solution 1:
    Use Material.SetPass

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class MultiPass : MonoBehaviour
    6. {
    7.  
    8.     public RenderTexture Source;
    9.     public RenderTexture Destination;
    10.     public Material material;
    11.     public int pass;
    12.    
    13.     void Blit(RenderTexture source, RenderTexture destination, Material mat)
    14.     {
    15.         RenderTexture.active = destination;
    16.         mat.SetTexture("_MainTex", source);
    17.         GL.PushMatrix();
    18.         GL.LoadOrtho();
    19.         GL.invertCulling = true;
    20.         mat.SetPass(0);
    21.         GL.Begin(GL.QUADS);
    22.         GL.MultiTexCoord2(0, 0.0f, 0.0f);
    23.         GL.Vertex3(0.0f, 0.0f, 0.0f);
    24.         GL.MultiTexCoord2(0, 1.0f, 0.0f);
    25.         GL.Vertex3(1.0f, 0.0f, 0.0f);
    26.         GL.MultiTexCoord2(0, 1.0f, 1.0f);
    27.         GL.Vertex3(1.0f, 1.0f, 1.0f);
    28.         GL.MultiTexCoord2(0, 0.0f, 1.0f);
    29.         GL.Vertex3(0.0f, 1.0f, 0.0f);
    30.         GL.End();
    31.         GL.invertCulling = false;
    32.         GL.PopMatrix();      
    33.     }
    34.    
    35.     void Start ()
    36.     {
    37.        
    38.     }
    39.    
    40.     void Update ()
    41.     {
    42.         Blit(Source,Destination,material);
    43.     }
    44. }
    45.  
    Code (CSharp):
    1. Shader "MultiPass"
    2. {
    3.     SubShader
    4.     {
    5.         CGINCLUDE
    6.         #pragma vertex SetVertexShader
    7.         #pragma fragment SetPixelShader      
    8.         void SetVertexShader (inout float4 vertex:POSITION,inout float2 uv:TEXCOORD0)
    9.         {
    10.             vertex = UnityObjectToClipPos(vertex);
    11.         }
    12.         ENDCG
    13.        
    14.         Pass
    15.         {
    16.             CGPROGRAM          
    17.             float4 SetPixelShader (float4 vertex:POSITION,float2 uv:TEXCOORD0) : SV_TARGET
    18.             {
    19.                 return float4(1,0,0,1);
    20.             }
    21.             ENDCG
    22.         }
    23.        
    24.         Pass
    25.         {
    26.             CGPROGRAM                      
    27.             float4 SetPixelShader (float4 vertex:POSITION,float2 uv:TEXCOORD0) : SV_TARGET
    28.             {
    29.                 return float4(0,0,1,1);
    30.             }
    31.             ENDCG
    32.         }      
    33.     }
    34. }
    Shader output (second pass):
    upload_2018-11-2_15-54-14.png

    Render texture with first pass:
    upload_2018-11-2_15-56-10.png
    so you can combine Blit with various passes.



    Solution 2:
    Use discard and Material.SetFloat:
    Code (CSharp):
    1. Shader "MultiPass"
    2. {
    3.     SubShader
    4.     {
    5.         CGINCLUDE
    6.         #pragma vertex SetVertexShader
    7.         #pragma fragment SetPixelShader      
    8.         void SetVertexShader (inout float4 vertex:POSITION,inout float2 uv:TEXCOORD0)
    9.         {
    10.             vertex = UnityObjectToClipPos(vertex);
    11.         }
    12.         ENDCG
    13.        
    14.         Pass
    15.         {
    16.             CGPROGRAM          
    17.             float4 SetPixelShader (float4 vertex:POSITION,float2 uv:TEXCOORD0) : SV_TARGET
    18.             {
    19.                 return float4(1,0,0,1);
    20.             }
    21.             ENDCG
    22.         }
    23.        
    24.         Pass
    25.         {
    26.             CGPROGRAM                      
    27.             float4 SetPixelShader (float4 vertex:POSITION,float2 uv:TEXCOORD0) : SV_TARGET
    28.             {
    29.                 if (true)
    30.                 {
    31.                     discard;              
    32.                 }
    33.                 return float4(0,0,1,1);
    34.             }
    35.             ENDCG
    36.         }      
    37.     }
    38. }
    Shader output:
    upload_2018-11-2_15-59-59.png


    Solution 3:
    Write custom native rendering plugin with multipass support. For OpenGL here is topic about compact code:
    https://forum.unity.com/threads/unity-opengl-native-plugin-basic-source-code.570571/

    Solution 4:
    Play with various blending modes, to "hide" output of given pass:
    https://docs.unity3d.com/Manual/SL-Blend.html
     
    bluescrn likes this.
  5. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    327