GLSL |
|
precision highp float;
uniform sampler2D u_image;
varying vec2 vTextureCoordinate;
mat4 protanopia = mat4(
0.1120, 0.8853, -0.0005, 0,
0.1126, 0.8897, -0.0001, 0,
0.0045, 0.0001, 1.00191, 0,
0, 0, 0, 1);
vec4 srgbToRgb(vec4 color){
bvec4 bcutoff = lessThan(color, vec4(0.04045));
vec4 cutoff = vec4(float(bcutoff[0]), float(bcutoff[1]), float(bcutoff[2]), float(bcutoff[3]));
vec4 higher = pow((color + vec4(0.055)) / vec4(1.055), vec4(2.4));
vec4 lower = color / vec4(12.92);
return mix(higher, lower, cutoff);
}
vec4 rgbToSrgb(vec4 color){
bvec4 bcutoff = lessThan(color, vec4(0.0031308));
vec4 cutoff = vec4(float(bcutoff[0]), float(bcutoff[1]), float(bcutoff[2]), float(bcutoff[3]));
vec4 higher = vec4(1.055) * pow(color, vec4(1.0 / 2.4)) - 0.055;
vec4 lower = color * vec4(12.92);
return mix(higher, lower, cutoff);
}
void main() {
vec4 source = texture2D(u_image, vTextureCoordinate);
vec4 linearColor = srgbToRgb(source);
vec4 linearTarget = linearColor * protanopia;
vec4 srgbTarget = rgbToSrgb(linearTarget);
gl_FragColor = srgbTarget;
}
|
precision mediump float;
uniform sampler2D u_image;
varying vec2 vTextureCoordinate;
mat4 deuteranopia = mat4(
0.2920, 0.7054, -0.0003, 0,
0.2934, 0.7089, 0.0000, 0,
-0.02098, 0.02559, 1.0019, 0,
0, 0, 0, 1);
vec4 srgbToRgb(vec4 color){
bvec4 bcutoff = lessThan(color, vec4(0.04045));
vec4 cutoff = vec4(float(bcutoff[0]), float(bcutoff[1]), float(bcutoff[2]), float(bcutoff[3]));
vec4 higher = pow((color + vec4(0.055)) / vec4(1.055), vec4(2.4));
vec4 lower = color / vec4(12.92);
return mix(higher, lower, cutoff);
}
vec4 rgbToSrgb(vec4 color){
bvec4 bcutoff = lessThan(color, vec4(0.0031308));
vec4 cutoff = vec4(float(bcutoff[0]), float(bcutoff[1]), float(bcutoff[2]), float(bcutoff[3]));
vec4 higher = vec4(1.055) * pow(color, vec4(1.0 / 2.4)) - 0.055;
vec4 lower = color * vec4(12.92);
return mix(higher, lower, cutoff);
}
void main() {
vec4 source = texture2D(u_image, vTextureCoordinate);
vec4 linearColor = srgbToRgb(source);
vec4 linearTarget = linearColor * deuteranopia;
vec4 srgbTarget = rgbToSrgb(linearTarget);
gl_FragColor = srgbTarget;
}
|
|
precision highp float;
uniform sampler2D u_image;
varying vec2 vTextureCoordinate;
mat4 achromatopsia = mat4(
0.21, 0.72, 0.07, 0,
0.21, 0.72, 0.07, 0,
0.21, 0.72, 0.07, 0,
0, 0, 0, 1);
vec4 srgbToRgb(vec4 color){
bvec4 bcutoff = lessThan(color, vec4(0.04045));
vec4 cutoff = vec4(float(bcutoff[0]), float(bcutoff[1]), float(bcutoff[2]), float(bcutoff[3]));
vec4 higher = pow((color + vec4(0.055)) / vec4(1.055), vec4(2.4));
vec4 lower = color / vec4(12.92);
return mix(higher, lower, cutoff);
}
vec4 rgbToSrgb(vec4 color){
bvec4 bcutoff = lessThan(color, vec4(0.0031308));
vec4 cutoff = vec4(float(bcutoff[0]), float(bcutoff[1]), float(bcutoff[2]), float(bcutoff[3]));
vec4 higher = vec4(1.055) * pow(color, vec4(1.0 / 2.4)) - 0.055;
vec4 lower = color * vec4(12.92);
return mix(higher, lower, cutoff);
}
void main() {
vec4 source = texture2D(u_image, vTextureCoordinate);
vec4 linearColor = srgbToRgb(source);
vec4 linearTarget = linearColor * achromatopsia;
vec4 srgbTarget = rgbToSrgb(linearTarget);
gl_FragColor = srgbTarget;
}
|
JS |
|
const protanopia = [
[0.1120, 0.8853, -0.0005, 0],
[0.1126, 0.8897, -0.0001, 0],
[0.0045, 0.0001, 1.00191, 0],
[0, 0, 0, 1]
];
function srgbToRgb(color) {
return color.map(component => {
const sign = component < 0 ? -1 : 1;
const abs=Math.abs(component);
return abs <= 0.04045
? component / 12.92
: sign * Math.pow((abs + 0.055) / 1.055, 2.4);
});
}
function rgbToSrgb(color) {
return color.map(component => {
return component < 0.0031308
? component * 12.92
: 1.055 * Math.pow(component, 1/2.4) - 0.055
});
}
const linearColor = srgbToRgb(color);
const linearResult = Matrix.crossMultiplyMatrixVector(linearColor, protanopia);
const srgbResult = rgbToSrgb(linearResult);
return srgbResult;
|
const deuteranopia = [
[0.2920, 0.7054, -0.0003, 0],
[0.2934, 0.7089, 0.0000, 0],
[-0.02098, 0.02559, 1.0019, 0],
[0, 0, 0, 1]
];
function srgbToRgb(color) {
return color.map(component => {
const sign = component < 0 ? -1 : 1;
const abs=Math.abs(component);
return abs <= 0.04045
? component / 12.92
: sign * Math.pow((abs + 0.055) / 1.055, 2.4);
});
}
function rgbToSrgb(color) {
return color.map(component => {
return component < 0.0031308
? component * 12.92
: 1.055 * Math.pow(component, 1/2.4) - 0.055
});
}
const linearColor = srgbToRgb(color);
const linearResult = Matrix.crossMultiplyMatrixVector(linearColor, deuteranopia);
const srgbResult = rgbToSrgb(linearResult);
return srgbResult;
|
function srgbToRgb(color) {
return color.map(component => {
const sign = component < 0 ? -1 : 1;
const abs=Math.abs(component);
return abs <= 0.04045
? component / 12.92
: sign * Math.pow((abs + 0.055) / 1.055, 2.4);
});
}
function rgbToSrgb(color) {
return color.map(component => {
return component < 0.0031308
? component * 12.92
: 1.055 * Math.pow(component, 1/2.4) - 0.055
});
}
const e = [65.5178, 34.4782, 1.68427, 1]; //RGB white in LMS space
function lmsColorToTritanopia([l, m, s, alpha]) { //input "Q"
const anchor = (m / l) < (e[1] / e[0]) // anchor "A"
? [0.0930085, 0.00730255, 0.0] //660nm
: [0.163952, 0.268063, 0.290322] //485nm
const a = (e[1] * anchor[2]) - (e[2] * anchor[1]);
const b = (e[2] * anchor[0]) - (e[0] * anchor[2]);
const c = (e[0] * anchor[1]) - (e[1] * anchor[0]);
return [l, m, -((a * l) + (b * m)) / c, alpha];
}
//Hunt-Pointer-Estevez
const rgbToLms = [
[31.3989492, 63.95129383, 4.64975462, 0],
[15.53714069, 75.78944616, 8.67014186, 0],
[1.77515606, 10.94420944, 87.25692246, 0],
[0, 0, 0, 1]
];
const lmsToRgb = [
[0.0547, -0.0464, 0.0017, 0],
[-0.0112, 0.0229, -0.0017, 0],
[0.0002, -0.0019, 0.0116, 0],
[0, 0, 0, 1]
];
const linearColor = srgbToRgb(color);
const lmsColor = Matrix.crossMultiplyMatrixVector(linearColor, rgbToLms);
const lmsTritanopia = lmsColorToTritanopia(lmsColor);
const rgbTritanopia = Matrix.crossMultiplyMatrixVector(lmsTritanopia, lmsToRgb);
const srgbResult = rgbToSrgb(rgbTritanopia);
return srgbResult;
|
const achromatopsia = [
[0.21, 0.72, 0.07, 0],
[0.21, 0.72, 0.07, 0],
[0.21, 0.72, 0.07, 0],
[0, 0, 0, 1],
];
function srgbToRgb(color) {
return color.map(component => {
const sign = component < 0 ? -1 : 1;
const abs=Math.abs(component);
return abs <= 0.04045
? component / 12.92
: sign * Math.pow((abs + 0.055) / 1.055, 2.4);
});
}
function rgbToSrgb(color) {
return color.map(component=> {
return component < 0.0031308
? component * 12.92
: 1.055 * Math.pow(component, 1/2.4) - 0.055
});
}
const linearColor = srgbToRgb(color);
const linearResult = Matrix.crossMultiplyMatrixVector(color, achromatopsia);
const srgbResult = rgbToSrgb(linearResult);
return srgbResult;
|