Thursday, November 27, 2014

Rules for Multi-pass Shaders in Unity

Here is some basic information about multi-pass shaders in Unity. This post is accurate to 11/27/2014, for Unity 4.5.

In the last few days I've been looking a bit at shaders - especially at combining surface shaders and vertex/fragment shaders. The most informative info was in this thread.

However, some of the information has been deprecated and is listed in a confusing format, so I think it'll be nice to have an updated summary:

For starters, what is a pass? 


A pass block in a Unity shader denotes when something is rendered once. Each sub-shader can theoretically have multiple passes - meaning that the geometry will be rendered multiple times.

(Each pass has its own properties that will not be "passed" on to other passes. For a list of those properties, check here)

Most sub-shaders will only have one pass - or possibly none, if people are using a surface shader. However, the rules and exceptions get a bit complicated with mutli-pass shaders.

Rules for Multi-pass Shader



Q: Can you put two vertex/fragment shaders together?
A: Yes, just put two passes with vertex/fragment shaders right next to each other. The second one will be drawn over the first one. (Note that some properties will be passed on from one pass to the other. For example, if you use a vertex shader to change the mesh geometry, the changes will still be there in the next pass.)

Q: Can you combine surface shaders and vertex/fragment shaders?
A: No. You used to be able to, but right now the surface shader will simply override the vertex/fragment shader.

Q: Can you put two surface shaders together?
A: Yes. You can't put surface shaders into a pass (this will throw an error), but you can put two surface shaders right next to each other. As usual, the second one will override the first one.

Q: What about fixed functionality shaders?
A: Fixed functionality shaders (I'm referring to these) can be put into a pass and act the same way as the vertex/fragment shaders in a pass.


Sample Code

Here is some basic sample code for testing. There are two surface shaders, one fixed functionality shader, and one vertex/fragment shader. You can comment out the different parts for experimentation on how the system works.





Shader "Custom/GrayScale" {
Shader "Custom/MultipassTest" {
    Properties {

    }
    SubShader {
      Tags {"Queue" = "Geometry" "RenderType" = "Opaque" }
    
       ////////////////////////////////////////////////////////
       //Surface Shader 1 - BLUE                             //
       ////////////////////////////////////////////////////////
       CGPROGRAM
       #pragma target 3.0
       #pragma surface surf BlinnPhong
       
       struct Input {
           float4 color : COLOR;
       };

       void surf (Input IN, inout SurfaceOutput o) {
           o.Emission = float3(0,0,1);
       }
       ENDCG
       
  
       ////////////////////////////////////////////////////////
       //Surface Shader 2 - RED                              //
       ////////////////////////////////////////////////////////
       CGPROGRAM
       #pragma target 3.0
       #pragma surface surf BlinnPhong
       
       struct Input {
           float4 color : COLOR;
       };

       void surf (Input IN, inout SurfaceOutput o) {
           o.Emission = float3(1,0,0);
       }
       ENDCG    
          
          
       ////////////////////////////////////////////////////////
       //Fixed Functionality shader - GREEN                  //
       ////////////////////////////////////////////////////////
       Pass
       {
           Color (0,1,0,1)
       }
      
       ////////////////////////////////////////////////////////
       //Fixed Functionality shader - WHITE                  //
       ////////////////////////////////////////////////////////
       Pass {
           CGPROGRAM
           #pragma fragment frag

           fixed4 frag() : COLOR {
               return fixed4(1,1,1,1);
           }
           ENDCG
       }

      
    } 
    Fallback "Diffuse"
  }

2 comments:

  1. I would like to thank you for the time you invest in making such articles cause as I think it can be very helpful for many people who just wish to get as much information about this topic as possible.

    cheap writing service

    ReplyDelete
  2. Many Many thanks.. Seriously.....

    ReplyDelete