Removed SSAO test from CPC shader

This commit is contained in:
Robert Beckebans 2024-07-31 21:30:35 +02:00
parent 9fb21205f1
commit 21645ee262

View file

@ -175,138 +175,6 @@ float BlueNoise( float2 n, float x )
return noise;
}
// Total number of direct samples to take at each pixel
#define NUM_SAMPLES 11
// This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent
// taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9
#define NUM_SPIRAL_TURNS 7
// If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower
// miplevel to maintain reasonable spatial locality in the cache
// If this number is too small (< 3), too many taps will land in the same pixel, and we'll get bad variance that manifests as flashing.
// If it is too high (> 5), we'll get bad performance because we're not using the MIP levels effectively
#define LOG_MAX_OFFSET (3)
// This must be less than or equal to the MAX_MIP_LEVEL defined in SAmbientOcclusion.cpp
#define MAX_MIP_LEVEL (5)
#define MIN_MIP_LEVEL 0
#define USE_MIPMAPS 1
static const float radius = 1.0 * METERS_TO_DOOM;
static const float radius2 = radius * radius;
static const float invRadius2 = 1.0 / radius2;
/** Bias to avoid AO in smooth corners, e.g., 0.01m */
static const float bias = 0.01 * METERS_TO_DOOM;
/** intensity / radius^6 */
static const float intensity = 0.6;
static const float intensityDivR6 = intensity / ( radius* radius* radius* radius* radius* radius );
/** The height in pixels of a 1m object if viewed from 1m away.
You can compute it from your projection matrix. The actual value is just
a scale factor on radius; you can simply hardcode this to a constant (~500)
and make your radius value unitless (...but resolution dependent.) */
static const float projScale = 500.0;
float fallOffFunction( float vv, float vn, float epsilon )
{
// A: From the HPG12 paper
// Note large epsilon to avoid overdarkening within cracks
// Assumes the desired result is intensity/radius^6 in main()
// return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6;
// B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended]
//
// Epsilon inside the sqrt for rsqrt operation
float f = max( 1.0 - vv * invRadius2, 0.0 );
return f * max( ( vn - bias ) * rsqrt( epsilon + vv ), 0.0 );
}
float aoValueFromPositionsAndNormal( float3 C, float3 n_C, float3 Q )
{
float3 v = Q - C;
//v = normalize( v );
float vv = dot( v, v );
float vn = dot( v, n_C );
const float epsilon = 0.001;
// Without the angular adjustment term, surfaces seen head on have less AO
return fallOffFunction( vv, vn, epsilon ) * lerp( 1.0, max( 0.0, 1.5 * n_C.z ), 0.35 );
}
void computeMipInfo( float ssR, int2 ssP, out int mipLevel, out int2 mipP )
{
// Derivation:
// mipLevel = floor(log(ssR / MAX_OFFSET));
#ifdef GL_EXT_gpu_shader5
mipLevel = clamp( findMSB( int( ssR ) ) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL );
#else
mipLevel = clamp( int( floor( log2( ssR ) ) ) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL );
#endif
// We need to divide by 2^mipLevel to read the appropriately scaled coordinate from a MIP-map.
// Manually clamp to the texture size because texelFetch bypasses the texture unit
// used in newer radiosity
//mipP = ssP >> mipLevel;
mipP = clamp( ssP >> mipLevel, _int2( 0 ), textureSize( t_Depth, mipLevel ) - _int2( 1 ) );
}
float3 getOffsetPosition( int2 issC, float2 unitOffset, float ssR, float invCszBufferScale )
{
int2 ssP = int2( ssR * unitOffset ) + issC;
float3 P;
int mipLevel;
int2 mipP;
computeMipInfo( ssR, ssP, mipLevel, mipP );
#if USE_MIPMAPS
// RB: this is the key for fast ambient occlusion - use a hierarchical depth buffer
// for more information see McGuire12SAO.pdf - Scalable Ambient Obscurance
// http://graphics.cs.williams.edu/papers/SAOHPG12/
P.z = t_Depth.Load( int3( mipP, mipLevel ) ).r;
#else
P.z = t_Depth.Load( int3( mipP, 0 ) ).r;
#endif
// Offset to pixel center
P = ReconstructPosition( float2( ssP ) + _float2( 0.5 ), P.z );
return P;
}
float2 tapLocation( int sampleNumber, float spinAngle, out float ssR )
{
// Radius relative to ssR
float alpha = ( float( sampleNumber ) + 0.5 ) * ( 1.0 / float( NUM_SAMPLES ) );
float angle = alpha * ( float( NUM_SPIRAL_TURNS ) * 6.28 ) + spinAngle;
ssR = alpha;
return float2( cos( angle ), sin( angle ) );
}
float sampleAO( int2 issC, float3 C, float3 n_C, float ssDiskRadius, int tapIndex, float randomPatternRotationAngle, float invCszBufferScale )
{
// Offset on the unit disk, spun for this pixel
float ssR;
float2 unitOffset = tapLocation( tapIndex, randomPatternRotationAngle, ssR );
// Ensure that the taps are at least 1 pixel away
ssR = max( 0.75, ssR * ssDiskRadius );
// The occluding point in camera space
float3 Q = getOffsetPosition( issC, unitOffset, ssR, invCszBufferScale );
return aoValueFromPositionsAndNormal( C, n_C, Q );
}
float3 ditherRGB( float2 fragPos, float3 quantDeviation )
{
float2 uvDither = fragPos / ( RESOLUTION_DIVISOR / rpJitterTexScale.x );
@ -598,29 +466,6 @@ void main( PS_IN fragment, out PS_OUT result )
//result.color = float4( n_C * 0.5 + 0.5, 1.0 );
//return;
#if 0
// SSAO to test the ReconstructPosition function
float vis = 1.0;
//float randomPatternRotationAngle = BlueNoise( float2( ssP.xy ), 10.0 ) * 10.0;
float randomPatternRotationAngle = InterleavedGradientNoise( ssP.xy ) * 10.0;
float ssDiskRadius = -projScale * radius / C.z;
float sum = 0.0;
for( int i = 0; i < NUM_SAMPLES; ++i )
{
sum += sampleAO( ssP, C, n_C, ssDiskRadius, i, randomPatternRotationAngle, 1.0 );
}
float A = pow( max( 0.0, 1.0 - sqrt( sum * ( 3.0 / float( NUM_SAMPLES ) ) ) ), intensity );
const float minRadius = 3.0;
vis = lerp( 1.0, A, saturate( ssDiskRadius - minRadius ) );
result.color = float4( _float3( vis ), 1.0 );
return;
#endif
// triplanar UVs
float3 worldPos = C;