#version 400
#extension GL_EXT_gpu_shader4 : enable

// Input from our geometry shader.
in vec3 epSpAngles;

// How many MRT layers are we using?
uniform uint numLayers;

// Output buffers
layout(location = 0) out uvec4 fragOutput0;
layout(location = 1) out uvec4 fragOutput1;
layout(location = 2) out uvec4 fragOutput2;
layout(location = 3) out uvec4 fragOutput3;


uvec4 SetBit( uint whichBit )
{
	// Compute how many bits are required to shift the particular bit into place,
	//    assuming it is in the current color channel.  If the bit specified is in 
	//    particular color channel (32-bit tuples), then shiftBits for that channel
	//    will be in [0..31].  Values outside that range mean the bit is not in
	//    the channel.
	uvec4 shiftBits = uvec4( whichBit ) - uvec4( 0u, 32u, 64u, 96u );
	
	// Set a bit in the lowest bit of the correct color channel.  To do this, we 
	//    check if any bit besides the first 5 is set (the & followed by the min),
	//    which returns a 1 in channels not in the range [0..31] and a 0 elsewhere.
	//    We then invert this (1-val) to get a 0 in channels without the current
	//    bit, and a 1 in the channel with the bit.
	uvec4 bitToShift = uvec4(1u) - min( uvec4(1u), shiftBits & uvec4(0xFFFFFFE0u) );
	
	// Shift the correct bit into place
	return bitToShift << shiftBits;
}

void main( void )
{
	// Figure out which z-voxel this sample should be rasterized into
	int iDepth =  int( (epSpAngles.z/3.14159265358979) * 128.0 * float(numLayers) );
	
	uvec4 b0 = SetBit( uint(iDepth) ) | SetBit( uint(iDepth+1) ) | SetBit( uint(iDepth-1) );
	uvec4 b1 = SetBit( uint(iDepth-128) ) | SetBit( uint(iDepth-127) ) | SetBit( uint(iDepth-129) );
	uvec4 b2 = SetBit( uint(iDepth-256) ) | SetBit( uint(iDepth-255) ) | SetBit( uint(iDepth-257) );
	uvec4 b3 = SetBit( uint(iDepth-384) ) | SetBit( uint(iDepth-383) ) | SetBit( uint(iDepth-385) );
	
	// Output the bits for the appropriate layers
	fragOutput0 = ( (iDepth     > 0) && (iDepth     < 128) ) ? b0 : uvec4( 0u );
	fragOutput1 = ( (iDepth-128 > 0) && (iDepth-128 < 128) ) ? b1 : uvec4( 0u );
	fragOutput2 = ( (iDepth-256 > 0) && (iDepth-256 < 128) ) ? b2 : uvec4( 0u );
	fragOutput3 = ( (iDepth-384 > 0) && (iDepth-384 < 128) ) ? b3 : uvec4( 0u );
}