Backlog/engine/rend/shaders/ssao.frag.hlsl

112 lines
3.8 KiB
HLSL

Texture2D<float4> PositionTexture : register(t0, space2);
SamplerState Sampler0 : register(s0, space2);
Texture2D<float4> NormalTexture : register(t1, space2);
SamplerState Sampler1 : register(s1, space2);
Texture2D<float4> NoiseTexture : register(t2, space2);
SamplerState Sampler2 : register(s2, space2);
#include "randomSamplesFloat3.hlsli"
cbuffer Uniforms : register(b0, space3)
{
float4x4 View;
float4x4 ViewProjection;
float4x4 Projection;
float2 extents;
float radius; // = 0.5;
float bias; // = 0.025;
int numSamples; // up to 64
};
float4 main(float2 UV: TEXCOORD0) : SV_Target0
{
float2 uv = UV;
uv.y *= -1;
uv.y += 1.0;
float2 scale = float2(1280 / 4.0, 720 / 4.0);
float4 c = PositionTexture.Sample(Sampler0, uv);
float3 position = mul(View, PositionTexture.Sample(Sampler0, uv)).xyz;
if (position.z < 0.01)
{
return 1.0;
}
float3 normal = NormalTexture.Sample(Sampler1, uv).xyz;
float3 randomVec = normalize(NoiseTexture.Sample(Sampler2, uv * scale).xyz);
// randomVec = normalize(float3(1.0, 1.0, 0.0) + randomVec * 0.00001);
// randomVec = mul(View, randomVec);
float3 x = normal;
float3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
float3 bitangent = cross(normal, tangent);
float3x3 TBN = transpose(float3x3(tangent, bitangent, normal));
x = tangent;
float occlusion = 0.0;
x = (normal + 1.0) * 0.5; // -1 -> 0 . 1.0 -> 1.0 0 -> 0.5
// x = tangent;
//for(int i = 0; i < numSamples; i += 1)
for(int i = 0; i < numSamples; i += 1)
{
float d = length(SamplingKernel[i]);
//float3 samplePos = mul(TBN, d * normalize(SamplingKernel[i] * float3(1.0, 1.0, 1.0))); //float3(0.0, 0.0, 1.0)); // from tangent to view-space
float3 samplePos = mul(TBN, SamplingKernel[i] + float3(0.0, 0.0, 0.05)); //float3(0.0, 0.0, 1.0)); // from tangent to view-space
samplePos = position + samplePos * radius;
// project sample position (to sample texture) (to get position on screen/texture)
float4 offset = float4(samplePos, 1.0);
// c = offset - float4(position, 1.0);
offset = mul(Projection, offset); // from view to clip-space
offset.xyz /= offset.w; // perspective divide
offset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0
offset.y *= -1;
offset.y += 1.0;
// x += (float3(offset.xy - uv, 0.0) * 0.5 + 0.5) / numSamples;
// get sample depth
float sampleDepth = mul(View, PositionTexture.Sample(Sampler0, offset.xy)).z; // texture(gPosition, offset.xy).z; // get depth value of kernel sample
// x += float3(sampleDepth, sampleDepth, sampleDepth) / numSamples;
// x -= float3(samplePos.z, samplePos.z, samplePos.z) / numSamples;
// c = float4(sampleDepth, sampleDepth, sampleDepth, 1.0) / 100;
// c = float4(offset) * 2.0 - 0.6 ;
// range check & accumulate
float rangeCheck = smoothstep(0.0, 1.0, radius / abs(position.z - sampleDepth));
occlusion += (sampleDepth <= samplePos.z - bias ? 1.0 : 0.0) * rangeCheck;
if (samplePos.z > 30)
{
occlusion *= max(0.0, 1.0 - ((samplePos.z - 30) / 300));
}
}
occlusion = 1.0 - (occlusion / numSamples);
// occlusion = 1.0 - occlusion;
// c += PositionTexture.Sample(Sampler0, uv).x * 0.00001;
// c += NormalTexture.Sample(Sampler1, uv).x * 0.00001;
// c += NoiseTexture.Sample(Sampler2, uv).x * 0.00001;
// float x = length(c);
// c = float4(x, x, x, 1.0);
#if 1
c = occlusion;
#else
c = mul(View, PositionTexture.Sample(Sampler0, uv)).z / 100; // texture(gPosition, offset.xy).z; // get depth value of kernel sample
#endif
//float j = x.z;
//c = float4(x, 1.0);
return c + occlusion * 0.00001;
}