#version 400

uniform sampler2D randTex;
uniform vec4 color;
uniform vec2 randOffset;
uniform int  numSamples;

in vec2 fragTexCoord;
in vec4 esFragNormal;
in vec4 esFragPos;
in float vertID;

out vec4 result;

// This takes the random number seed for this pixel and increments it,
//   returning the next pseudorandom number in the sequence
float RandomNumber( inout uint prev )
{
  const uint LCG_A = 1664525u;
  const uint LCG_C = 1013904223u;
  prev = (LCG_A * prev + LCG_C);
  return ( float(prev & 0x00FFFFFF) / float(0x01000000) );
}


// This is the actual code that is executed.
void main( void )
{                        
	// Get the size of our random texture in pixels
	ivec2 size      = textureSize( randTex, 0 );
	
	// Get our random texture seed.
	ivec2 vertOffset = ivec2( int( vertID ) % 1024, int( vertID ) / 1024 );
	ivec2 sampCoord  = ivec2( gl_FragCoord ) + vertOffset + ivec2( randOffset*size );
	vec2 texCoords   = vec2( sampCoord.x % size.x, sampCoord.y % size.y ) / vec2( size );
	float rnd = texture( randTex, texCoords ).x;
	uint rndSeed = uint( rnd*0xFFFF );

	// Identify which of the pixel samples have been covered
	//    -> This segment is unstratified (i.e., independently random samples)
	uint coverage = 0x0;
	for (uint i=0; i<numSamples; i++)
		coverage |= ( color.a < RandomNumber( rndSeed ) ) ? 0x0u : (0x1u << i);	
	if ( bitCount(coverage) <= 0 )
		discard;
	
	
	// Output the color to the appropriate multisamples
	result = vec4( color.xyz * abs( dot( normalize( esFragNormal.xyz ), normalize( -esFragPos.xyz ) ) ), 1.0f );	
	gl_SampleMask[0] = int(coverage);
}