#version 400

// NVIDIA driver bug requires this?  (for gl_PrimitiveID)
#extension GL_EXT_gpu_shader4 : enable

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

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

out vec4 result;


// 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 );
	
	// We want different random numbers for each triangle in the model, so we'll select
	//    different random numbers (in our texture) based on the vertexID.
	ivec2 vertOffset = ivec2( int( vertID ) % 1024, int( vertID ) / 1024 );

    // We need a different random number of each sample, so split the texture into blocks
    //    with each block containing the number of samples.  Each pixel onscreen uses all
    //    the random numbers in a block, and each pixel corresponds to 1 block of rnd numbers
    //    In this case, we have 32 samples, so each block is 8x4.
	ivec2 sampOffset = ivec2( gl_SampleID % 8, gl_SampleID / 8 );
	
	// Take the pixel screen-space position (gl_FragCoord), multiplied by the block size,
	//    plus the block offset (i.e., per-sample location in the block) to find the 
	//    sample coordinate for the random texture.   Also add in an optional random 
	//    offset ( [0..1]^2 ) from the CPU code -- this allows different bits of geometry
	//    covering the same pixel to use different sets of random numbers.
	ivec2 sampCoord = ivec2( gl_FragCoord.x*8, gl_FragCoord.y*4 ) + sampOffset + vertOffset + ivec2( randOffset*size );
	
	// Based on the sample offset above, do some modulo math to take everything to 
	//   [0..size.x] x [0..size.y], then divide to get texCoords in [0..1]^2.
	vec2 texCoords  = vec2( sampCoord.x % size.x, sampCoord.y % size.y ) / vec2( size );

    // Look up the random number for the current pixel sample
	vec4 rnd = texture( randTex, texCoords );

	// If this random sample is too small, discard.
	if( (color.a) < rnd.x )
		discard;
		
	result = color * abs( dot( normalize( esFragNormal.xyz ), normalize( -esFragPos.xyz ) ) );	
}