//TEXTURE

uniform sampler2D txColorFront;
uniform sampler2D txColorBack;
uniform sampler3D txVolume;
uniform sampler2D txNoise;

//QUALITY PERFORMANCE

uniform float stepSize;	
uniform int   maxSamples;
uniform bool  applyNoise;

//TEXTURE ACCESS 

varying vec2 fragpos;

//LIGHTDIR

//GLOBAL FRAGVARS 

vec3  rayStart;
vec3  rayEnd;
vec3  rayDir;
float rayLength;
float rayStep;
vec3  samplePos;

//GLOBAL SAMPLEVARS

float density;
vec4  sampleCol;

 /*********************** DVR FRAGMENT SHADER *****************\
|*                                                             *|
|*  APPROACH : BACK FRONT COLOR TEXTURES MIP                   *|
|*  VERSION  : 1.2                                             *|
|*  (c)      : Robert Hausmair                                 *|
|*                                                             *|
 \*************************************************************/

void main(){

	/*-----------------------------*/
	/*---INIT FOR EVERY FRAGMENT---*/
	/*-----------------------------*/

	rayStart  = texture2D(txColorFront,fragpos).xyz;
	rayEnd    = texture2D(txColorBack,fragpos).xyz;
	rayDir    = normalize(rayEnd - rayStart);
	rayLength = length(rayEnd - rayStart);
	rayStep   = 0.0;
		
	// STOCHASTIC RAY SHIFTING

	if(applyNoise)
	{
		rayStart  += (texture2D(txNoise,fragpos).r)  * stepSize * 5 *  rayDir;
	}

	/*-----------------------------------------*/ 
	/*---RAYMARCHING AND SAMPLE ACCUMULATION---*/
	/*-----------------------------------------*/ 

	float mipMax = 0.0;

	for(int i = 0 ; i < maxSamples ; i++)
	{
		samplePos = rayStart + (rayDir * rayStep);
		density   = texture3D(txVolume,samplePos).a;
				
		if(density > mipMax)
		{
			mipMax = density;
		}

		/*--------------------*/ 
		/*---STOP CONDITION---*/	
		/*--------------------*/ 	
		
		if( (rayStep += stepSize) > rayLength || mipMax == 1.0)
		{
			i = maxSamples;
		}
	}	

	/*--------------------*/
	/*-------OUTPUT-------*/
	/*--------------------*/
	
	gl_FragColor = vec4(mipMax);
}