I am trying to reconstruct the pixels world position inside the fragment shader. I have read the suggestion of using Internal-PrepassLighting.shader as a reference. I am still no able to achieve what I want. I pretty much copy the code out of Internal-PrepassLighting and output the world position as color. I have attached the output image of my shader. The first one shows the scene without the shader, the second with the shader, and the third is with the shader, with the camera tilted.
Here is the C# script:
using UnityEngine;
[RequireComponent (typeof(Camera))]
[AddComponentMenu("")]
public class postfx : MonoBehaviour {
/// Provides a shader property that is set in the inspector
/// and a material instantiated from the shader
public Shader shader;
private Material m_Material;
protected void Start ()
{
// Disable if we don't support image effects
if (!SystemInfo.supportsImageEffects) {
enabled = false;
return;
}
// Disable the image effect if the shader can't
// run on the users graphics card
if (!shader || !shader.isSupported)
enabled = false;
}
protected Material material {
get {
if (m_Material == null) {
m_Material = new Material (shader);
m_Material.hideFlags = HideFlags.HideAndDontSave;
}
return m_Material;
}
}
protected void OnDisable() {
if( m_Material ) {
DestroyImmediate( m_Material );
}
}
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit (source, destination, material);
}
}
And here is the shader code
Shader "Test Post Effect" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass {
ZTest Always
Cull Off
ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_lightpass
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
struct appdata {
float4 vertex : POSITION;
float3 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
float3 ray : TEXCOORD1;
};
v2f vert (appdata v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = ComputeScreenPos (o.pos);
o.ray = mul (UNITY_MATRIX_MV, v.vertex).xyz * float3(-1,-1,1);
// v.texcoord is equal to 0 when we are drawing 3D light shapes and
// contains a ray pointing from the camera to one of near plane's
// corners in camera space when we are drawing a full screen quad.
o.ray = lerp(o.ray, v.texcoord, v.texcoord.z != 0);
return o;
}
sampler2D _CameraDepthTexture;
float4x4 _CameraToWorld;
half4 frag (v2f i) : COLOR
{
i.ray = i.ray * (_ProjectionParams.z / i.ray.z);
float2 uv = i.uv.xy / i.uv.w;
float depth = tex2D (_CameraDepthTexture, uv).r;
depth = Linear01Depth (depth);
float4 vpos = float4(i.ray * depth,1);
float3 wpos = mul (_CameraToWorld, vpos).xyz;
return half4(wpos,1.0f);
}
ENDCG
}
}
Fallback off
}
Can you spot the problem with my code?
Thanks