48                              const SFVEC3F& cnorm, 
const float aShadowAtSamplePos,
 
   49                              const float aShadowAtCenterPos, 
int c1, 
int c2 )
 const 
   51    const float shadowGain = 0.60f;
 
   52    const float aoGain = 1.0f;
 
   54    const float shadow_factor_at_sample = ( 1.0f - aShadowAtSamplePos ) * shadowGain;
 
   55    const float shadow_factor_at_center = ( 1.0f - aShadowAtCenterPos ) * shadowGain;
 
   57    float return_value = shadow_factor_at_center;
 
   59    const float rd = glm::length( ddiff );
 
   64        if( rd > FLT_EPSILON )
 
   66            const SFVEC3F vv = glm::normalize( ddiff );
 
   74            const float attDistFactor = 1.0f / ( rd * rd * 8.0f + 1.0f );
 
   78            float sampledNormalFactor = glm::max( glm::dot( 
GetNormalAt( vr ), cnorm ), 0.0f );
 
   80            sampledNormalFactor = glm::max( 1.0f - sampledNormalFactor *
 
   81                                            sampledNormalFactor, 0.0f );
 
   83            const float shadowAttDistFactor = glm::max( glm::min( rd * 5.0f - 0.25f, 1.0f ), 0.0f );
 
   85            float shadowAttFactor = glm::min( sampledNormalFactor + shadowAttDistFactor, 1.0f );
 
   87            const float shadowFactor = glm::mix( shadow_factor_at_sample, shadow_factor_at_center,
 
   93            const float aDotThreshold = 0.15f;
 
   97            const float localNormalFactor = glm::dot( cnorm, vv );
 
   99            const float localNormalFactorWithThreshold =
 
  100                    ( glm::max( localNormalFactor, aDotThreshold ) - aDotThreshold ) /
 
  101                    ( 1.0f - aDotThreshold );
 
  103            const float aoFactor = localNormalFactorWithThreshold * aoGain * attDistFactor;
 
  105            return_value = glm::min( aoFactor + shadowFactor, 1.0f );
 
 
  114                              const SFVEC3F& cnorm, 
const float aShadow, 
int c1, 
int c2 )
 const 
  116    if( ( ddiff.x > FLT_EPSILON ) || ( ddiff.y > FLT_EPSILON ) || ( ddiff.z > FLT_EPSILON ) )
 
  118        const SFVEC3F vv = glm::normalize( ddiff );
 
  119        const float rd = glm::length( ddiff );
 
  122        const float attDistFactor = 1.0f / ( rd * rd + 1.0f );
 
  124        return ( glm::clamp( glm::dot( 
GetNormalAt( vr ), -vv), 0.0f, 1.0f ) *
 
  125                 glm::clamp( glm::dot( cnorm, vv ), 0.0f, 1.0f ) * attDistFactor ) *
 
  126                 ( 0.03f + aShadow ) * 3.0f;
 
 
  137    if( cdepth > FLT_EPSILON )
 
  139        cdepth = ( 30.0f / ( cdepth * 2.0f + 1.0f ) );
 
  152        for( 
unsigned int i = 0; i < 
ROUNDS; ++i )
 
  154            static const int limit[
ROUNDS] = { 0x01, 0x03, 0x03 };
 
  159            const int npw = (int) ( ( pw + i ) * cdepth ) + ( i + 1 );
 
  160            const int nph = (int) ( ( ph + i ) * cdepth ) + ( i + 1 );
 
  180            ao += 
aoFF( aShaderPos, ddiff , n, shadowAt1, shadowAt0,  npw,  nph );
 
  181            ao += 
aoFF( aShaderPos, ddiff2, n, shadowAt2, shadowAt0,  npw, -nph );
 
  182            ao += 
aoFF( aShaderPos, ddiff3, n, shadowAt3, shadowAt0, -npw,  nph );
 
  183            ao += 
aoFF( aShaderPos, ddiff4, n, shadowAt4, shadowAt0, -npw, -nph );
 
  184            ao += 
aoFF( aShaderPos, ddiff5, n, shadowAt5, shadowAt0,   pw,  nph );
 
  185            ao += 
aoFF( aShaderPos, ddiff6, n, shadowAt6, shadowAt0,   pw, -nph );
 
  186            ao += 
aoFF( aShaderPos, ddiff7, n, shadowAt7, shadowAt0,  npw,   ph );
 
  187            ao += 
aoFF( aShaderPos, ddiff8, n, shadowAt8, shadowAt0, -npw,   ph );
 
  189            gi += 
giFF( aShaderPos, ddiff , n, shadowAt1, npw,  nph) *
 
  191            gi += 
giFF( aShaderPos, ddiff2, n, shadowAt2, npw, -nph) *
 
  193            gi += 
giFF( aShaderPos, ddiff3, n, shadowAt3, -npw,  nph) *
 
  195            gi += 
giFF( aShaderPos, ddiff4, n, shadowAt4, -npw, -nph) *
 
  197            gi += 
giFF( aShaderPos, ddiff5, n, shadowAt5 , pw, nph) *
 
  199            gi += 
giFF( aShaderPos, ddiff6, n, shadowAt6,  pw,-nph) *
 
  201            gi += 
giFF( aShaderPos, ddiff7, n, shadowAt7,  npw, ph) *
 
  203            gi += 
giFF( aShaderPos, ddiff8, n, shadowAt8, -npw, ph) *
 
  209        const float reduceAOwhenNoShadow = 
m_isUsingShadows ? ( 1.0f - shadowAt0 * 0.3f ) : 1.0f;
 
  211        ao = reduceAOwhenNoShadow * ( ao / ( 
ROUNDS * 8.0f ) );
 
  213        ao = ( 1.0f - 1.0f / ( ao * ao * 5.0f + 1.0f ) ) * 1.2f;
 
  215        gi = ( gi / ( 
ROUNDS * 8.0f ) );
 
  217        float giL = glm::min( glm::length( gi ) * 4.0f, 1.0f );
 
  219        giL = ( 1.0f - 1.0f / ( giL * 4.0f + 1.0f ) ) * 1.5f;
 
  221        return glm::mix( 
SFVEC3F( ao ), -gi, giL );
 
 
  231                                           const SFVEC3F& aShadeColor )
 const 
  234    SFVEC3F inColor( aInputColor );
 
  236    const SFVEC3F subtracted = inColor - aShadeColor;
 
  237    const SFVEC3F mixed = glm::mix( inColor, inColor * 0.50f - aShadeColor * 0.05f,
 
  238                                    glm::min( aShadeColor, 1.0f ) );
 
  240    outColor.r = ( aShadeColor.r < 0.0f ) ? subtracted.r : mixed.r;
 
  241    outColor.g = ( aShadeColor.g < 0.0f ) ? subtracted.g : mixed.g;
 
  242    outColor.b = ( aShadeColor.b < 0.0f ) ? subtracted.b : mixed.b;
 
  243    outColor.a = std::max( aInputColor.a, ( aShadeColor.r + aShadeColor.g + aShadeColor.b ) / 3 );
 
 
  275    const float dCenter = 
GetDepthAt( aShaderPos );
 
  279    float totalWeight = 1.0f;
 
  281    for( 
int y = -3; y < 3; y++ )
 
  283        for( 
int x = -3; x < 3; x++ )
 
  286            const unsigned int idx = 
GetIndex( 
SFVEC2I( aShaderPos.x + x, aShaderPos.y + y ) );
 
  290            if( !( ( x == 0 ) && ( y == 0 ) ) )
 
  296                const float depthAtt = ( dCenter - d ) * dCenter * 25.0f;
 
  298                const float depthAttSqr = depthAtt * depthAtt;
 
  300                float weight = ( 1.0f / ( depthAttSqr + 1.0f ) ) - 0.02f * depthAttSqr;
 
  302                weight = glm::max( weight, 0.0f );
 
  304                shadedOut += s * weight;
 
  305                totalWeight += weight;
 
  314    return shadedOut / totalWeight;
 
 
float aoFF(const SFVEC2I &aShaderPos, const SFVEC3F &ddiff, const SFVEC3F &cnorm, const float aShadowAtSamplePos, const float aShadowAtCenterPos, int c1, int c2) const
 
SFVEC3F giColorCurveShade(const SFVEC4F &aColor) const
 
float giFF(const SFVEC2I &aShaderPos, const SFVEC3F &ddiff, const SFVEC3F &cnorm, const float aShadow, int c1, int c2) const
 
SFVEC4F ApplyShadeColor(const SFVEC2I &aShaderPos, const SFVEC4F &aInputColor, const SFVEC3F &aShadeColor) const override
Apply the final color process using a previous stage color.
 
SFVEC3F Shade(const SFVEC2I &aShaderPos) const override
 
POST_SHADER_SSAO(const CAMERA &aCamera)
 
SFVEC3F giColorCurve(const SFVEC3F &aColor) const
Apply a curve transformation to the original color.
 
SFVEC3F Blur(const SFVEC2I &aShaderPos) const
 
unsigned int GetIndex(const SFVEC2F &aPos) const
 
POST_SHADER(const CAMERA &aCamera)
 
const SFVEC4F & GetColorAt(const SFVEC2F &aPos) const
 
const SFVEC3F & GetNormalAt(const SFVEC2F &aPos) const
 
const SFVEC3F & GetPositionAt(const SFVEC2F &aPos) const
 
const float & GetShadowFactorAt(const SFVEC2I &aPos) const
 
float GetDepthAt(const SFVEC2F &aPos) const
 
Implements a post shader screen space ambient occlusion on software.