#include "common.h" #ifndef SSAO_QUALITY half calc_ssao( half3 P, half3 N, half2 tc, half2 tcJ) { return 1.0h; } #else // SSAO_QUALITY #if SSAO_QUALITY == 3 #define RINGS 3 #define DIRS 8 static const half rads[4] = { //I know it will be more focused in the cener, but that's OK 0.20000f, 0.57735f, 0.81650f, 1.00000f }; static const half angles[9] = { 0.0000f, 0.7854f, 1.5708f, 2.3562f, 3.1416f, 3.9267f, 4.7124f, 5.4978f, 6.2832f }; #elif SSAO_QUALITY == 2 #define RINGS 3 #define DIRS 4 static const half rads[4] = { //I know it will be more focused in the cener, but that's OK 0.20000f, 0.57735f, 0.81650f, 1.00000f }; static const half angles[5] = { 0.0000f, 1.5708f, 3.1416f, 4.7124f, 6.2832f }; #elif SSAO_QUALITY == 1 #define RINGS 2 #define DIRS 4 static const half rads[3] = { //I know it will be more focused in the cener, but that's OK 0.2000f, 0.7071f, 1.0000f, }; static const half angles[5] = { 0.0000f, 1.5708f, 3.1416f, 4.7124f, 6.2832f }; #endif float4 ssao_params; float4 pos_decompression_params; uniform sampler2D jitter0; float3 uv_to_eye(float2 uv, float eye_z) { uv = (uv * float2(2.0, 2.0) - float2(1.0, 1.0)); return float3(uv * pos_decompression_params.xy * eye_z, eye_z); } // Screen space ambient occlusion // P screen space position of the original point // N screen space normal of the original point // tc G-buffer coordinates of the original point half calc_ssao( half3 P, half3 N, half2 tc, half2 tcJ) { const float ssao_noise_tile_factor = ssao_params.x; const float ssao_kernel_size = ssao_params.y; half point_depth = P.z; if (point_depth<0.01) point_depth = 100000.0h; // filter for the sky // half2 scale = half2 (.5f / 1024.h, .5f / 768.h)*100/point_depth; // half2 scale = half2 (.5f / 1024.h, .5f / 768.h)*100/max(point_depth,1.3); // half2 scale = half2 (.5f / 1024.h, .5f / 768.h)*70/point_depth; // half2 scale = half2 (.5f / 1024.h, .5f / 768.h)*150/max(point_depth,1.3); // Looks better but triggers some strange hardware(?) bug. half2 scale = half2 (.5f / 1024.h, .5f / 768.h)*ssao_kernel_size/max(point_depth,1.3); // half2 scale = half2 (.5f / 1024.h, .5f / 768.h)*min( ssao_kernel_size/point_depth , ssao_kernel_size/1.3 ); // sample half occ = 0.1h; half num_dir = 0.1h; // half occ = 1.0h; // half num_dir = 1.0h; //////////////////////////////// // jittering // half2 Mirror = tex2D( jitter0, tcJ ); // half2 Mirror = half2(1,1); float3 tc1 = mul( m_v2w, float4(P,1) ); tc1 *= ssao_noise_tile_factor; // tc1 *= 2; // tc1 *= 4; tc1.xz += tc1.y; half2 SmallTap = tex2D( jitter0, tc1.xz ); // half2 Mirror = tex2D( jitter0, tc1.xz ); // Mirror = normalize(Mirror); for (int rad=0; rad < RINGS; rad++) { for (int dir=0; dir < DIRS; dir++) { SmallTap.x += 0.31337f; SmallTap.y += 0.73313f; SmallTap = frac(SmallTap); float r = lerp(rads[rad]*1.3, rads[rad+1]*1.3, SmallTap.x); float a = lerp(angles[dir], angles[dir+1], SmallTap.y); float s, c; sincos( a, s, c ); float2 tap = float2( r * c, r * s ); tap *= scale; tap += tc; #ifndef SSAO_OPT_DATA half3 tap_pos = tex2D (s_position,tap); #else // SSAO_OPT_DATA float z = tex2Dlod(s_half_depth,float4(tap, 0, 0)); half3 tap_pos = uv_to_eye(tap, z); #endif // SSAO_OPT_DATA half3 dir = tap_pos-P.xyz; half dist = length(dir); dir = normalize(dir); half infl = saturate(dot( dir, N.xyz)); half occ_factor = saturate(dist); { // occ += lerp( 1, occ_factor, infl); // num_dir += 1; occ += (infl+0.01)*lerp( 1, occ_factor, infl)/(occ_factor+0.1); num_dir += (infl+0.01)/(occ_factor+0.1); // occ += (infl+0.1)*lerp( 1, occ_factor, infl)/(occ_factor+0.1); // num_dir += (infl+0.1)/(occ_factor+0.1); // occ += (infl+0.1)*lerp( 1, occ_factor, infl); // num_dir += (infl+0.1); } } } occ /= num_dir; // occ = lerp(1, occ, saturate(point_depth/1.5f)); occ = saturate(occ); // occ = Contrast(occ,2); // occ = occ*1.5 - 0.5; // occ = occ*occ; // occ = occ*0.5+0.5; #if SSAO_QUALITY==1 occ = (occ+0.3)/(1+0.3); #else // SSAO_QUALITY==1 occ = (occ+0.2)/(1+0.2); #endif // SSAO_QUALITY==1 // occ = 1; float WeaponAttenuation = smoothstep( 0.8, 0.9, length( P.xyz )); occ = lerp( 1, occ, WeaponAttenuation ); return occ; } #endif // SSAO_QUALITY