Texture2D PositionTexture : register(t0, space2); SamplerState Sampler0 : register(s0, space2); Texture2D NormalTexture : register(t1, space2); SamplerState Sampler1 : register(s1, space2); Texture2D 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; }