Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    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,778
    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,778
    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,778
    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,778
    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,778
    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.
     
unityunity