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

Rendering with Replaced Shaders

Discussion in 'Shaders' started by ivkoni, Mar 11, 2011.

  1. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    Could somebody please explain to me rendering with replaced shaders as if I am an 8 years old?

    SL-ShaderReplacement

    Code (csharp):
    1.  
    2. var dif : Shader
    3. function Awake (){
    4.    camera.SetReplacementShader(dif,null);
    5. }
    6.  
    where dif is say the built in Diffuse shader. I would expect the camera to render the scene as if all materials are using the diffused shader, but nothing is rendered.
    Why?
     
    ModLunar likes this.
  2. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
    Its like a post processing shader, but indeed its a processing shader.
    Below is a simple sample:
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [ExecuteInEditMode]
    5. public class ReplacementShader : MonoBehaviour {
    6.     public Shader shader;
    7.     public void Awake() {
    8.         if (shader)
    9.             transform.camera.SetReplacementShader(shader, null);
    10.     }
    11. }
    Code (csharp):
    1. Shader "Hidden/Aubergine/Orthographic Depth" {
    2.     SubShader {
    3.         Pass {
    4.             Lighting Off Fog { Mode Off }
    5.             CGPROGRAM
    6.             #pragma vertex vert
    7.             #pragma fragment frag
    8.  
    9.             struct v2f {
    10.                 float4 pos : POSITION;
    11.                 float3 Z : TEXCOORD0;
    12.             };
    13.  
    14.             v2f vert (float4 vertex : POSITION) {
    15.                 v2f o;
    16.                 float4 oPos = mul(UNITY_MATRIX_MVP, vertex);
    17.                 o.pos = oPos;
    18.                 o.Z = oPos.zzz;
    19.                 return o;
    20.             }
    21.             half4 frag( v2f i ) : COLOR {
    22.                 return i.Z.xxxx;
    23.             }
    24.             ENDCG
    25.         }
    26.     }
    27. }
     
  3. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    Thanks.
    However I still don't get it.
    What is a 'processing shader'?
    What are the shaders that SetReplacementShader works with?

    Why wouldn't it work if the shader is:
    Code (csharp):
    1.  
    2. Shader "Diffuse" {
    3. Properties {
    4.     _Color ("Main Color", Color) = (1,1,1,1)
    5.     _MainTex ("Base (RGB)", 2D) = "white" {}
    6. }
    7. SubShader {
    8.     Tags { "RenderType"="Opaque" }
    9.     LOD 200
    10.  
    11. CGPROGRAM
    12. #pragma surface surf Lambert
    13.  
    14. sampler2D _MainTex;
    15. float4 _Color;
    16.  
    17. struct Input {
    18.     float2 uv_MainTex;
    19. };
    20.  
    21. void surf (Input IN, inout SurfaceOutput o) {
    22.     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    23.     o.Albedo = c.rgb;
    24.     o.Alpha = c.a;
    25. }
    26. ENDCG
    27. }
    28.  
    29. Fallback "VertexLit"
    30. }
    31.  
    for example
     
    Last edited: Mar 11, 2011
  4. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
    I dont know why a surf shader doesnt work, i never tried so. Replacement shader has a limited usage by my opinion anyhow, can be useful for depth info and setting a specific shader for a series of tagged objects.

    To answer your question; replacement shader replaces the selected or all objects in scene to use the defined shader and still use their own materials.
     
  5. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    Well, if this is what it is supposed to do, (which is my understanding as well) then it simply doesn't work in general.
     
  6. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
    Make a scene with various cubes and stuff and render your camera with the following simple shader
    Code (csharp):
    1. Shader "Replacement_Example" {
    2.     SubShader {
    3.         Pass {
    4.             Tags { "RenderType"="Opaque" }
    5.             CGPROGRAM
    6.                 #pragma fragment frag
    7.                 half4 frag( ) : COLOR { return half4(0,1,0,1); }
    8.             ENDCG
    9.         }
    10.     }
    11. }
    You will see all objects go green despite their default diffuse color is grey
     
  7. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
    Rendertype is irrelevant in the above example and not necessary indeed, just forgot to delete it.
     
  8. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    Thank you very much Aubergine for looking into this!
    I see that some shader work as 'replacement shaders' like the ones that you posted, but I would like to know what type of shaders work.

    For example, why would it not work with the built in diffuse shader that I posted above?
     
  9. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
    Well, i didnt try before but as i got curious myself as well i tried your surf shader and it works. I dont see a problem there.
    Probably you tried to replace another diffuse shader and thus you were not able to see a visual difference.

    In order to see the difference, first create a sphere and add a regular diffuse material on it with a nice simple texture. Then make another material with the following shader:
    Code (csharp):
    1. Shader "New Shader" {
    2.     Properties {
    3.         _MainTex ("Base (RGB)", 2D) = "white" {}
    4.     }
    5.     SubShader {
    6.         Tags { "RenderType"="Opaque" }
    7.         LOD 200
    8.        
    9.         CGPROGRAM
    10.         #pragma surface surf Lambert
    11.  
    12.         sampler2D _MainTex;
    13.  
    14.         struct Input {
    15.             float2 uv_MainTex;
    16.         };
    17.  
    18.         void surf (Input IN, inout SurfaceOutput o) {
    19.             half4 c = tex2D (_MainTex, IN.uv_MainTex);
    20.             o.Emission = c.rgb;
    21.             o.Alpha = c.a;
    22.         }
    23.         ENDCG
    24.     }
    25.     FallBack "Diffuse"
    26. }
    which is the same regular diffuse shader except that i changed albedo to emission to make a visual difference. And just try to render with this one and you will see that it works.
     
  10. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    thank you kind sir. Will try it when I get home.