varying vec3 worldPosition;
const int MaxEvents = 32;
uniform int eventCount;
uniform vec3 events[MaxEvents];
uniform float eventRadius[MaxEvents];
uniform vec2 eventWeightRange[MaxEvents];
// color normalization
uniform float weightMax;
void main()
{
const float eventHeightMax = 16.0;
float weightAccum = 0.0;
for( int i = 0; i < eventCount; i++ )
{
// reject height differences so we dont project through much height variation as we do horizontally
if ( abs( events[ i ].z - worldPosition.z ) < eventHeightMax )
{
// Compute distance between surface and event position
float dist = distance( events[ i ], worldPosition );
if ( dist <= eventRadius[ i ] )
{
float distRatio = clamp( dist / eventRadius[ i ], 0.0, 1.0 );
weightAccum += mix( eventWeightRange[ i ].y, eventWeightRange[ i ].x, distRatio );
}
}
}
// the w component is the weight ratio, rather than alpha
vec4 heatgradient[5];
heatgradient[ 0 ] = vec4( 1.0, 0.0, 0.0, 1.0 ); // red
heatgradient[ 1 ] = vec4( 1.0, 1.0, 0.0, 0.75 ); // yellow
heatgradient[ 2 ] = vec4( 0.0, 1.0, 0.0, 0.50 ); // green
heatgradient[ 3 ] = vec4( 0.0, 0.0, 1.0, 0.25 ); // blue
heatgradient[ 4 ] = vec4( 1.0, 0.0, 1.0, 0.00 ); // magenta
if ( weightAccum > 0.0 )
{
float weightRatio = clamp( weightAccum / weightMax, 0.0, 1.0 );
vec4 col = vec4( 1 );
for ( int i = 1; i < 5; ++i )
{
if ( weightRatio <= heatgradient[ i-1 ].w && weightRatio >= heatgradient[ i ].w )
{
float t = ( weightRatio - heatgradient[ i-1 ].w ) / ( heatgradient[ i ].w - heatgradient[ i-1 ].w );
col = mix( heatgradient[ i-1 ], heatgradient[ i ], t );
}
//col = mix( col, heatgradient[ i ], smoothstep( col.w, heatgradient[ i ].w, weightRatio ));
}
gl_FragColor = col;
gl_FragColor.a = 1.0;
}
else
{
gl_FragColor = vec4( 1.0 );
}
}