Mar
6
2012

Camera Shaders

yay..took few hours just to get this working: Render a whole camera view with one shader.
It should be simple, but the documents wont give any examples: Camera.RenderWithShader

Main image is showing vertex-depth-shader seen with camera (its modified version from one of these unity replacement shaders)

Next..
– How to use camera shaders to make some more fake shadows? or ambient occlusion? or this kind of screen water effect? (with unity indie..)
(I dont know..going to play around with the camera shader a bit..)

Update#1

Well this is interesting, the fake river shader works quite nicely as camera shader.
And a problem..fragment shaders wont work with camera??

image#2:  without camera shader & with shader

CameraShader.js:


#pragma strict

private var cam:Camera;
public var repl:Shader;

function Start () {
//repl = Shader.Find( "Custom/Render Depth" );
cam = Camera.main;
cam.RenderWithShader(repl, "RenderType");
}

function OnPostRender ()
{
cam.RenderWithShader(repl, "RenderType");
}

Depth shader test:


// Upgrade NOTE: replaced 'glstate.matrix.mvp' with 'UNITY_MATRIX_MVP'

Shader "Custom/DepthCamSurf2"
{
    Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _Amount ("Extrusion Amount", Range(-1,1)) = 0.5
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }
      Lighting Off
      
      CGPROGRAM
// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices
#pragma exclude_renderers gles
        #pragma surface surf Lambert vertex:vert
        #include "UnityCG.cginc"
        
      struct Input {
//          float2 uv_MainTex;
            float2 uv_MainTex;
            
//            float3 depth;
            float4 pos;
//            float3 viewDir;
            float3 color;
            float3 worldPos;
//            float3 worldRefl;
//            float3 worldNormal;
//            float4 screenPos;
            INTERNAL_DATA
      };
//    struct v2f {
//        float4 pos : POSITION;
//        float4 color : COLOR;
//    };      
      
      
      float _Amount;
      
      void vert (inout appdata_full v, out Input o) {
//          v.vertex.xyz += v.normal * _Amount;
            o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
//            float3 viewNormal = mul((float3x3)glstate.matrix.invtrans.modelview[0], v.normal);
            float z = (mul((float3x4)UNITY_MATRIX_MV, v.vertex).z+9);
            
            o.color.rgb = float3(z,z,z); //viewNormal * 0.5 + 0.5;
            //o.color.a = 1; //-z / _ProjectionParams.z;

      }
      
      sampler2D _MainTex;
      
      void surf (Input IN, inout SurfaceOutput o) {
      
            half3 col = IN.color;
      
            // could use as "scanner effect" (laser line moves across screen)
             if (IN.worldPos.x >= 2 && IN.worldPos.x <= 2.1)
            {
                col= float3(1,0,0);
            }
      
          o.Albedo = col; //tex2D (_MainTex, IN.uv_MainTex).rgb;
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

 

 

 

 

One other test shader:


// Upgrade NOTE: replaced 'glstate.matrix.mvp' with 'UNITY_MATRIX_MVP'

Shader "Custom/DepthCamSurf3"
{
    Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _Amount ("Extrusion Amount", Range(-1,1)) = 0.5
      _ObjPos ("ObjPos", Vector) = (1,1,1,1)
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }
      Lighting Off
      
      CGPROGRAM
// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices
#pragma exclude_renderers gles
        #pragma surface surf Lambert vertex:vert
        #include "UnityCG.cginc"
        
      struct Input {
//          float2 uv_MainTex;
            float2 uv_MainTex;
            
//            float3 depth;
            float4 pos;
//            float3 viewDir;
            float3 color;
            float3 worldPos;
//            float3 worldRefl;
//            float3 worldNormal;
//            float4 screenPos;
            INTERNAL_DATA
      };
//    struct v2f {
//        float4 pos : POSITION;
//        float4 color : COLOR;
//    };      
      
      
      float _Amount;
      
      void vert (inout appdata_full v, out Input o) {
//          v.vertex.xyz += v.normal * _Amount;
            o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
//            float3 viewNormal = mul((float3x3)glstate.matrix.invtrans.modelview[0], v.normal);
            float z = (mul((float3x4)UNITY_MATRIX_MV, v.vertex).z+9);
            
            o.color.rgb = float3(z,z,z); //viewNormal * 0.5 + 0.5;
            //o.color.a = 1; //-z / _ProjectionParams.z;
            
            // do scanning here, with screenpos?

      }
      
      sampler2D _MainTex;
      uniform float4 _ObjPos;
//    sampler2D input : register(s0); // ?

      
      void surf (Input IN, inout SurfaceOutput o) {
      
            half3 col = IN.color;

            float x1 = IN.worldPos.x;
            float y1 = IN.worldPos.y;
            float x2 = _ObjPos.x;
            float y2 = _ObjPos.y;
            
            int steps = 15;
            
            float dx = x2-x1;
            float dy = y2-y1;
            float xs = dx/steps;
            float ys = dy/steps;
            
            float x = x1;
            float y = y1;   
            
            //half3 origcol = tex2D (_MainTex, IN.uv_MainTex).rgb*3;
            
            float pixel=0;
            half c = 0;
            
//            float2 screenUV = IN.screenPos.xy / IN.screenPos.w;
//            screenUV *= float2(8,6);
            
            for (float n= 0; n <= 15; n++)
            {
            
                
                //pixel = tex2D (_WallTex, float2(x,y)*0.1).r;
                pixel = IN.color.r;
                
                if (pixel>0)
                {
                    c++;
                }
                
                x+=xs;
                y+=ys;
                
            }
            
            if (c>0) // we hit something
            {
                col = float3(1,0,0);
            }else{
                col = float3(0,0,1);
            }
            
//            col = tex2D (input, IN.uv_MainTex).rgb;

            // could use as "scanner effect" (laser line moves across screen)
             if (IN.worldPos.x >= 2 && IN.worldPos.x <= 2.1)
            {
                col= float3(1,0,0);
            }

      
          o.Albedo = col; //tex2D (_MainTex, IN.uv_MainTex).rgb;
      }
      ENDCG
    }
    

    
    
    Fallback "Diffuse"
  }

 

 


7 Comments + Add Comment

Leave a comment

Connect

Twitter View LinkedIn profile Youtube Youtube Join Discord Twitch

UnityLauncherPro

Get UnityLauncherPRO and work faster with Unity Projects!
*free unity hub alternative

@unitycoder_com

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.