1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
/* Shader for color correction of RGB and Luminance textures by CLUT lookup.
* Uses a RGB color lookup table, encoded in a texture, to independently
* lookup corresponding remapped output red, green or blue intensity values
* for given input red, green or blue intensity values in the input texture.
*
* This shader is used by PsychColorCorrection() in 'LookupTable' mode,
* as part of PTB's built-in stimulus color correction.
*
* (w)2009 by Mario Kleiner. Licensed under MIT license.
*/
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect ICMCLUT;
uniform float ICMPrescale;
uniform float ICMMaxInputValue;
/* Allowable range for output values: To be initialized by PsychColorCorrection() typically: */
uniform vec2 ICMClampToColorRange;
vec4 icmTransformColor(vec4 incolor)
{
vec4 outcolor;
vec3 lutcolor1, lutcolor2, incolor1, incolor2;
/* Return alpha component unmodified: */
outcolor.a = incolor.a;
/* Clamp input to valid 0-ICMMaxInputValue range: */
incolor.rgb = clamp(incolor.rgb, vec3(0.0), vec3(ICMMaxInputValue));
/* Remap them to index in resolution range: */
incolor.rgb = incolor.rgb * ICMPrescale;
incolor1 = floor(incolor.rgb) + 0.5;
incolor2 = incolor1 + 1.0;
/* Lookup values for each channel in rows of texture: Perform linear */
/* filtering manual by dual-lookup and mix. This way we work on old hw as well: */
lutcolor1.r = texture2DRect(ICMCLUT, vec2(incolor1.r, 0.5)).r;
lutcolor2.r = texture2DRect(ICMCLUT, vec2(incolor2.r, 0.5)).r;
lutcolor1.g = texture2DRect(ICMCLUT, vec2(incolor1.g, 1.5)).r;
lutcolor2.g = texture2DRect(ICMCLUT, vec2(incolor2.g, 1.5)).r;
lutcolor1.b = texture2DRect(ICMCLUT, vec2(incolor1.b, 2.5)).r;
lutcolor2.b = texture2DRect(ICMCLUT, vec2(incolor2.b, 2.5)).r;
outcolor.rgb = mix(lutcolor1, lutcolor2, fract(incolor.rgb));
/* Clamp outcolor to range given by ICMClampToColorRange: */
outcolor.rgb = clamp(outcolor.rgb, vec3(ICMClampToColorRange[0]), vec3(ICMClampToColorRange[1]));
return(outcolor);
}
float icmTransformColor1(float incolor)
{
float outcolor;
float lutcolor1, lutcolor2, incolor1, incolor2;
/* Clamp input to valid 0-ICMMaxInputValue range: */
incolor = clamp(incolor, 0.0, ICMMaxInputValue);
/* Remap them to index in resolution range: */
incolor = incolor * ICMPrescale;
incolor1 = floor(incolor) + 0.5;
incolor2 = incolor1 + 1.0;
/* Lookup values for each channel in rows of texture: */
lutcolor1 = texture2DRect(ICMCLUT, vec2(incolor1, 0.5)).r;
lutcolor2 = texture2DRect(ICMCLUT, vec2(incolor2, 0.5)).r;
outcolor = mix(lutcolor1, lutcolor2, fract(incolor));
/* Clamp outcolor to range given by ICMClampToColorRange: */
outcolor = clamp(outcolor, ICMClampToColorRange[0], ICMClampToColorRange[1]);
return(outcolor);
}
|