31#include "../3d_fastmath.h"
36 m_shadedBuffer( nullptr ),
37 m_isUsingShadows( false )
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 );
257 return vec1 - ( vec1 / (aColor *
SFVEC3F(9.0f) + vec1) ) + aColor *
SFVEC3F(0.10f);
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;
A class used to derive camera objects from.
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
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.