#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