@chinhui/niivue
Version:
minimal webgl2 nifti image viewer
1,689 lines (1,686 loc) • 3.87 MB
JavaScript
function Shader(gl, vertexSrc, fragmentSrc) {
var self2 = this;
this.program = compileShader(gl, vertexSrc, fragmentSrc);
var regexUniform = /uniform[^;]+[ ](\w+);/g;
var matchUniformName = /uniform[^;]+[ ](\w+);/;
this.uniforms = {};
var vertexUnifs = vertexSrc.match(regexUniform);
var fragUnifs = fragmentSrc.match(regexUniform);
if (vertexUnifs) {
vertexUnifs.forEach(function(unif2) {
var m = unif2.match(matchUniformName);
self2.uniforms[m[1]] = -1;
});
}
if (fragUnifs) {
fragUnifs.forEach(function(unif2) {
var m = unif2.match(matchUniformName);
self2.uniforms[m[1]] = -1;
});
}
for (var unif in this.uniforms) {
this.uniforms[unif] = gl.getUniformLocation(this.program, unif);
}
}
Shader.prototype.use = function(gl) {
gl.useProgram(this.program);
};
var compileShader = function(gl, vert, frag) {
var vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, vert);
gl.compileShader(vs);
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
alert("Vertex shader failed to compile, see console for log");
console.log(gl.getShaderInfoLog(vs));
return null;
}
var fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fs, frag);
gl.compileShader(fs);
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
alert("Fragment shader failed to compile, see console for log");
console.log(gl.getShaderInfoLog(fs));
return null;
}
var program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
alert("Shader failed to link, see console for log");
console.log(gl.getProgramInfoLog(program));
return null;
}
return program;
};
var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array;
if (!Math.hypot)
Math.hypot = function() {
var y = 0, i2 = arguments.length;
while (i2--) {
y += arguments[i2] * arguments[i2];
}
return Math.sqrt(y);
};
function create$3() {
var out = new ARRAY_TYPE(9);
if (ARRAY_TYPE != Float32Array) {
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[5] = 0;
out[6] = 0;
out[7] = 0;
}
out[0] = 1;
out[4] = 1;
out[8] = 1;
return out;
}
function fromValues$3(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
var out = new ARRAY_TYPE(9);
out[0] = m00;
out[1] = m01;
out[2] = m02;
out[3] = m10;
out[4] = m11;
out[5] = m12;
out[6] = m20;
out[7] = m21;
out[8] = m22;
return out;
}
function multiply$2(out, a, b) {
var a00 = a[0], a01 = a[1], a02 = a[2];
var a10 = a[3], a11 = a[4], a12 = a[5];
var a20 = a[6], a21 = a[7], a22 = a[8];
var b00 = b[0], b01 = b[1], b02 = b[2];
var b10 = b[3], b11 = b[4], b12 = b[5];
var b20 = b[6], b21 = b[7], b22 = b[8];
out[0] = b00 * a00 + b01 * a10 + b02 * a20;
out[1] = b00 * a01 + b01 * a11 + b02 * a21;
out[2] = b00 * a02 + b01 * a12 + b02 * a22;
out[3] = b10 * a00 + b11 * a10 + b12 * a20;
out[4] = b10 * a01 + b11 * a11 + b12 * a21;
out[5] = b10 * a02 + b11 * a12 + b12 * a22;
out[6] = b20 * a00 + b21 * a10 + b22 * a20;
out[7] = b20 * a01 + b21 * a11 + b22 * a21;
out[8] = b20 * a02 + b21 * a12 + b22 * a22;
return out;
}
function create$2() {
var out = new ARRAY_TYPE(16);
if (ARRAY_TYPE != Float32Array) {
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[11] = 0;
out[12] = 0;
out[13] = 0;
out[14] = 0;
}
out[0] = 1;
out[5] = 1;
out[10] = 1;
out[15] = 1;
return out;
}
function clone$1(a) {
var out = new ARRAY_TYPE(16);
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4];
out[5] = a[5];
out[6] = a[6];
out[7] = a[7];
out[8] = a[8];
out[9] = a[9];
out[10] = a[10];
out[11] = a[11];
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
return out;
}
function copy$1(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4];
out[5] = a[5];
out[6] = a[6];
out[7] = a[7];
out[8] = a[8];
out[9] = a[9];
out[10] = a[10];
out[11] = a[11];
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
return out;
}
function fromValues$2(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
var out = new ARRAY_TYPE(16);
out[0] = m00;
out[1] = m01;
out[2] = m02;
out[3] = m03;
out[4] = m10;
out[5] = m11;
out[6] = m12;
out[7] = m13;
out[8] = m20;
out[9] = m21;
out[10] = m22;
out[11] = m23;
out[12] = m30;
out[13] = m31;
out[14] = m32;
out[15] = m33;
return out;
}
function identity$1(out) {
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[5] = 1;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[10] = 1;
out[11] = 0;
out[12] = 0;
out[13] = 0;
out[14] = 0;
out[15] = 1;
return out;
}
function transpose(out, a) {
if (out === a) {
var a01 = a[1], a02 = a[2], a03 = a[3];
var a12 = a[6], a13 = a[7];
var a23 = a[11];
out[1] = a[4];
out[2] = a[8];
out[3] = a[12];
out[4] = a01;
out[6] = a[9];
out[7] = a[13];
out[8] = a02;
out[9] = a12;
out[11] = a[14];
out[12] = a03;
out[13] = a13;
out[14] = a23;
} else {
out[0] = a[0];
out[1] = a[4];
out[2] = a[8];
out[3] = a[12];
out[4] = a[1];
out[5] = a[5];
out[6] = a[9];
out[7] = a[13];
out[8] = a[2];
out[9] = a[6];
out[10] = a[10];
out[11] = a[14];
out[12] = a[3];
out[13] = a[7];
out[14] = a[11];
out[15] = a[15];
}
return out;
}
function invert(out, a) {
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
var b00 = a00 * a11 - a01 * a10;
var b01 = a00 * a12 - a02 * a10;
var b02 = a00 * a13 - a03 * a10;
var b03 = a01 * a12 - a02 * a11;
var b04 = a01 * a13 - a03 * a11;
var b05 = a02 * a13 - a03 * a12;
var b06 = a20 * a31 - a21 * a30;
var b07 = a20 * a32 - a22 * a30;
var b08 = a20 * a33 - a23 * a30;
var b09 = a21 * a32 - a22 * a31;
var b10 = a21 * a33 - a23 * a31;
var b11 = a22 * a33 - a23 * a32;
var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
if (!det) {
return null;
}
det = 1 / det;
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
return out;
}
function multiply$1(out, a, b) {
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
var b0 = b[0], b1 = b[1], b22 = b[2], b3 = b[3];
out[0] = b0 * a00 + b1 * a10 + b22 * a20 + b3 * a30;
out[1] = b0 * a01 + b1 * a11 + b22 * a21 + b3 * a31;
out[2] = b0 * a02 + b1 * a12 + b22 * a22 + b3 * a32;
out[3] = b0 * a03 + b1 * a13 + b22 * a23 + b3 * a33;
b0 = b[4];
b1 = b[5];
b22 = b[6];
b3 = b[7];
out[4] = b0 * a00 + b1 * a10 + b22 * a20 + b3 * a30;
out[5] = b0 * a01 + b1 * a11 + b22 * a21 + b3 * a31;
out[6] = b0 * a02 + b1 * a12 + b22 * a22 + b3 * a32;
out[7] = b0 * a03 + b1 * a13 + b22 * a23 + b3 * a33;
b0 = b[8];
b1 = b[9];
b22 = b[10];
b3 = b[11];
out[8] = b0 * a00 + b1 * a10 + b22 * a20 + b3 * a30;
out[9] = b0 * a01 + b1 * a11 + b22 * a21 + b3 * a31;
out[10] = b0 * a02 + b1 * a12 + b22 * a22 + b3 * a32;
out[11] = b0 * a03 + b1 * a13 + b22 * a23 + b3 * a33;
b0 = b[12];
b1 = b[13];
b22 = b[14];
b3 = b[15];
out[12] = b0 * a00 + b1 * a10 + b22 * a20 + b3 * a30;
out[13] = b0 * a01 + b1 * a11 + b22 * a21 + b3 * a31;
out[14] = b0 * a02 + b1 * a12 + b22 * a22 + b3 * a32;
out[15] = b0 * a03 + b1 * a13 + b22 * a23 + b3 * a33;
return out;
}
function translate(out, a, v) {
var x2 = v[0], y = v[1], z = v[2];
var a00, a01, a02, a03;
var a10, a11, a12, a13;
var a20, a21, a22, a23;
if (a === out) {
out[12] = a[0] * x2 + a[4] * y + a[8] * z + a[12];
out[13] = a[1] * x2 + a[5] * y + a[9] * z + a[13];
out[14] = a[2] * x2 + a[6] * y + a[10] * z + a[14];
out[15] = a[3] * x2 + a[7] * y + a[11] * z + a[15];
} else {
a00 = a[0];
a01 = a[1];
a02 = a[2];
a03 = a[3];
a10 = a[4];
a11 = a[5];
a12 = a[6];
a13 = a[7];
a20 = a[8];
a21 = a[9];
a22 = a[10];
a23 = a[11];
out[0] = a00;
out[1] = a01;
out[2] = a02;
out[3] = a03;
out[4] = a10;
out[5] = a11;
out[6] = a12;
out[7] = a13;
out[8] = a20;
out[9] = a21;
out[10] = a22;
out[11] = a23;
out[12] = a00 * x2 + a10 * y + a20 * z + a[12];
out[13] = a01 * x2 + a11 * y + a21 * z + a[13];
out[14] = a02 * x2 + a12 * y + a22 * z + a[14];
out[15] = a03 * x2 + a13 * y + a23 * z + a[15];
}
return out;
}
function rotateX(out, a, rad) {
var s = Math.sin(rad);
var c2 = Math.cos(rad);
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
var a20 = a[8];
var a21 = a[9];
var a22 = a[10];
var a23 = a[11];
if (a !== out) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
}
out[4] = a10 * c2 + a20 * s;
out[5] = a11 * c2 + a21 * s;
out[6] = a12 * c2 + a22 * s;
out[7] = a13 * c2 + a23 * s;
out[8] = a20 * c2 - a10 * s;
out[9] = a21 * c2 - a11 * s;
out[10] = a22 * c2 - a12 * s;
out[11] = a23 * c2 - a13 * s;
return out;
}
function rotateZ(out, a, rad) {
var s = Math.sin(rad);
var c2 = Math.cos(rad);
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
if (a !== out) {
out[8] = a[8];
out[9] = a[9];
out[10] = a[10];
out[11] = a[11];
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
}
out[0] = a00 * c2 + a10 * s;
out[1] = a01 * c2 + a11 * s;
out[2] = a02 * c2 + a12 * s;
out[3] = a03 * c2 + a13 * s;
out[4] = a10 * c2 - a00 * s;
out[5] = a11 * c2 - a01 * s;
out[6] = a12 * c2 - a02 * s;
out[7] = a13 * c2 - a03 * s;
return out;
}
function orthoNO(out, left, right, bottom, top, near, far) {
var lr = 1 / (left - right);
var bt = 1 / (bottom - top);
var nf = 1 / (near - far);
out[0] = -2 * lr;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[5] = -2 * bt;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[10] = 2 * nf;
out[11] = 0;
out[12] = (left + right) * lr;
out[13] = (top + bottom) * bt;
out[14] = (far + near) * nf;
out[15] = 1;
return out;
}
var ortho = orthoNO;
function multiplyScalar(out, a, b) {
out[0] = a[0] * b;
out[1] = a[1] * b;
out[2] = a[2] * b;
out[3] = a[3] * b;
out[4] = a[4] * b;
out[5] = a[5] * b;
out[6] = a[6] * b;
out[7] = a[7] * b;
out[8] = a[8] * b;
out[9] = a[9] * b;
out[10] = a[10] * b;
out[11] = a[11] * b;
out[12] = a[12] * b;
out[13] = a[13] * b;
out[14] = a[14] * b;
out[15] = a[15] * b;
return out;
}
var mul$1 = multiply$1;
function create$1() {
var out = new ARRAY_TYPE(3);
if (ARRAY_TYPE != Float32Array) {
out[0] = 0;
out[1] = 0;
out[2] = 0;
}
return out;
}
function clone(a) {
var out = new ARRAY_TYPE(3);
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
return out;
}
function length(a) {
var x2 = a[0];
var y = a[1];
var z = a[2];
return Math.hypot(x2, y, z);
}
function fromValues$1(x2, y, z) {
var out = new ARRAY_TYPE(3);
out[0] = x2;
out[1] = y;
out[2] = z;
return out;
}
function copy(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
return out;
}
function add$1(out, a, b) {
out[0] = a[0] + b[0];
out[1] = a[1] + b[1];
out[2] = a[2] + b[2];
return out;
}
function subtract(out, a, b) {
out[0] = a[0] - b[0];
out[1] = a[1] - b[1];
out[2] = a[2] - b[2];
return out;
}
function min$Q(out, a, b) {
out[0] = Math.min(a[0], b[0]);
out[1] = Math.min(a[1], b[1]);
out[2] = Math.min(a[2], b[2]);
return out;
}
function max$R(out, a, b) {
out[0] = Math.max(a[0], b[0]);
out[1] = Math.max(a[1], b[1]);
out[2] = Math.max(a[2], b[2]);
return out;
}
function scale(out, a, b) {
out[0] = a[0] * b;
out[1] = a[1] * b;
out[2] = a[2] * b;
return out;
}
function negate(out, a) {
out[0] = -a[0];
out[1] = -a[1];
out[2] = -a[2];
return out;
}
function normalize(out, a) {
var x2 = a[0];
var y = a[1];
var z = a[2];
var len2 = x2 * x2 + y * y + z * z;
if (len2 > 0) {
len2 = 1 / Math.sqrt(len2);
}
out[0] = a[0] * len2;
out[1] = a[1] * len2;
out[2] = a[2] * len2;
return out;
}
function dot(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
function cross(out, a, b) {
var ax = a[0], ay = a[1], az = a[2];
var bx = b[0], by = b[1], bz = b[2];
out[0] = ay * bz - az * by;
out[1] = az * bx - ax * bz;
out[2] = ax * by - ay * bx;
return out;
}
function lerp(out, a, b, t) {
var ax = a[0];
var ay = a[1];
var az = a[2];
out[0] = ax + t * (b[0] - ax);
out[1] = ay + t * (b[1] - ay);
out[2] = az + t * (b[2] - az);
return out;
}
function angle(a, b) {
var ax = a[0], ay = a[1], az = a[2], bx = b[0], by = b[1], bz = b[2], mag1 = Math.sqrt(ax * ax + ay * ay + az * az), mag2 = Math.sqrt(bx * bx + by * by + bz * bz), mag = mag1 * mag2, cosine = mag && dot(a, b) / mag;
return Math.acos(Math.min(Math.max(cosine, -1), 1));
}
var len = length;
(function() {
var vec = create$1();
return function(a, stride, offset, count, fn, arg2) {
var i2, l;
if (!stride) {
stride = 3;
}
if (!offset) {
offset = 0;
}
if (count) {
l = Math.min(count * stride + offset, a.length);
} else {
l = a.length;
}
for (i2 = offset; i2 < l; i2 += stride) {
vec[0] = a[i2];
vec[1] = a[i2 + 1];
vec[2] = a[i2 + 2];
fn(vec, vec, arg2);
a[i2] = vec[0];
a[i2 + 1] = vec[1];
a[i2 + 2] = vec[2];
}
return a;
};
})();
function create() {
var out = new ARRAY_TYPE(4);
if (ARRAY_TYPE != Float32Array) {
out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] = 0;
}
return out;
}
function fromValues(x2, y, z, w) {
var out = new ARRAY_TYPE(4);
out[0] = x2;
out[1] = y;
out[2] = z;
out[3] = w;
return out;
}
function add(out, a, b) {
out[0] = a[0] + b[0];
out[1] = a[1] + b[1];
out[2] = a[2] + b[2];
out[3] = a[3] + b[3];
return out;
}
function multiply(out, a, b) {
out[0] = a[0] * b[0];
out[1] = a[1] * b[1];
out[2] = a[2] * b[2];
out[3] = a[3] * b[3];
return out;
}
function transformMat4(out, a, m) {
var x2 = a[0], y = a[1], z = a[2], w = a[3];
out[0] = m[0] * x2 + m[4] * y + m[8] * z + m[12] * w;
out[1] = m[1] * x2 + m[5] * y + m[9] * z + m[13] * w;
out[2] = m[2] * x2 + m[6] * y + m[10] * z + m[14] * w;
out[3] = m[3] * x2 + m[7] * y + m[11] * z + m[15] * w;
return out;
}
var mul = multiply;
(function() {
var vec = create();
return function(a, stride, offset, count, fn, arg2) {
var i2, l;
if (!stride) {
stride = 4;
}
if (!offset) {
offset = 0;
}
if (count) {
l = Math.min(count * stride + offset, a.length);
} else {
l = a.length;
}
for (i2 = offset; i2 < l; i2 += stride) {
vec[0] = a[i2];
vec[1] = a[i2 + 1];
vec[2] = a[i2 + 2];
vec[3] = a[i2 + 3];
fn(vec, vec, arg2);
a[i2] = vec[0];
a[i2 + 1] = vec[1];
a[i2 + 2] = vec[2];
a[i2 + 3] = vec[3];
}
return a;
};
})();
var vertRenderShader = `#version 300 es
#line 4
layout(location=0) in vec3 pos;
layout(location=1) in vec3 texCoords;
uniform mat4 mvpMtx;
out vec3 vColor;
void main(void) {
gl_Position = mvpMtx * vec4(pos, 1.0); //vec4(2.0 * (pos.xyz - 0.5), 1.0);
vColor = texCoords;
}`;
const kRenderFunc = `vec3 GetBackPosition(vec3 startPositionTex) {
vec3 startPosition = startPositionTex * volScale;
vec3 invR = 1.0 / rayDir;
vec3 tbot = invR * (vec3(0.0)-startPosition);
vec3 ttop = invR * (volScale-startPosition);
vec3 tmax = max(ttop, tbot);
vec2 t = min(tmax.xx, tmax.yz);
vec3 endPosition = startPosition + (rayDir * min(t.x, t.y));
//convert world position back to texture position:
endPosition = endPosition / volScale;
return endPosition;
}
vec4 applyClip (vec3 dir, inout vec4 samplePos, inout float len, inout bool isClip) {
float cdot = dot(dir,clipPlane.xyz);
isClip = false;
if ((clipPlane.a > 1.0) || (cdot == 0.0)) return samplePos;
bool frontface = (cdot > 0.0);
float clipThick = 2.0;
float dis = (-clipPlane.a - dot(clipPlane.xyz, samplePos.xyz-0.5)) / cdot;
float disBackFace = (-(clipPlane.a-clipThick) - dot(clipPlane.xyz, samplePos.xyz-0.5)) / cdot;
if (((frontface) && (dis >= len)) || ((!frontface) && (dis <= 0.0))) {
samplePos.a = len + 1.0;
return samplePos;
}
if (frontface) {
dis = max(0.0, dis);
samplePos = vec4(samplePos.xyz+dir * dis, dis);
if (dis > 0.0) isClip = true;
len = min(disBackFace, len);
}
if (!frontface) {
len = min(dis, len);
disBackFace = max(0.0, disBackFace);
if (len == dis) isClip = true;
samplePos = vec4(samplePos.xyz+dir * disBackFace, disBackFace);
}
return samplePos;
}`;
var fragRenderShader = `#version 300 es
#line 14
precision highp int;
precision highp float;
uniform vec3 rayDir;
uniform vec3 texVox;
uniform vec3 volScale;
uniform vec4 clipPlane;
uniform highp sampler3D volume, overlay;
uniform float overlays;
uniform float backOpacity;
uniform mat4 mvpMtx;
uniform mat4 matRAS;
uniform vec4 clipPlaneColor;
in vec3 vColor;
out vec4 fColor;
` + kRenderFunc + `
float frac2ndc(vec3 frac) {
//https://stackoverflow.com/questions/7777913/how-to-render-depth-linearly-in-modern-opengl-with-gl-fragcoord-z-in-fragment-sh
vec4 pos = vec4(frac.xyz, 1.0); //fraction
vec4 dim = vec4(vec3(textureSize(volume, 0)), 1.0);
pos = pos * dim;
vec4 shim = vec4(-0.5, -0.5, -0.5, 0.0);
pos += shim;
vec4 mm = transpose(matRAS) * pos;
float z_ndc = (mvpMtx * vec4(mm.xyz, 1.0)).z;
return (z_ndc + 1.0) / 2.0;
}
void main() {
fColor = vec4(0.0,0.0,0.0,0.0);
//fColor = vec4(vColor.rgb, 1.0); return;
vec3 start = vColor;
gl_FragDepth = 0.0;
vec3 backPosition = GetBackPosition(start);
// fColor = vec4(backPosition, 1.0); return;
vec3 dir = backPosition - start;
float len = length(dir);
float lenVox = length((texVox * start) - (texVox * backPosition));
if ((lenVox < 0.5) || (len > 3.0)) { //length limit for parallel rays
return;
}
float sliceSize = len / lenVox; //e.g. if ray length is 1.0 and traverses 50 voxels, each voxel is 0.02 in unit cube
float stepSize = sliceSize; //quality: larger step is faster traversal, but fewer samples
float opacityCorrection = stepSize/sliceSize;
dir = normalize(dir);
vec4 deltaDir = vec4(dir.xyz * stepSize, stepSize);
vec4 samplePos = vec4(start.xyz, 0.0); //ray position
float lenNoClip = len;
bool isClip = false;
vec4 clipPos = applyClip(dir, samplePos, len, isClip);
//if ((clipPos.a != samplePos.a) && (len < 3.0)) {
//start: OPTIONAL fast pass: rapid traversal until first hit
float stepSizeFast = sliceSize * 1.9;
vec4 deltaDirFast = vec4(dir.xyz * stepSizeFast, stepSizeFast);
while (samplePos.a <= len) {
float val = texture(volume, samplePos.xyz).a;
if (val > 0.01) break;
samplePos += deltaDirFast; //advance ray position
}
if ((samplePos.a >= len) && (overlays < 1.0)) {
if (isClip)
fColor += clipPlaneColor;
return;
}
fColor = vec4(1.0, 1.0, 1.0, 1.0);
//gl_FragDepth = frac2ndc(samplePos.xyz); //crude due to fast pass resolution
samplePos -= deltaDirFast;
if (samplePos.a < 0.0)
vec4 samplePos = vec4(start.xyz, 0.0); //ray position
//end: fast pass
vec4 colAcc = vec4(0.0,0.0,0.0,0.0);
vec4 firstHit = vec4(0.0,0.0,0.0,2.0 * lenNoClip);
const float earlyTermination = 0.95;
float backNearest = len; //assume no hit
float ran = fract(sin(gl_FragCoord.x * 12.9898 + gl_FragCoord.y * 78.233) * 43758.5453);
samplePos += deltaDir * ran; //jitter ray
while (samplePos.a <= len) {
vec4 colorSample = texture(volume, samplePos.xyz);
samplePos += deltaDir; //advance ray position
if (colorSample.a < 0.01) continue;
if (firstHit.a > lenNoClip)
firstHit = samplePos;
backNearest = min(backNearest, samplePos.a);
colorSample.a = 1.0-pow((1.0 - colorSample.a), opacityCorrection);
colorSample.rgb *= colorSample.a;
colAcc= (1.0 - colAcc.a) * colorSample + colAcc;
if ( colAcc.a > earlyTermination )
break;
}
if (firstHit.a < len)
gl_FragDepth = frac2ndc(firstHit.xyz);
colAcc.a = (colAcc.a / earlyTermination) * backOpacity;
fColor = colAcc;
if (isClip) //CR
fColor.rgb = mix(fColor.rgb, clipPlaneColor.rgb, clipPlaneColor.a * 0.15);
if (overlays < 1.0) return;
//overlay pass
len = lenNoClip;
samplePos = vec4(start.xyz, 0.0); //ray position
//start: OPTIONAL fast pass: rapid traversal until first hit
stepSizeFast = sliceSize * 1.9;
deltaDirFast = vec4(dir.xyz * stepSizeFast, stepSizeFast);
while (samplePos.a <= len) {
float val = texture(overlay, samplePos.xyz).a;
if (val > 0.01) break;
samplePos += deltaDirFast; //advance ray position
}
if (samplePos.a >= len) {
if (isClip && (fColor.a == 0.0))
fColor += clipPlaneColor;
return;
}
samplePos -= deltaDirFast;
if (samplePos.a < 0.0)
vec4 samplePos = vec4(start.xyz, 0.0); //ray position
//end: fast pass
float overFarthest = len;
colAcc = vec4(0.0, 0.0, 0.0, 0.0);
samplePos += deltaDir * ran; //jitter ray
vec4 overFirstHit = vec4(0.0,0.0,0.0,2.0 * len);
while (samplePos.a <= len) {
vec4 colorSample = texture(overlay, samplePos.xyz);
samplePos += deltaDir; //advance ray position
if (colorSample.a < 0.01) continue;
if (overFirstHit.a > len)
overFirstHit = samplePos;
colorSample.a = 1.0-pow((1.0 - colorSample.a), opacityCorrection);
colorSample.rgb *= colorSample.a;
colAcc= (1.0 - colAcc.a) * colorSample + colAcc;
overFarthest = samplePos.a;
if ( colAcc.a > earlyTermination )
break;
}
if (overFirstHit.a < firstHit.a)
//if (overFirstHit.a < len)
gl_FragDepth = frac2ndc(overFirstHit.xyz);
float overMix = colAcc.a;
float overlayDepth = 0.3;
if (fColor.a <= 0.0)
overMix = 1.0;
else if (((overFarthest) > backNearest)) {
float dx = (overFarthest - backNearest)/1.73;
dx = fColor.a * pow(dx, overlayDepth);
overMix *= 1.0 - dx;
}
fColor.rgb = mix(fColor.rgb, colAcc.rgb, overMix);
fColor.a = max(fColor.a, colAcc.a);
}`;
var vertSliceShader = `#version 300 es
#line 150
layout(location=0) in vec3 pos;
uniform int axCorSag;
uniform float slice;
uniform vec2 canvasWidthHeight;
uniform vec4 leftTopWidthHeight;
out vec3 texPos;
void main(void) {
//convert pixel x,y space 1..canvasWidth,1..canvasHeight to WebGL 1..-1,-1..1
vec2 frac;
frac.x = (leftTopWidthHeight.x + (pos.x * leftTopWidthHeight.z)) / canvasWidthHeight.x; //0..1
frac.y = 1.0 - ((leftTopWidthHeight.y + ((1.0 - pos.y) * leftTopWidthHeight.w)) / canvasWidthHeight.y); //1..0
frac = (frac * 2.0) - 1.0;
gl_Position = vec4(frac, 0.0, 1.0);
if (axCorSag == 1)
texPos = vec3(pos.x, slice, pos.y);
else if (axCorSag == 2)
texPos = vec3(slice, pos.x, pos.y);
else
texPos = vec3(pos.xy, slice);
}`;
var fragSliceShader = `#version 300 es
#line 228
precision highp int;
precision highp float;
uniform highp sampler3D volume, overlay;
uniform float overlays;
uniform float opacity;
uniform float drawOpacity;
uniform highp sampler3D drawing;
in vec3 texPos;
out vec4 color;
void main() {
color = vec4(texture(volume, texPos).rgb, opacity);
vec4 ocolor = vec4(0.0);
if (overlays < 1.0) {
ocolor = vec4(0.0, 0.0, 0.0, 0.0);
} else {
ocolor = texture(overlay, texPos);
}
float draw = texture(drawing, texPos).r;
if (draw > 0.0) {
vec3 dcolor = vec3(0.0, 0.0, 0.0);
if (draw >= (3.0/255.0))
dcolor.b = 1.0;
else if (draw >= (2.0/255.0))
dcolor.g = 1.0;
else
dcolor.r = 1.0;
color.rgb = mix(color.rgb, dcolor, drawOpacity);
color.a = max(drawOpacity, color.a);
}
float aout = ocolor.a + (1.0 - ocolor.a) * color.a;
if (aout <= 0.0) return;
color.rgb = ((ocolor.rgb * ocolor.a) + (color.rgb * color.a * (1.0 - ocolor.a))) / aout;
color.a = aout;
}`;
var fragLineShader = `#version 300 es
#line 189
precision highp int;
precision highp float;
uniform vec4 lineColor;
out vec4 color;
void main() {
color = lineColor;
}`;
var vertColorbarShader = `#version 300 es
#line 200
layout(location=0) in vec3 pos;
uniform vec2 canvasWidthHeight;
uniform vec4 leftTopWidthHeight;
out vec2 vColor;
void main(void) {
//convert pixel x,y space 1..canvasWidth,1..canvasHeight to WebGL 1..-1,-1..1
vec2 frac;
frac.x = (leftTopWidthHeight.x + (pos.x * leftTopWidthHeight.z)) / canvasWidthHeight.x; //0..1
frac.y = 1.0 - ((leftTopWidthHeight.y + ((1.0 - pos.y) * leftTopWidthHeight.w)) / canvasWidthHeight.y); //1..0
frac = (frac * 2.0) - 1.0;
gl_Position = vec4(frac, 0.0, 1.0);
vColor = pos.xy;
}`;
var fragColorbarShader = `#version 300 es
#line 217
precision highp int;
precision highp float;
uniform highp sampler2D colormap;
in vec2 vColor;
out vec4 color;
void main() {
color = vec4(texture(colormap, vColor).rgb, 1.0);
}`;
var vertLineShader = `#version 300 es
#line 229
layout(location=0) in vec3 pos;
uniform vec2 canvasWidthHeight;
uniform vec4 leftTopWidthHeight;
void main(void) {
//convert pixel x,y space 1..canvasWidth,1..canvasHeight to WebGL 1..-1,-1..1
vec2 frac;
frac.x = (leftTopWidthHeight.x + (pos.x * leftTopWidthHeight.z)) / canvasWidthHeight.x; //0..1
frac.y = 1.0 - ((leftTopWidthHeight.y + ((1.0 - pos.y) * leftTopWidthHeight.w)) / canvasWidthHeight.y); //1..0
frac = (frac * 2.0) - 1.0;
gl_Position = vec4(frac, 0.0, 1.0);
}`;
var vertBmpShader = `#version 300 es
#line 229
layout(location=0) in vec3 pos;
uniform vec2 canvasWidthHeight;
uniform vec4 leftTopWidthHeight;
out vec2 vUV;
void main(void) {
//convert pixel x,y space 1..canvasWidth,1..canvasHeight to WebGL 1..-1,-1..1
vec2 frac;
frac.x = (leftTopWidthHeight.x + (pos.x * leftTopWidthHeight.z)) / canvasWidthHeight.x; //0..1
frac.y = 1.0 - ((leftTopWidthHeight.y + ((1.0 - pos.y) * leftTopWidthHeight.w)) / canvasWidthHeight.y); //1..0
frac = (frac * 2.0) - 1.0;
gl_Position = vec4(frac, 0.0, 1.0);
vUV = vec2(pos.x, 1.0 - pos.y);
}`;
var fragBmpShader = `#version 300 es
#line 262
precision highp int;
precision highp float;
uniform highp sampler2D bmpTexture;
in vec2 vUV;
out vec4 color;
void main() {
color = texture(bmpTexture, vUV);
}`;
var vertFontShader = `#version 300 es
#line 244
layout(location=0) in vec3 pos;
uniform vec2 canvasWidthHeight;
uniform vec4 leftTopWidthHeight;
uniform vec4 uvLeftTopWidthHeight;
out vec2 vUV;
void main(void) {
//convert pixel x,y space 1..canvasWidth,1..canvasHeight to WebGL 1..-1,-1..1
vec2 frac;
frac.x = (leftTopWidthHeight.x + (pos.x * leftTopWidthHeight.z)) / canvasWidthHeight.x; //0..1
frac.y = 1.0 - ((leftTopWidthHeight.y + ((1.0 - pos.y) * leftTopWidthHeight.w)) / canvasWidthHeight.y); //1..0
frac = (frac * 2.0) - 1.0;
gl_Position = vec4(frac, 0.0, 1.0);
vUV = vec2(uvLeftTopWidthHeight.x + (pos.x * uvLeftTopWidthHeight.z), uvLeftTopWidthHeight.y + ((1.0 - pos.y) * uvLeftTopWidthHeight.w) );
}`;
var fragFontShader = `#version 300 es
#line 262
precision highp int;
precision highp float;
uniform highp sampler2D fontTexture;
uniform vec4 fontColor;
uniform float screenPxRange;
in vec2 vUV;
out vec4 color;
float median(float r, float g, float b) {
return max(min(r, g), min(max(r, g), b));
}
void main() {
vec3 msd = texture(fontTexture, vUV).rgb;
float sd = median(msd.r, msd.g, msd.b);
float screenPxDistance = screenPxRange*(sd - 0.5);
float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0);
color = vec4(fontColor.rgb , fontColor.a * opacity);
}`;
var vertOrientShader = `#version 300 es
#line 283
precision highp int;
precision highp float;
in vec3 vPos;
out vec2 TexCoord;
void main() {
TexCoord = vPos.xy;
gl_Position = vec4( (vPos.xy-vec2(0.5,0.5)) * 2.0, 0.0, 1.0);
}`;
var fragOrientShaderU = `#version 300 es
uniform highp usampler3D intensityVol;
`;
var fragOrientShaderI = `#version 300 es
uniform highp isampler3D intensityVol;
`;
var fragOrientShaderF = `#version 300 es
uniform highp sampler3D intensityVol;
`;
var fragOrientShaderAtlas = `#line 309
precision highp int;
precision highp float;
in vec2 TexCoord;
out vec4 FragColor;
uniform float coordZ;
uniform float layer;
uniform float numLayers;
uniform highp sampler2D colormap;
uniform lowp sampler3D blend3D;
uniform float opacity;
uniform vec3 xyzFrac;
uniform mat4 mtx;
void main(void) {
vec4 vx = vec4(TexCoord.x, TexCoord.y, coordZ, 1.0) * mtx;
uint idx = texture(intensityVol, vx.xyz).r;
FragColor = vec4(0.0, 0.0, 0.0, 0.0);
if (idx == uint(0))
return;
if (xyzFrac.x > 0.0) { //outline
vx = vec4(TexCoord.x+xyzFrac.x, TexCoord.y, coordZ, 1.0) * mtx;
uint R = texture(intensityVol, vx.xyz).r;
vx = vec4(TexCoord.x-xyzFrac.x, TexCoord.y, coordZ, 1.0) * mtx;
uint L = texture(intensityVol, vx.xyz).r;
vx = vec4(TexCoord.x, TexCoord.y+xyzFrac.y, coordZ, 1.0) * mtx;
uint A = texture(intensityVol, vx.xyz).r;
vx = vec4(TexCoord.x, TexCoord.y-xyzFrac.y, coordZ, 1.0) * mtx;
uint P = texture(intensityVol, vx.xyz).r;
vx = vec4(TexCoord.x, TexCoord.y, coordZ+xyzFrac.z, 1.0) * mtx;
uint S = texture(intensityVol, vx.xyz).r;
vx = vec4(TexCoord.x, TexCoord.y, coordZ-xyzFrac.z, 1.0) * mtx;
uint I = texture(intensityVol, vx.xyz).r;
if ((idx == R) && (idx == L) && (idx == A) && (idx == P) && (idx == S) && (idx == I))
return;
}
idx = ((idx - uint(1)) % uint(100))+uint(1);
float fx = (float(idx)+0.5) / 256.0;
float y = (2.0 * layer + 1.0)/(2.0 * numLayers);
FragColor = texture(colormap, vec2(fx, y)).rgba;
FragColor.a *= opacity;
if (layer < 2.0) return;
vec2 texXY = TexCoord.xy*0.5 +vec2(0.5,0.5);
vec4 prevColor = texture(blend3D, vec3(texXY, coordZ));
// https://en.wikipedia.org/wiki/Alpha_compositing
float aout = FragColor.a + (1.0 - FragColor.a) * prevColor.a;
if (aout <= 0.0) return;
FragColor.rgb = ((FragColor.rgb * FragColor.a) + (prevColor.rgb * prevColor.a * (1.0 - FragColor.a))) / aout;
FragColor.a = aout;
}`;
var fragOrientShader = `#line 309
precision highp int;
precision highp float;
in vec2 TexCoord;
out vec4 FragColor;
uniform float coordZ;
uniform float layer;
uniform float numLayers;
uniform float scl_slope;
uniform float scl_inter;
uniform float cal_max;
uniform float cal_min;
uniform highp sampler2D colormap;
uniform lowp sampler3D blend3D;
uniform float opacity;
uniform mat4 mtx;
void main(void) {
vec4 vx = vec4(TexCoord.xy, coordZ, 1.0) * mtx;
float f = (scl_slope * float(texture(intensityVol, vx.xyz).r)) + scl_inter;
float r = max(0.00001, abs(cal_max - cal_min));
float mn = min(cal_min, cal_max);
f = mix(0.0, 1.0, (f - mn) / r);
//float y = 1.0 / numLayers;
//y = ((layer + 0.5) * y);
//https://stackoverflow.com/questions/5879403/opengl-texture-coordinates-in-pixel-space
float y = (2.0 * layer + 1.0)/(2.0 * numLayers);
FragColor = texture(colormap, vec2(f, y)).rgba;
FragColor.a *= opacity;
if (layer < 2.0) return;
vec2 texXY = TexCoord.xy*0.5 +vec2(0.5,0.5);
vec4 prevColor = texture(blend3D, vec3(texXY, coordZ));
// https://en.wikipedia.org/wiki/Alpha_compositing
float aout = FragColor.a + (1.0 - FragColor.a) * prevColor.a;
if (aout <= 0.0) return;
FragColor.rgb = ((FragColor.rgb * FragColor.a) + (prevColor.rgb * prevColor.a * (1.0 - FragColor.a))) / aout;
FragColor.a = aout;
}`;
var fragRGBOrientShader = `#line 309
precision highp int;
precision highp float;
in vec2 TexCoord;
out vec4 FragColor;
uniform float coordZ;
uniform float layer;
uniform float numLayers;
uniform float scl_slope;
uniform float scl_inter;
uniform float cal_max;
uniform float cal_min;
uniform highp sampler2D colormap;
uniform lowp sampler3D blend3D;
uniform float opacity;
uniform mat4 mtx;
uniform bool hasAlpha;
void main(void) {
vec4 vx = vec4(TexCoord.xy, coordZ, 1.0) * mtx;
uvec4 aColor = texture(intensityVol, vx.xyz);
FragColor = vec4(float(aColor.r) / 255.0, float(aColor.g) / 255.0, float(aColor.b) / 255.0, float(aColor.a) / 255.0);
if (!hasAlpha)
FragColor.a = (FragColor.r * 0.21 + FragColor.g * 0.72 + FragColor.b * 0.07);
FragColor.a *= opacity;
}`;
var fragOrientShaderLookuptable = `#version 300 es
uniform highp sampler3D intensityVol;
precision highp int;
precision highp float;
in vec2 TexCoord;
out vec4 FragColor;
uniform float coordZ;
uniform float layer;
uniform float numLayers;
uniform float scl_slope;
uniform float scl_inter;
uniform float cal_max;
uniform float cal_min;
uniform highp sampler2D colormap;
uniform lowp sampler3D blend3D;
uniform float opacity;
uniform mat4 mtx;
void main(void) {
vec4 vx = vec4(TexCoord.xy, coordZ, 1.0) * mtx;
float f = (scl_slope * float(texture(intensityVol, vx.xyz).r)) + scl_inter;
// in 64bit fragOrientShaderF
// raw value: int(texture(intensityVol, vx.xyz).r) E.g.
// if(int(texture(intensityVol, vx.xyz).r) == 11116) {
// FragColor.r = 145.0/255.0;
// FragColor.g = 58.0/255.0;
// FragColor.b = 113.0/255.0;
//}
// scl_slope=1; scl_inter=0
// f (0.0-1.0) = normalized value of raw value
float r = max(0.00001, abs(cal_max - cal_min));
float mn = min(cal_min, cal_max);
f = mix(0.0, 1.0, (f - mn) / r);
//float y = 1.0 / numLayers;
//y = ((layer + 0.5) * y);
//https://stackoverflow.com/questions/5879403/opengl-texture-coordinates-in-pixel-space
float y = (2.0 * layer + 1.0)/(2.0 * numLayers);
FragColor = texture(colormap, vec2(f, y)).rgba;
switch( int(texture(intensityVol, vx.xyz).r) ) {
case 0:
FragColor.r = 0.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 0.0/255.0;
break;
case 1:
FragColor.r = 70.0/255.0; FragColor.g = 130.0/255.0; FragColor.b = 180.0/255.0;
break;
case 2:
FragColor.r = 245.0/255.0; FragColor.g = 245.0/255.0; FragColor.b = 245.0/255.0;
break;
case 3:
FragColor.r = 205.0/255.0; FragColor.g = 62.0/255.0; FragColor.b = 78.0/255.0;
break;
case 4:
FragColor.r = 120.0/255.0; FragColor.g = 18.0/255.0; FragColor.b = 134.0/255.0;
break;
case 5:
FragColor.r = 196.0/255.0; FragColor.g = 58.0/255.0; FragColor.b = 250.0/255.0;
break;
case 6:
FragColor.r = 0.0/255.0; FragColor.g = 148.0/255.0; FragColor.b = 0.0/255.0;
break;
case 7:
FragColor.r = 220.0/255.0; FragColor.g = 248.0/255.0; FragColor.b = 164.0/255.0;
break;
case 8:
FragColor.r = 230.0/255.0; FragColor.g = 148.0/255.0; FragColor.b = 34.0/255.0;
break;
case 9:
FragColor.r = 0.0/255.0; FragColor.g = 118.0/255.0; FragColor.b = 14.0/255.0;
break;
case 10:
FragColor.r = 0.0/255.0; FragColor.g = 118.0/255.0; FragColor.b = 14.0/255.0;
break;
case 11:
FragColor.r = 122.0/255.0; FragColor.g = 186.0/255.0; FragColor.b = 220.0/255.0;
break;
case 12:
FragColor.r = 236.0/255.0; FragColor.g = 13.0/255.0; FragColor.b = 176.0/255.0;
break;
case 13:
FragColor.r = 12.0/255.0; FragColor.g = 48.0/255.0; FragColor.b = 255.0/255.0;
break;
case 14:
FragColor.r = 204.0/255.0; FragColor.g = 182.0/255.0; FragColor.b = 142.0/255.0;
break;
case 15:
FragColor.r = 42.0/255.0; FragColor.g = 204.0/255.0; FragColor.b = 164.0/255.0;
break;
case 16:
FragColor.r = 119.0/255.0; FragColor.g = 159.0/255.0; FragColor.b = 176.0/255.0;
break;
case 17:
FragColor.r = 220.0/255.0; FragColor.g = 216.0/255.0; FragColor.b = 20.0/255.0;
break;
case 18:
FragColor.r = 103.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 255.0/255.0;
break;
case 19:
FragColor.r = 80.0/255.0; FragColor.g = 196.0/255.0; FragColor.b = 98.0/255.0;
break;
case 20:
FragColor.r = 60.0/255.0; FragColor.g = 58.0/255.0; FragColor.b = 210.0/255.0;
break;
case 21:
FragColor.r = 60.0/255.0; FragColor.g = 58.0/255.0; FragColor.b = 210.0/255.0;
break;
case 22:
FragColor.r = 60.0/255.0; FragColor.g = 58.0/255.0; FragColor.b = 210.0/255.0;
break;
case 23:
FragColor.r = 60.0/255.0; FragColor.g = 58.0/255.0; FragColor.b = 210.0/255.0;
break;
case 24:
FragColor.r = 60.0/255.0; FragColor.g = 60.0/255.0; FragColor.b = 60.0/255.0;
break;
case 25:
FragColor.r = 255.0/255.0; FragColor.g = 165.0/255.0; FragColor.b = 0.0/255.0;
break;
case 26:
FragColor.r = 255.0/255.0; FragColor.g = 165.0/255.0; FragColor.b = 0.0/255.0;
break;
case 27:
FragColor.r = 0.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 127.0/255.0;
break;
case 28:
FragColor.r = 165.0/255.0; FragColor.g = 42.0/255.0; FragColor.b = 42.0/255.0;
break;
case 29:
FragColor.r = 135.0/255.0; FragColor.g = 206.0/255.0; FragColor.b = 235.0/255.0;
break;
case 30:
FragColor.r = 160.0/255.0; FragColor.g = 32.0/255.0; FragColor.b = 240.0/255.0;
break;
case 31:
FragColor.r = 0.0/255.0; FragColor.g = 200.0/255.0; FragColor.b = 200.0/255.0;
break;
case 32:
FragColor.r = 100.0/255.0; FragColor.g = 50.0/255.0; FragColor.b = 100.0/255.0;
break;
case 33:
FragColor.r = 135.0/255.0; FragColor.g = 50.0/255.0; FragColor.b = 74.0/255.0;
break;
case 34:
FragColor.r = 122.0/255.0; FragColor.g = 135.0/255.0; FragColor.b = 50.0/255.0;
break;
case 35:
FragColor.r = 51.0/255.0; FragColor.g = 50.0/255.0; FragColor.b = 135.0/255.0;
break;
case 36:
FragColor.r = 74.0/255.0; FragColor.g = 155.0/255.0; FragColor.b = 60.0/255.0;
break;
case 37:
FragColor.r = 120.0/255.0; FragColor.g = 62.0/255.0; FragColor.b = 43.0/255.0;
break;
case 38:
FragColor.r = 74.0/255.0; FragColor.g = 155.0/255.0; FragColor.b = 60.0/255.0;
break;
case 39:
FragColor.r = 122.0/255.0; FragColor.g = 135.0/255.0; FragColor.b = 50.0/255.0;
break;
case 40:
FragColor.r = 70.0/255.0; FragColor.g = 130.0/255.0; FragColor.b = 180.0/255.0;
break;
case 41:
FragColor.r = 245.0/255.0; FragColor.g = 245.0/255.0; FragColor.b = 245.0/255.0;
break;
case 42:
FragColor.r = 205.0/255.0; FragColor.g = 62.0/255.0; FragColor.b = 78.0/255.0;
break;
case 43:
FragColor.r = 120.0/255.0; FragColor.g = 18.0/255.0; FragColor.b = 134.0/255.0;
break;
case 44:
FragColor.r = 196.0/255.0; FragColor.g = 58.0/255.0; FragColor.b = 250.0/255.0;
break;
case 45:
FragColor.r = 0.0/255.0; FragColor.g = 148.0/255.0; FragColor.b = 0.0/255.0;
break;
case 46:
FragColor.r = 220.0/255.0; FragColor.g = 248.0/255.0; FragColor.b = 164.0/255.0;
break;
case 47:
FragColor.r = 230.0/255.0; FragColor.g = 148.0/255.0; FragColor.b = 34.0/255.0;
break;
case 48:
FragColor.r = 0.0/255.0; FragColor.g = 118.0/255.0; FragColor.b = 14.0/255.0;
break;
case 49:
FragColor.r = 0.0/255.0; FragColor.g = 118.0/255.0; FragColor.b = 14.0/255.0;
break;
case 50:
FragColor.r = 122.0/255.0; FragColor.g = 186.0/255.0; FragColor.b = 220.0/255.0;
break;
case 51:
FragColor.r = 236.0/255.0; FragColor.g = 13.0/255.0; FragColor.b = 176.0/255.0;
break;
case 52:
FragColor.r = 13.0/255.0; FragColor.g = 48.0/255.0; FragColor.b = 255.0/255.0;
break;
case 53:
FragColor.r = 220.0/255.0; FragColor.g = 216.0/255.0; FragColor.b = 20.0/255.0;
break;
case 54:
FragColor.r = 103.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 255.0/255.0;
break;
case 55:
FragColor.r = 80.0/255.0; FragColor.g = 196.0/255.0; FragColor.b = 98.0/255.0;
break;
case 56:
FragColor.r = 60.0/255.0; FragColor.g = 58.0/255.0; FragColor.b = 210.0/255.0;
break;
case 57:
FragColor.r = 255.0/255.0; FragColor.g = 165.0/255.0; FragColor.b = 0.0/255.0;
break;
case 58:
FragColor.r = 255.0/255.0; FragColor.g = 165.0/255.0; FragColor.b = 0.0/255.0;
break;
case 59:
FragColor.r = 0.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 127.0/255.0;
break;
case 60:
FragColor.r = 165.0/255.0; FragColor.g = 42.0/255.0; FragColor.b = 42.0/255.0;
break;
case 61:
FragColor.r = 135.0/255.0; FragColor.g = 206.0/255.0; FragColor.b = 235.0/255.0;
break;
case 62:
FragColor.r = 160.0/255.0; FragColor.g = 32.0/255.0; FragColor.b = 240.0/255.0;
break;
case 63:
FragColor.r = 0.0/255.0; FragColor.g = 200.0/255.0; FragColor.b = 221.0/255.0;
break;
case 64:
FragColor.r = 100.0/255.0; FragColor.g = 50.0/255.0; FragColor.b = 100.0/255.0;
break;
case 65:
FragColor.r = 135.0/255.0; FragColor.g = 50.0/255.0; FragColor.b = 74.0/255.0;
break;
case 66:
FragColor.r = 122.0/255.0; FragColor.g = 135.0/255.0; FragColor.b = 50.0/255.0;
break;
case 67:
FragColor.r = 51.0/255.0; FragColor.g = 50.0/255.0; FragColor.b = 135.0/255.0;
break;
case 68:
FragColor.r = 74.0/255.0; FragColor.g = 155.0/255.0; FragColor.b = 60.0/255.0;
break;
case 69:
FragColor.r = 120.0/255.0; FragColor.g = 62.0/255.0; FragColor.b = 43.0/255.0;
break;
case 70:
FragColor.r = 74.0/255.0; FragColor.g = 155.0/255.0; FragColor.b = 60.0/255.0;
break;
case 71:
FragColor.r = 122.0/255.0; FragColor.g = 135.0/255.0; FragColor.b = 50.0/255.0;
break;
case 72:
FragColor.r = 120.0/255.0; FragColor.g = 190.0/255.0; FragColor.b = 150.0/255.0;
break;
case 73:
FragColor.r = 122.0/255.0; FragColor.g = 135.0/255.0; FragColor.b = 50.0/255.0;
break;
case 74:
FragColor.r = 122.0/255.0; FragColor.g = 135.0/255.0; FragColor.b = 50.0/255.0;
break;
case 77:
FragColor.r = 200.0/255.0; FragColor.g = 70.0/255.0; FragColor.b = 255.0/255.0;
break;
case 78:
FragColor.r = 255.0/255.0; FragColor.g = 148.0/255.0; FragColor.b = 10.0/255.0;
break;
case 79:
FragColor.r = 255.0/255.0; FragColor.g = 148.0/255.0; FragColor.b = 10.0/255.0;
break;
case 80:
FragColor.r = 164.0/255.0; FragColor.g = 108.0/255.0; FragColor.b = 226.0/255.0;
break;
case 81:
FragColor.r = 164.0/255.0; FragColor.g = 108.0/255.0; FragColor.b = 226.0/255.0;
break;
case 82:
FragColor.r = 164.0/255.0; FragColor.g = 108.0/255.0; FragColor.b = 226.0/255.0;
break;
case 83:
FragColor.r = 255.0/255.0; FragColor.g = 218.0/255.0; FragColor.b = 185.0/255.0;
break;
case 84:
FragColor.r = 255.0/255.0; FragColor.g = 218.0/255.0; FragColor.b = 185.0/255.0;
break;
case 85:
FragColor.r = 234.0/255.0; FragColor.g = 169.0/255.0; FragColor.b = 30.0/255.0;
break;
case 192:
FragColor.r = 250.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 50.0/255.0;
break;
case 86:
FragColor.r = 200.0/255.0; FragColor.g = 120.0/255.0; FragColor.b = 255.0/255.0;
break;
case 87:
FragColor.r = 200.0/255.0; FragColor.g = 121.0/255.0; FragColor.b = 255.0/255.0;
break;
case 88:
FragColor.r = 200.0/255.0; FragColor.g = 122.0/255.0; FragColor.b = 255.0/255.0;
break;
case 96:
FragColor.r = 205.0/255.0; FragColor.g = 10.0/255.0; FragColor.b = 125.0/255.0;
break;
case 97:
FragColor.r = 205.0/255.0; FragColor.g = 10.0/255.0; FragColor.b = 125.0/255.0;
break;
case 98:
FragColor.r = 160.0/255.0; FragColor.g = 32.0/255.0; FragColor.b = 240.0/255.0;
break;
case 100:
FragColor.r = 124.0/255.0; FragColor.g = 140.0/255.0; FragColor.b = 178.0/255.0;
break;
case 101:
FragColor.r = 125.0/255.0; FragColor.g = 140.0/255.0; FragColor.b = 178.0/255.0;
break;
case 102:
FragColor.r = 126.0/255.0; FragColor.g = 140.0/255.0; FragColor.b = 178.0/255.0;
break;
case 103:
FragColor.r = 127.0/255.0; FragColor.g = 140.0/255.0; FragColor.b = 178.0/255.0;
break;
case 104:
FragColor.r = 124.0/255.0; FragColor.g = 141.0/255.0; FragColor.b = 178.0/255.0;
break;
case 105:
FragColor.r = 124.0/255.0; FragColor.g = 142.0/255.0; FragColor.b = 178.0/255.0;
break;
case 106:
FragColor.r = 124.0/255.0; FragColor.g = 143.0/255.0; FragColor.b = 178.0/255.0;
break;
case 107:
FragColor.r = 124.0/255.0; FragColor.g = 144.0/255.0; FragColor.b = 178.0/255.0;
break;
case 108:
FragColor.r = 124.0/255.0; FragColor.g = 140.0/255.0; FragColor.b = 179.0/255.0;
break;
case 109:
FragColor.r = 124.0/255.0; FragColor.g = 140.0/255.0; FragColor.b = 178.0/255.0;
break;
case 110:
FragColor.r = 125.0/255.0; FragColor.g = 140.0/255.0; FragColor.b = 178.0/255.0;
break;
case 111:
FragColor.r = 126.0/255.0; FragColor.g = 140.0/255.0; FragColor.b = 178.0/255.0;
break;
case 112:
FragColor.r = 127.0/255.0; FragColor.g = 140.0/255.0; FragColor.b = 178.0/255.0;
break;
case 113:
FragColor.r = 124.0/255.0; FragColor.g = 141.0/255.0; FragColor.b = 178.0/255.0;
break;
case 114:
FragColor.r = 124.0/255.0; FragColor.g = 142.0/255.0; FragColor.b = 178.0/255.0;
break;
case 115:
FragColor.r = 124.0/255.0; FragColor.g = 143.0/255.0; FragColor.b = 178.0/255.0;
break;
case 116:
FragColor.r = 124.0/255.0; FragColor.g = 144.0/255.0; FragColor.b = 178.0/255.0;
break;
case 117:
FragColor.r = 124.0/255.0; FragColor.g = 140.0/255.0; FragColor.b = 179.0/255.0;
break;
case 118:
FragColor.r = 255.0/255.0; FragColor.g = 20.0/255.0; FragColor.b = 147.0/255.0;
break;
case 119:
FragColor.r = 205.0/255.0; FragColor.g = 179.0/255.0; FragColor.b = 139.0/255.0;
break;
case 120:
FragColor.r = 238.0/255.0; FragColor.g = 238.0/255.0; FragColor.b = 209.0/255.0;
break;
case 121:
FragColor.r = 200.0/255.0; FragColor.g = 200.0/255.0; FragColor.b = 200.0/255.0;
break;
case 122:
FragColor.r = 74.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 74.0/255.0;
break;
case 123:
FragColor.r = 238.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 0.0/255.0;
break;
case 124:
FragColor.r = 0.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 139.0/255.0;
break;
case 125:
FragColor.r = 173.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 47.0/255.0;
break;
case 126:
FragColor.r = 133.0/255.0; FragColor.g = 203.0/255.0; FragColor.b = 229.0/255.0;
break;
case 127:
FragColor.r = 26.0/255.0; FragColor.g = 237.0/255.0; FragColor.b = 57.0/255.0;
break;
case 128:
FragColor.r = 34.0/255.0; FragColor.g = 139.0/255.0; FragColor.b = 34.0/255.0;
break;
case 129:
FragColor.r = 30.0/255.0; FragColor.g = 144.0/255.0; FragColor.b = 255.0/255.0;
break;
case 130:
FragColor.r = 147.0/255.0; FragColor.g = 19.0/255.0; FragColor.b = 173.0/255.0;
break;
case 131:
FragColor.r = 238.0/255.0; FragColor.g = 59.0/255.0; FragColor.b = 59.0/255.0;
break;
case 132:
FragColor.r = 221.0/255.0; FragColor.g = 39.0/255.0; FragColor.b = 200.0/255.0;
break;
case 133:
FragColor.r = 238.0/255.0; FragColor.g = 174.0/255.0; FragColor.b = 238.0/255.0;
break;
case 134:
FragColor.r = 255.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 0.0/255.0;
break;
case 135:
FragColor.r = 72.0/255.0; FragColor.g = 61.0/255.0; FragColor.b = 139.0/255.0;
break;
case 136:
FragColor.r = 21.0/255.0; FragColor.g = 39.0/255.0; FragColor.b = 132.0/255.0;
break;
case 137:
FragColor.r = 21.0/255.0; FragColor.g = 39.0/255.0; FragColor.b = 132.0/255.0;
break;
case 138:
FragColor.r = 65.0/255.0; FragColor.g = 135.0/255.0; FragColor.b = 20.0/255.0;
break;
case 139:
FragColor.r = 65.0/255.0; FragColor.g = 135.0/255.0; FragColor.b = 20.0/255.0;
break;
case 140:
FragColor.r = 134.0/255.0; FragColor.g = 4.0/255.0; FragColor.b = 160.0/255.0;
break;
case 142:
FragColor.r = 221.0/255.0; FragColor.g = 226.0/255.0; FragColor.b = 68.0/255.0;
break;
case 143:
FragColor.r = 255.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 254.0/255.0;
break;
case 144:
FragColor.r = 52.0/255.0; FragColor.g = 209.0/255.0; FragColor.b = 226.0/255.0;
break;
case 145:
FragColor.r = 239.0/255.0; FragColor.g = 160.0/255.0; FragColor.b = 223.0/255.0;
break;
case 146:
FragColor.r = 70.0/255.0; FragColor.g = 130.0/255.0; FragColor.b = 180.0/255.0;
break;
case 147:
FragColor.r = 70.0/255.0; FragColor.g = 130.0/255.0; FragColor.b = 181.0/255.0;
break;
case 148:
FragColor.r = 139.0/255.0; FragColor.g = 121.0/255.0; FragColor.b = 94.0/255.0;
break;
case 149:
FragColor.r = 224.0/255.0; FragColor.g = 224.0/255.0; FragColor.b = 224.0/255.0;
break;
case 150:
FragColor.r = 255.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 0.0/255.0;
break;
case 151:
FragColor.r = 205.0/255.0; FragColor.g = 205.0/255.0; FragColor.b = 0.0/255.0;
break;
case 152:
FragColor.r = 238.0/255.0; FragColor.g = 238.0/255.0; FragColor.b = 209.0/255.0;
break;
case 153:
FragColor.r = 139.0/255.0; FragColor.g = 121.0/255.0; FragColor.b = 94.0/255.0;
break;
case 154:
FragColor.r = 238.0/255.0; FragColor.g = 59.0/255.0; FragColor.b = 59.0/255.0;
break;
case 155:
FragColor.r = 238.0/255.0; FragColor.g = 59.0/255.0; FragColor.b = 59.0/255.0;
break;
case 156:
FragColor.r = 238.0/255.0; FragColor.g = 59.0/255.0; FragColor.b = 59.0/255.0;
break;
case 157:
FragColor.r = 62.0/255.0; FragColor.g = 10.0/255.0; FragColor.b = 205.0/255.0;
break;
case 158:
FragColor.r = 62.0/255.0; FragColor.g = 10.0/255.0; FragColor.b = 205.0/255.0;
break;
case 159:
FragColor.r = 0.0/255.0; FragColor.g = 118.0/255.0; FragColor.b = 14.0/255.0;
break;
case 160:
FragColor.r = 0.0/255.0; FragColor.g = 118.0/255.0; FragColor.b = 14.0/255.0;
break;
case 161:
FragColor.r = 220.0/255.0; FragColor.g = 216.0/255.0; FragColor.b = 21.0/255.0;
break;
case 162:
FragColor.r = 220.0/255.0; FragColor.g = 216.0/255.0; FragColor.b = 21.0/255.0;
break;
case 163:
FragColor.r = 122.0/255.0; FragColor.g = 186.0/255.0; FragColor.b = 220.0/255.0;
break;
case 164:
FragColor.r = 122.0/255.0; FragColor.g = 186.0/255.0; FragColor.b = 220.0/255.0;
break;
case 165:
FragColor.r = 120.0/255.0; FragColor.g = 120.0/255.0; FragColor.b = 120.0/255.0;
break;
case 166:
FragColor.r = 14.0/255.0; FragColor.g = 48.0/255.0; FragColor.b = 255.0/255.0;
break;
case 167:
FragColor.r = 166.0/255.0; FragColor.g = 42.0/255.0; FragColor.b = 42.0/255.0;
break;
case 168:
FragColor.r = 121.0/255.0; FragColor.g = 18.0/255.0; FragColor.b = 134.0/255.0;
break;
case 169:
FragColor.r = 236.0/255.0; FragColor.g = 13.0/255.0; FragColor.b = 127.0/255.0;
break;
ca