const float ETA = 1.4; // oil index of refraction const float LAMBDAMIN = 400.; // blue const float LAMBDAMAX = 600.; // red const vec4 BLACK = vec4( 0., 0., 0., 0. ); varying vec3 MCposition; varying vec3 Center; uniform sampler3D Noise3; uniform float MaxHeight; uniform float NoiseMag; uniform float Tol; uniform float A; uniform float B; vec3 Rainbow( float t ) { t = clamp( t, 0., 1. ); vec3 rgb = vec3( 0., 0., 0. ); // b -> c if( t >= 0. ) { // rgb.r = 0.; rgb.g = 4. * ( t - (0./4.) ); rgb.b = 1.; } // c -> g if( t >= (1./4.) ) { // rgb.r = 0.; rgb.g = 1.; rgb.b = 1. - 4. * ( t - (1./4.) ); } // g -> y if( t >= (2./4.) ) { rgb.r = 4. * ( t - (2./4.) ); rgb.g = 1.; // rgb.b = 0.; } // y -> r if( t >= (3./4.) ) { rgb.r = 1.; rgb.g = 1. - 4. * ( t - (3./4.) ); // rgb.b = 0.; } return rgb; } int AssignRGB( in float lambda, out vec3 color ) { if( lambda < LAMBDAMIN || lambda > LAMBDAMAX ) return 0; float t = ( lambda - LAMBDAMIN ) / ( LAMBDAMAX - LAMBDAMIN ); color = Rainbow( t ); return 1; } void main( void ) { vec4 nv = texture3D( Noise3, MCposition ); float rad = distance( MCposition.xy, Center.xy ) + NoiseMag * ( nv[0] - 0.5 ); gl_FragColor = BLACK; float d = MaxHeight * exp( -A*rad*rad ); int mmin = int( floor( 2.*d*ETA/LAMBDAMAX - .5 ) ); int mmax = int( ceil( 2.*d*ETA/LAMBDAMIN - .5 ) ); if( mmin > 0 ) { vec3 color = vec3( 0., 0., 0. ); int count = 0; for( int m = mmin; m <= mmax; m++ ) { float lambda = 2.*d*ETA / ( float(m) + .5 ); vec3 col; int status = AssignRGB( lambda, col ); if( status > 0 ) { color += col; count++; } } if( count > 0 ) gl_FragColor = vec4( color / float(count), 1. ); } }