I have tried to make this shader as a post process shader…
But I am having trouble converting viewPos into screenPos.
Basically, I need to convert view space position into screen space position using projecting matrix, but I can’t make it work for the post processing shader.
It works for non-post process shader.
Please note that this is an experiment shader code.
Shader "Custom/SSRPostProcess"
{
Properties
{
_MainTex ("Base (RGB)", any) = "" {}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma exclude_renderers d3d11 xbox360
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
#pragma glsl
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _MainTex_TexelSize;
uniform sampler2D _backgroundTexture;
uniform float _fadeToView;
uniform float4x4 _inverseProjection;
uniform float4x4 _ProjMatrix;
uniform float4x4 _ProjectionInv;
uniform float4 _ProjInfo;
sampler2D _CameraNormalsTexture;
sampler2D _CameraDepthNormalsTexture;
float4 _CameraDepthNormalsTexture_ST;
sampler2D _CameraDepthTexture;
float4 _CameraDepthTexture_ST;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
float3 ReconstructCSPosition(float2 S, float z)
{
float linEyeZ = LinearEyeDepth(z);
return float3(( ( S.xy * _MainTex_TexelSize.zw) * _ProjInfo.xy + _ProjInfo.zw) * linEyeZ, linEyeZ);
}
float4 ReconstructViewPosition(float2 S, float z)
{
// for reference
float4 clipPos = float4(S*2.0-1.0, (z*2-1), 1);
float4 viewPos;
viewPos.x = dot((float4)_ProjectionInv[0], clipPos);
viewPos.y = dot((float4)_ProjectionInv[1], clipPos);
viewPos.w = dot((float4)_ProjectionInv[3], clipPos);
viewPos.z = -z;
viewPos = viewPos/viewPos.w;
return viewPos;
}
half4 frag (v2f i) : COLOR
{
float4 geom = tex2D(_CameraDepthNormalsTexture,i.uv);
float3 viewNormal;
float depth;
// ths is to get a view normal
DecodeDepthNormal(geom,depth,viewNormal);
// just get Z again from depthmap because I don't want linear Z from 0-1 initially..(I think)
float d = ( tex2D(_CameraDepthTexture, i.uv.xy) );
float3 scrPos = float3(i.uv * 2 -1,d);
float4 viewPos = ReconstructViewPosition(i.uv,d);
float3 vspReflect = normalize(reflect(normalize(viewPos.xyz), normalize(viewNormal)));
// I think the problem is here
//float4 vspPosReflectT = mul (UNITY_MATRIX_P,viewPos+float4(vspReflect,1));
float4 vspPosReflectT = mul (_ProjMatrix, viewPos +float4(vspReflect,1));
float3 vspPosReflect = vspPosReflectT.xyz / vspPosReflectT.w;
// subtract to get a vector.. (sub from end to start)
float3 sspReflect = normalize( vspPosReflect - scrPos );
sspReflect = float3(sspReflect.xy*0.5f,sspReflect.z);
//initial stepping scalse value.. not sure about this neither
float stepScale = 2/_ScreenParams.x/length(sspReflect.xy);
stepScale = 0.002;
float4 c;
float sampleDepth;
float currentDepth;
float depthTest = 0;
float len = 0;
int maxCount =164;
float4 r = 0;
float bias = 0.001;
float rcpfadefact = 1/(1.0 - _fadeToView);
float faceviewerfactor = (vspReflect.z - _fadeToView) * rcpfadefact;
faceviewerfactor = 1-faceviewerfactor;
float3 startPosSS = float3(i.uv,scrPos.z);
float3 sspReflectFinal = sspReflect;
sspReflectFinal *= stepScale * 1;
c = tex2D (_MainTex,i.uv);
float deltaD = 0;
float3 samplePos = startPosSS + sspReflectFinal;
float3 oldPos = startPosSS;
int cnt=1;
// ray march
while (cnt < maxCount)
{
geom = tex2Dlod (_CameraDepthNormalsTexture, float4(samplePos.xy,0,0));
sampleDepth = DecodeFloatRG(geom.zw);
currentDepth = Linear01Depth(samplePos.z);
if ( sampleDepth < currentDepth)
{
deltaD = (currentDepth - sampleDepth);
if (deltaD < bias)
{
depthTest = 1;
cnt = maxCount+1;
break;
}
else
{
sspReflectFinal *= 0.5;
samplePos = oldPos + sspReflectFinal;
}
}
else
{
oldPos = samplePos;
sspReflectFinal *= 1.1;
samplePos += sspReflectFinal;
}
len += 1;
cnt += 1;
}
float3 endP = float3(samplePos.x*2-1 , samplePos.y*2-1,samplePos.z);
float dist = abs((distance(scrPos.xyz,endP)));
r = tex2D(_MainTex,samplePos.xy);
r *= faceviewerfactor* faceviewerfactor;
r *= (1- pow(dist,1));
r *= depthTest;
return c + saturate(r)*0.5f ;
}
ENDCG
}
}
}
I think this line here is the problem… (not 100% sure but)
float4 vspPosReflectT = mul (UNITY_MATRIX_P,viewPos+float4(vspReflect,1));
This works for non post process shader, but for some reason doing this and then doing the next line
float3 vspPosReflect = vspPosReflectT.xyz / vspPosReflectT.w;
doesn’t give me the correct result. For some reason vspPosReflectT.w part is wrong…
Any ideas?