Commit f5c767e8 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[ADD] - added several other colormaps. Added DOC to them and added a more...

[ADD] - added several other colormaps. Added DOC to them and added a more generic way for value-based clipping.
parent 44c2ec52
......@@ -64,8 +64,37 @@ float clipZero( in float valueDescaled, in float minV )
return clipIfValue( valueDescaled, 0.0 );
}
/**
* Works similiar to the other clipZero, but uses the vector lenght unstead.
*
* \param valueDescaled the descaled vector value
*
* \return 0.0 if clip, 1.0 if not.
*/
float clipZero( in vec3 valueDescaled )
{
return clamp( sign( length( valueDescaled ) - 0.01 ), 0.0, 1.0 );
}
/**
* The method decides whether the value should be clipped because of the threshold value. This is different for vector and scalar data, which is
* why this method handles it transparently.
*
* \param valueDescaled the descaled data. Scalar or vector.
* \param colormap if this is a vector colormap, thresholding is done using vector length.
*
* \return 0.0 if clipped
*/
float clipThreshold( in vec3 valueDescaled, in int colormap, in float thresholdV )
{
float isVec = float( colormap == 6 );
return isVec * clamp( sign( length( valueDescaled ) - thresholdV ), 0.0, 1.0 )
+
( 1.0 - isVec ) * clamp( sign( valueDescaled.r - ( thresholdV - 0.001 ) ), 0.0, 1.0 );
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Colormaps. They need to handle clipping!
// Colormaps.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
......@@ -73,18 +102,18 @@ float clipZero( in float valueDescaled, in float minV )
*
* \param value the <b>scaled</b> value
*
* \return color. Alpha == 0 if value.r == 0.
* \return color.
*/
vec4 grayscale( in vec3 value, in vec3 valueDescaled, in float minV, in float scaleV )
vec4 grayscale( in vec3 value )
{
return vec4( value, clipZero( valueDescaled.r, minV ) );
return vec4( value, 1.0 );
}
/**
* Maps red and blue to the positive and negative part of the interval linearly. It handles the zero-point according to specified min and scale
* values.
*
* \note it does not show blue values for data that is purely positive (like T1 images and similar).
* \note it clips on the mid-point of the scala or 0 if minV < 0
*
* \param valueDescaled <b>descaled</b> value
* \param minV min value
......@@ -126,27 +155,268 @@ vec4 vector( in vec3 valueDescaled, in float minV, in float scaleV )
{
// similar to negative2positive, we need the width of the interval.
float m = max( abs( minV ), abs( minV + scaleV ) );
return vec4( abs( valueDescaled / m ),
// if the vector length is near zero -> clip
clamp( sign( length( valueDescaled ) - 0.01 ), 0.0, 1.0 )
);
return vec4( abs( valueDescaled / m ), 1.0 );
}
/**
* The method decides whether the value should be clipped because of the threshold value. This is different for vector and scalar data, which is
* why this method handles it transparently.
* Hot Iron colormap. It fades between red and yellowish colors.
*
* \param valueDescaled the descaled data. Scalar or vector.
* \param colormap if this is a vector colormap, thresholding is done using vector length.
* \param value the scaled value
*
* \return 0.0 if clipped
* \return color.
*/
float clipThreshold( in vec3 valueDescaled, in int colormap, in float thresholdV )
vec4 hotIron( in float value )
{
float isVec = float( colormap == 6 );
return isVec * clamp( sign( length( valueDescaled ) - thresholdV ), 0.0, 1.0 )
+
( 1.0 - isVec ) * clamp( sign( valueDescaled.r - 1.001 * thresholdV ), 0.0, 1.0 );
vec4 color8 = vec4( 255.0 / 255.0, 255.0 / 255.0, 204.0 / 255.0, 1.0 );
vec4 color7 = vec4( 255.0 / 255.0, 237.0 / 255.0, 160.0 / 255.0, 1.0 );
vec4 color6 = vec4( 254.0 / 255.0, 217.0 / 255.0, 118.0 / 255.0, 1.0 );
vec4 color5 = vec4( 254.0 / 255.0, 178.0 / 255.0, 76.0 / 255.0, 1.0 );
vec4 color4 = vec4( 253.0 / 255.0, 141.0 / 255.0, 60.0 / 255.0, 1.0 );
vec4 color3 = vec4( 252.0 / 255.0, 78.0 / 255.0, 42.0 / 255.0, 1.0 );
vec4 color2 = vec4( 227.0 / 255.0, 26.0 / 255.0, 28.0 / 255.0, 1.0 );
vec4 color1 = vec4( 189.0 / 255.0, 0.0 / 255.0, 38.0 / 255.0, 1.0 );
vec4 color0 = vec4( 128.0 / 255.0, 0.0 / 255.0, 38.0 / 255.0, 1.0 );
float colorValue = value * 8.0;
int sel = int( floor( colorValue ) );
if ( sel >= 8 )
{
return color0;
}
else if ( sel < 0 )
{
return color0;
}
else
{
colorValue -= float( sel );
if ( sel < 1 )
{
return ( color1 * colorValue + color0 * ( 1.0 - colorValue ) );
}
else if ( sel < 2 )
{
return ( color2 * colorValue + color1 * ( 1.0 - colorValue ) );
}
else if ( sel < 3 )
{
return ( color3 * colorValue + color2 * ( 1.0 - colorValue ) );
}
else if ( sel < 4 )
{
return ( color4 * colorValue + color3 * ( 1.0 - colorValue ) );
}
else if ( sel < 5 )
{
return ( color5 * colorValue + color4 * ( 1.0 - colorValue ) );
}
else if ( sel < 6 )
{
return ( color6 * colorValue + color5 * ( 1.0 - colorValue ) );
}
else if ( sel < 7 )
{
return ( color7 * colorValue + color6 * ( 1.0 - colorValue ) );
}
else if ( sel < 8 )
{
return ( color8 * colorValue + color7 * ( 1.0 - colorValue ) );
}
else
{
return color0;
}
}
}
/**
* Rainbow colormap. Fading through the rainbow colors.
*
* \param value the value in [0,1]
*
* \return color
*/
vec4 rainbow( in float value )
{
float i = floor( 6.0 * value );
float f = 6.0 * value - i;
float q = 1.0 - f;
int iq = int( mod( i, 6.0 ) );
if ( ( iq == 0 ) || ( iq == 6 ) )
{
return vec4( 1.0, f, 0.0, 1.0 );
}
else if ( iq == 1 )
{
return vec4( q, 1.0, 0.0, 1.0 );
}
else if ( iq == 2 )
{
return vec4( 0.0, 1.0, f, 1.0 );
}
else if ( iq == 3 )
{
return vec4( 0.0, q, 1.0, 1.0 );
}
else if ( iq == 4 )
{
return vec4( f, 0.0, 1.0, 1.0 );
}
else // iq == 5
{
return vec4( 1.0, 0.0, q, 1.0 );
}
}
/**
* Colormap fading between green, blue and purple.
*
* \param value the scaled value in [0,1]
*
* \return the color
*/
vec4 blueGreenPurple( in float value )
{
value *= 5.0;
vec4 color;
if( value < 0.0 )
{
color = vec4( 0.0, 0.0, 0.0, 1.0 );
}
else if( value < 1.0 )
{
color = vec4( 0.0, value, 1.0, 1.0 );
}
else if( value < 2.0 )
{
color = vec4( 0.0, 1.0, 2.0 - value, 1.0 );
}
else if( value < 3.0 )
{
color = vec4( value - 2.0, 1.0, 0.0, 1.0 );
}
else if( value < 4.0 )
{
color = vec4( 1.0, 4.0 - value, 0.0, 1.0 );
}
else if( value <= 5.0 )
{
color = vec4( 1.0, 0.0, value - 4.0, 1.0 );
}
else
{
color = vec4( 1.0, 0.0, 1.0, 1.0 );
}
return color;
}
/**
* Checks wether a bit is set. This is done in this function since the &-operator is not available in GLSL 1.20 and GLSL 1.30 is problematic on
* Mac OS 10.6.*
*
* \note Remove this function and replace its calls with bitwise operations as soon as there on all platforms available.
*
* \param value the value in [0,1]
* \param bitpos which bit
*
* \return
*/
bool isBitSet( in float value, in float bitpos )
{
return ( abs( mod( floor( value / pow( 2.0, bitpos ) ), 2.0 ) - 1.0 ) ) < 0.001;
}
/**
* Colormap especially suitable for mask data. It tries to find distinct colors for neighbouring values.
*
* \param value the value in [0,1]
*
* \return the volor
*/
vec4 atlas( in float value )
{
float val = floor( value * 255.0 );
float r = 0.0;
float g = 0.0;
float b = 0.0;
float mult = 1.0;
if ( val == 0.0 )
{
return vec4( vec3( 0.0 ), 1.0 );
}
if ( isBitSet( val, 0.0 ) )
{
b = 1.0;
}
if ( isBitSet( val, 1.0 ) )
{
g = 1.0;
}
if ( isBitSet( val, 2.0 ) )
{
r = 1.0;
}
if ( isBitSet( val, 3.0 ) )
{
mult -= 0.15;
if ( r < 1.0 && g < 1.0 && b < 1.0 )
{
r = 1.0;
g = 1.0;
}
}
if ( isBitSet( val, 4.0 ) )
{
mult -= 0.15;
if ( r < 1.0 && g < 1.0 && b < 1.0 )
{
b = 1.0;
g = 1.0;
}
}
if ( isBitSet( val, 5.0 ) )
{
mult -= 0.15;
if ( r < 1.0 && g < 1.0 && b < 1.0 )
{
r = 1.0;
b = 1.0;
}
}
if ( isBitSet( val, 6.0 ) )
{
mult -= 0.15;
if ( r < 1.0 && g < 1.0 && b < 1.0 )
{
g = 1.0;
}
}
if ( isBitSet( val, 7.0 ) )
{
mult -= 0.15;
if ( r < 1.0 && g < 1.0 && b < 1.0 )
{
r = 1.0;
}
}
r *= mult;
g *= mult;
b *= mult;
clamp( r, 0.0, 1.0 );
clamp( g, 0.0, 1.0 );
clamp( b, 0.0, 1.0 );
return vec4( r, g, b, 1.0 );
}
/**
......@@ -167,21 +437,40 @@ vec4 colormap( in vec3 value, float minV, float scaleV, float thresholdV, float
vec3 valueDescaled = vec3( minV ) + ( value * scaleV );
// this is the final color returned by the colormapping algorithm. This is the correct value for the gray colormap
vec4 cmapped = grayscale( value, valueDescaled, minV, scaleV );
vec4 cmapped = grayscale( value );
float clip = clipZero( valueDescaled.r, minV );
// negative to positive shading in red-blue
if ( colormap == 3 )
if ( colormap == 1 )
{
cmapped = rainbow( value.r );
}
else if ( colormap == 2 )
{
cmapped = hotIron( value.r );
}
else if ( colormap == 3 )
{
cmapped = negative2positive( valueDescaled.r, minV, scaleV );
}
else if ( colormap == 4 )
{
cmapped = atlas( value.r );
}
else if ( colormap == 5 )
{
cmapped = blueGreenPurple( value.r );
}
else if ( colormap == 6 )
{
cmapped = vector( valueDescaled, minV, scaleV );
clip = clipZero( valueDescaled ); // vectors get clipped by their length
}
// build final color
return vec4( cmapped.rgb, cmapped.a * // did the colormap use a alpha value?
alpha * // did the user specified an alpha?
clip * // value clip?
clipThreshold( valueDescaled, colormap, thresholdV ) * // clip due to threshold?
float( active ) ); // is it active?
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment