Divergent/mods/Shaders Look Better/gamedata/shaders/r3/slb_shadow_normal.h

63 lines
2.6 KiB
C
Raw Permalink Normal View History

#ifndef SLB_SHADOW_NORMAL_H
#define SLB_SHADOW_NORMAL_H
float3 SLB_Shadow_ViewSpacePosAtScreenUV(float2 pos) {
return float3(pos.x, pos.y, SLB_Shadow_Sample(pos)); // * float2(float(SMAP_size), 1.0).xxy;
}
float3 SLB_Shadow_Normal(float2 vpos) {
float2 texelSize = float2(1.0, 1.0)/float2(float(SMAP_size), float(SMAP_size));
// screen uv from vpos
float2 uv = floor(vpos/texelSize)*texelSize;
// current pixel's depth
float c = SLB_Shadow_Sample(uv);
// get current pixel's view space position
float3 viewSpacePos_c = SLB_Shadow_ViewSpacePosAtScreenUV(uv);
// get view space position at 1 pixel offsets in each major direction
float3 viewSpacePos_l = SLB_Shadow_ViewSpacePosAtScreenUV(uv + float2(-1.0, 0.0) * texelSize);
float3 viewSpacePos_r = SLB_Shadow_ViewSpacePosAtScreenUV(uv + float2( 1.0, 0.0) * texelSize);
float3 viewSpacePos_d = SLB_Shadow_ViewSpacePosAtScreenUV(uv + float2( 0.0,-1.0) * texelSize);
float3 viewSpacePos_u = SLB_Shadow_ViewSpacePosAtScreenUV(uv + float2( 0.0, 1.0) * texelSize);
// get the difference between the current and each offset position
float3 l = viewSpacePos_c - viewSpacePos_l;
float3 r = viewSpacePos_r - viewSpacePos_c;
float3 d = viewSpacePos_c - viewSpacePos_d;
float3 u = viewSpacePos_u - viewSpacePos_c;
// get depth values at 1 & 2 pixels offsets from current along the horizontal axis
float4 H = float4(
SLB_Shadow_Sample(uv + float2(-1.0, 0.0) * texelSize),
SLB_Shadow_Sample(uv + float2( 1.0, 0.0) * texelSize),
SLB_Shadow_Sample(uv + float2(-2.0, 0.0) * texelSize),
SLB_Shadow_Sample(uv + float2( 2.0, 0.0) * texelSize)
);
// get depth values at 1 & 2 pixels offsets from current along the vertical axis
float4 V = float4(
SLB_Shadow_Sample(uv + float2(0.0,-1.0) * texelSize),
SLB_Shadow_Sample(uv + float2(0.0, 1.0) * texelSize),
SLB_Shadow_Sample(uv + float2(0.0,-2.0) * texelSize),
SLB_Shadow_Sample(uv + float2(0.0, 2.0) * texelSize)
);
// current pixel's depth difference from slope of offset depth samples
// differs from original article because we're using non-linear depth values
// see article's comments
float2 he = abs((2 * H.xy - H.zw) - c);
float2 ve = abs((2 * V.xy - V.zw) - c);
// pick horizontal and vertical diff with the smallest depth difference from slopes
float3 hDeriv = he.x < he.y ? l : r;
float3 vDeriv = ve.x < ve.y ? d : u;
// get view space normal from the cross product of the best derivatives
float3 viewNormal = normalize(cross(hDeriv, vDeriv));
return viewNormal;
}
#endif /// SLB_SHADOW_NORMAL_H