Danbias/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/SSAO.hlsli

50 lines
1.5 KiB
HLSL

#include "Defines.hlsli"
#include "PosManipulation.hlsli"
static float Radius =5;
float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID)
{
float occlusion = 0.0f;
//create sample coordinate system
float4 rnd = float4( SSAORand[(rndID.x + rndID.y) % SSAORand.Length.x].xyz, 0.0f );
rnd = normalize(rnd);
float3 normal = NormalSpec[uv].xyz;
float4 tangent = float4( normalize(rnd.xyz - (normal * dot(rnd.xyz, normal))), 0.0f );
float4 biTangent = float4( cross(tangent.xyz, normal), 0.0f );
float4x4 tbn = float4x4(tangent, biTangent, float4(normal,0), float4(pos*Radius,1));
for( uint i = 0; i < SSAOKernel.Length.x; ++i )
{
//take sample from localspace to viewspace
float4 sampled = mul(tbn, float4(SSAOKernel[i].xyz,1));
//project sample to get uv.xy
float4 ProjOffset = sampled;
ProjOffset = mul(Proj, ProjOffset);
float4 offset = ProjOffset;
float2 UV = offset.xy;
offset /= offset.w;
offset.xyz = offset.xyz * 0.5f + 0.5f;
//extra invert y axis, DX11
offset.y = 1.0f - offset.y;
// get depth from that point in screenspace
uint2 texCoord;
texCoord = (uint2)(offset.xy * Pixels);
float3 ViewPos = ToVpos(texCoord, UV);
float sampleDepth = ViewPos.z;
//compare to depth from sample
float rangeCheck = (abs(pos.z - sampleDepth) < Radius) ? 1.0f : 0.0f;
occlusion += (sampleDepth >= sampled.z ? 1.0f : 0.0f) * rangeCheck;
}
occlusion /= (float)(SSAOKernel.Length.x);
occlusion = 1.0f - occlusion;
return occlusion;
}