@chinhui/niivue
Version:
minimal webgl2 nifti image viewer
1,223 lines (1,220 loc) • 1.76 MB
JavaScript
(function(u,h){typeof exports=="object"&&typeof module!="undefined"?h(exports):typeof define=="function"&&define.amd?define(["exports"],h):(u=typeof globalThis!="undefined"?globalThis:u||self,h(u.niivue={}))})(this,function(exports){"use strict";function Shader(u,h,d){var F=this;this.program=compileShader(u,h,d);var k=/uniform[^;]+[ ](\w+);/g,_=/uniform[^;]+[ ](\w+);/;this.uniforms={};var P=h.match(k),L=d.match(k);P&&P.forEach(function(z){var U=z.match(_);F.uniforms[U[1]]=-1}),L&&L.forEach(function(z){var U=z.match(_);F.uniforms[U[1]]=-1});for(var Q in this.uniforms)this.uniforms[Q]=u.getUniformLocation(this.program,Q)}Shader.prototype.use=function(u){u.useProgram(this.program)};var compileShader=function(u,h,d){var F=u.createShader(u.VERTEX_SHADER);if(u.shaderSource(F,h),u.compileShader(F),!u.getShaderParameter(F,u.COMPILE_STATUS))return alert("Vertex shader failed to compile, see console for log"),console.log(u.getShaderInfoLog(F)),null;var k=u.createShader(u.FRAGMENT_SHADER);if(u.shaderSource(k,d),u.compileShader(k),!u.getShaderParameter(k,u.COMPILE_STATUS))return alert("Fragment shader failed to compile, see console for log"),console.log(u.getShaderInfoLog(k)),null;var _=u.createProgram();return u.attachShader(_,F),u.attachShader(_,k),u.linkProgram(_),u.getProgramParameter(_,u.LINK_STATUS)?_:(alert("Shader failed to link, see console for log"),console.log(u.getProgramInfoLog(_)),null)},ARRAY_TYPE=typeof Float32Array!="undefined"?Float32Array:Array;Math.hypot||(Math.hypot=function(){for(var u=0,h=arguments.length;h--;)u+=arguments[h]*arguments[h];return Math.sqrt(u)});function create$3(){var u=new ARRAY_TYPE(9);return ARRAY_TYPE!=Float32Array&&(u[1]=0,u[2]=0,u[3]=0,u[5]=0,u[6]=0,u[7]=0),u[0]=1,u[4]=1,u[8]=1,u}function fromValues$3(u,h,d,F,k,_,P,L,Q){var z=new ARRAY_TYPE(9);return z[0]=u,z[1]=h,z[2]=d,z[3]=F,z[4]=k,z[5]=_,z[6]=P,z[7]=L,z[8]=Q,z}function multiply$2(u,h,d){var F=h[0],k=h[1],_=h[2],P=h[3],L=h[4],Q=h[5],z=h[6],U=h[7],S=h[8],O=d[0],e=d[1],$=d[2],j=d[3],n0=d[4],h0=d[5],u0=d[6],g0=d[7],w=d[8];return u[0]=O*F+e*P+$*z,u[1]=O*k+e*L+$*U,u[2]=O*_+e*Q+$*S,u[3]=j*F+n0*P+h0*z,u[4]=j*k+n0*L+h0*U,u[5]=j*_+n0*Q+h0*S,u[6]=u0*F+g0*P+w*z,u[7]=u0*k+g0*L+w*U,u[8]=u0*_+g0*Q+w*S,u}function create$2(){var u=new ARRAY_TYPE(16);return ARRAY_TYPE!=Float32Array&&(u[1]=0,u[2]=0,u[3]=0,u[4]=0,u[6]=0,u[7]=0,u[8]=0,u[9]=0,u[11]=0,u[12]=0,u[13]=0,u[14]=0),u[0]=1,u[5]=1,u[10]=1,u[15]=1,u}function clone$1(u){var h=new ARRAY_TYPE(16);return h[0]=u[0],h[1]=u[1],h[2]=u[2],h[3]=u[3],h[4]=u[4],h[5]=u[5],h[6]=u[6],h[7]=u[7],h[8]=u[8],h[9]=u[9],h[10]=u[10],h[11]=u[11],h[12]=u[12],h[13]=u[13],h[14]=u[14],h[15]=u[15],h}function copy$1(u,h){return u[0]=h[0],u[1]=h[1],u[2]=h[2],u[3]=h[3],u[4]=h[4],u[5]=h[5],u[6]=h[6],u[7]=h[7],u[8]=h[8],u[9]=h[9],u[10]=h[10],u[11]=h[11],u[12]=h[12],u[13]=h[13],u[14]=h[14],u[15]=h[15],u}function fromValues$2(u,h,d,F,k,_,P,L,Q,z,U,S,O,e,$,j){var n0=new ARRAY_TYPE(16);return n0[0]=u,n0[1]=h,n0[2]=d,n0[3]=F,n0[4]=k,n0[5]=_,n0[6]=P,n0[7]=L,n0[8]=Q,n0[9]=z,n0[10]=U,n0[11]=S,n0[12]=O,n0[13]=e,n0[14]=$,n0[15]=j,n0}function identity$1(u){return u[0]=1,u[1]=0,u[2]=0,u[3]=0,u[4]=0,u[5]=1,u[6]=0,u[7]=0,u[8]=0,u[9]=0,u[10]=1,u[11]=0,u[12]=0,u[13]=0,u[14]=0,u[15]=1,u}function transpose(u,h){if(u===h){var d=h[1],F=h[2],k=h[3],_=h[6],P=h[7],L=h[11];u[1]=h[4],u[2]=h[8],u[3]=h[12],u[4]=d,u[6]=h[9],u[7]=h[13],u[8]=F,u[9]=_,u[11]=h[14],u[12]=k,u[13]=P,u[14]=L}else u[0]=h[0],u[1]=h[4],u[2]=h[8],u[3]=h[12],u[4]=h[1],u[5]=h[5],u[6]=h[9],u[7]=h[13],u[8]=h[2],u[9]=h[6],u[10]=h[10],u[11]=h[14],u[12]=h[3],u[13]=h[7],u[14]=h[11],u[15]=h[15];return u}function invert(u,h){var d=h[0],F=h[1],k=h[2],_=h[3],P=h[4],L=h[5],Q=h[6],z=h[7],U=h[8],S=h[9],O=h[10],e=h[11],$=h[12],j=h[13],n0=h[14],h0=h[15],u0=d*L-F*P,g0=d*Q-k*P,w=d*z-_*P,a0=F*Q-k*L,r0=F*z-_*L,s0=k*z-_*Q,l0=U*j-S*$,i0=U*n0-O*$,f=U*h0-e*$,F0=S*n0-O*j,C0=S*h0-e*j,_0=O*h0-e*n0,A0=u0*_0-g0*C0+w*F0+a0*f-r0*i0+s0*l0;return A0?(A0=1/A0,u[0]=(L*_0-Q*C0+z*F0)*A0,u[1]=(k*C0-F*_0-_*F0)*A0,u[2]=(j*s0-n0*r0+h0*a0)*A0,u[3]=(O*r0-S*s0-e*a0)*A0,u[4]=(Q*f-P*_0-z*i0)*A0,u[5]=(d*_0-k*f+_*i0)*A0,u[6]=(n0*w-$*s0-h0*g0)*A0,u[7]=(U*s0-O*w+e*g0)*A0,u[8]=(P*C0-L*f+z*l0)*A0,u[9]=(F*f-d*C0-_*l0)*A0,u[10]=($*r0-j*w+h0*u0)*A0,u[11]=(S*w-U*r0-e*u0)*A0,u[12]=(L*i0-P*F0-Q*l0)*A0,u[13]=(d*F0-F*i0+k*l0)*A0,u[14]=(j*g0-$*a0-n0*u0)*A0,u[15]=(U*a0-S*g0+O*u0)*A0,u):null}function multiply$1(u,h,d){var F=h[0],k=h[1],_=h[2],P=h[3],L=h[4],Q=h[5],z=h[6],U=h[7],S=h[8],O=h[9],e=h[10],$=h[11],j=h[12],n0=h[13],h0=h[14],u0=h[15],g0=d[0],w=d[1],a0=d[2],r0=d[3];return u[0]=g0*F+w*L+a0*S+r0*j,u[1]=g0*k+w*Q+a0*O+r0*n0,u[2]=g0*_+w*z+a0*e+r0*h0,u[3]=g0*P+w*U+a0*$+r0*u0,g0=d[4],w=d[5],a0=d[6],r0=d[7],u[4]=g0*F+w*L+a0*S+r0*j,u[5]=g0*k+w*Q+a0*O+r0*n0,u[6]=g0*_+w*z+a0*e+r0*h0,u[7]=g0*P+w*U+a0*$+r0*u0,g0=d[8],w=d[9],a0=d[10],r0=d[11],u[8]=g0*F+w*L+a0*S+r0*j,u[9]=g0*k+w*Q+a0*O+r0*n0,u[10]=g0*_+w*z+a0*e+r0*h0,u[11]=g0*P+w*U+a0*$+r0*u0,g0=d[12],w=d[13],a0=d[14],r0=d[15],u[12]=g0*F+w*L+a0*S+r0*j,u[13]=g0*k+w*Q+a0*O+r0*n0,u[14]=g0*_+w*z+a0*e+r0*h0,u[15]=g0*P+w*U+a0*$+r0*u0,u}function translate(u,h,d){var F=d[0],k=d[1],_=d[2],P,L,Q,z,U,S,O,e,$,j,n0,h0;return h===u?(u[12]=h[0]*F+h[4]*k+h[8]*_+h[12],u[13]=h[1]*F+h[5]*k+h[9]*_+h[13],u[14]=h[2]*F+h[6]*k+h[10]*_+h[14],u[15]=h[3]*F+h[7]*k+h[11]*_+h[15]):(P=h[0],L=h[1],Q=h[2],z=h[3],U=h[4],S=h[5],O=h[6],e=h[7],$=h[8],j=h[9],n0=h[10],h0=h[11],u[0]=P,u[1]=L,u[2]=Q,u[3]=z,u[4]=U,u[5]=S,u[6]=O,u[7]=e,u[8]=$,u[9]=j,u[10]=n0,u[11]=h0,u[12]=P*F+U*k+$*_+h[12],u[13]=L*F+S*k+j*_+h[13],u[14]=Q*F+O*k+n0*_+h[14],u[15]=z*F+e*k+h0*_+h[15]),u}function rotateX(u,h,d){var F=Math.sin(d),k=Math.cos(d),_=h[4],P=h[5],L=h[6],Q=h[7],z=h[8],U=h[9],S=h[10],O=h[11];return h!==u&&(u[0]=h[0],u[1]=h[1],u[2]=h[2],u[3]=h[3],u[12]=h[12],u[13]=h[13],u[14]=h[14],u[15]=h[15]),u[4]=_*k+z*F,u[5]=P*k+U*F,u[6]=L*k+S*F,u[7]=Q*k+O*F,u[8]=z*k-_*F,u[9]=U*k-P*F,u[10]=S*k-L*F,u[11]=O*k-Q*F,u}function rotateZ(u,h,d){var F=Math.sin(d),k=Math.cos(d),_=h[0],P=h[1],L=h[2],Q=h[3],z=h[4],U=h[5],S=h[6],O=h[7];return h!==u&&(u[8]=h[8],u[9]=h[9],u[10]=h[10],u[11]=h[11],u[12]=h[12],u[13]=h[13],u[14]=h[14],u[15]=h[15]),u[0]=_*k+z*F,u[1]=P*k+U*F,u[2]=L*k+S*F,u[3]=Q*k+O*F,u[4]=z*k-_*F,u[5]=U*k-P*F,u[6]=S*k-L*F,u[7]=O*k-Q*F,u}function orthoNO(u,h,d,F,k,_,P){var L=1/(h-d),Q=1/(F-k),z=1/(_-P);return u[0]=-2*L,u[1]=0,u[2]=0,u[3]=0,u[4]=0,u[5]=-2*Q,u[6]=0,u[7]=0,u[8]=0,u[9]=0,u[10]=2*z,u[11]=0,u[12]=(h+d)*L,u[13]=(k+F)*Q,u[14]=(P+_)*z,u[15]=1,u}var ortho=orthoNO;function multiplyScalar(u,h,d){return u[0]=h[0]*d,u[1]=h[1]*d,u[2]=h[2]*d,u[3]=h[3]*d,u[4]=h[4]*d,u[5]=h[5]*d,u[6]=h[6]*d,u[7]=h[7]*d,u[8]=h[8]*d,u[9]=h[9]*d,u[10]=h[10]*d,u[11]=h[11]*d,u[12]=h[12]*d,u[13]=h[13]*d,u[14]=h[14]*d,u[15]=h[15]*d,u}var mul$1=multiply$1;function create$1(){var u=new ARRAY_TYPE(3);return ARRAY_TYPE!=Float32Array&&(u[0]=0,u[1]=0,u[2]=0),u}function clone(u){var h=new ARRAY_TYPE(3);return h[0]=u[0],h[1]=u[1],h[2]=u[2],h}function length(u){var h=u[0],d=u[1],F=u[2];return Math.hypot(h,d,F)}function fromValues$1(u,h,d){var F=new ARRAY_TYPE(3);return F[0]=u,F[1]=h,F[2]=d,F}function copy(u,h){return u[0]=h[0],u[1]=h[1],u[2]=h[2],u}function add$1(u,h,d){return u[0]=h[0]+d[0],u[1]=h[1]+d[1],u[2]=h[2]+d[2],u}function subtract(u,h,d){return u[0]=h[0]-d[0],u[1]=h[1]-d[1],u[2]=h[2]-d[2],u}function min$Q(u,h,d){return u[0]=Math.min(h[0],d[0]),u[1]=Math.min(h[1],d[1]),u[2]=Math.min(h[2],d[2]),u}function max$R(u,h,d){return u[0]=Math.max(h[0],d[0]),u[1]=Math.max(h[1],d[1]),u[2]=Math.max(h[2],d[2]),u}function scale(u,h,d){return u[0]=h[0]*d,u[1]=h[1]*d,u[2]=h[2]*d,u}function negate(u,h){return u[0]=-h[0],u[1]=-h[1],u[2]=-h[2],u}function normalize(u,h){var d=h[0],F=h[1],k=h[2],_=d*d+F*F+k*k;return _>0&&(_=1/Math.sqrt(_)),u[0]=h[0]*_,u[1]=h[1]*_,u[2]=h[2]*_,u}function dot(u,h){return u[0]*h[0]+u[1]*h[1]+u[2]*h[2]}function cross(u,h,d){var F=h[0],k=h[1],_=h[2],P=d[0],L=d[1],Q=d[2];return u[0]=k*Q-_*L,u[1]=_*P-F*Q,u[2]=F*L-k*P,u}function lerp(u,h,d,F){var k=h[0],_=h[1],P=h[2];return u[0]=k+F*(d[0]-k),u[1]=_+F*(d[1]-_),u[2]=P+F*(d[2]-P),u}function angle(u,h){var d=u[0],F=u[1],k=u[2],_=h[0],P=h[1],L=h[2],Q=Math.sqrt(d*d+F*F+k*k),z=Math.sqrt(_*_+P*P+L*L),U=Q*z,S=U&&dot(u,h)/U;return Math.acos(Math.min(Math.max(S,-1),1))}var len=length;(function(){var u=create$1();return function(h,d,F,k,_,P){var L,Q;for(d||(d=3),F||(F=0),k?Q=Math.min(k*d+F,h.length):Q=h.length,L=F;L<Q;L+=d)u[0]=h[L],u[1]=h[L+1],u[2]=h[L+2],_(u,u,P),h[L]=u[0],h[L+1]=u[1],h[L+2]=u[2];return h}})();function create(){var u=new ARRAY_TYPE(4);return ARRAY_TYPE!=Float32Array&&(u[0]=0,u[1]=0,u[2]=0,u[3]=0),u}function fromValues(u,h,d,F){var k=new ARRAY_TYPE(4);return k[0]=u,k[1]=h,k[2]=d,k[3]=F,k}function add(u,h,d){return u[0]=h[0]+d[0],u[1]=h[1]+d[1],u[2]=h[2]+d[2],u[3]=h[3]+d[3],u}function multiply(u,h,d){return u[0]=h[0]*d[0],u[1]=h[1]*d[1],u[2]=h[2]*d[2],u[3]=h[3]*d[3],u}function transformMat4(u,h,d){var F=h[0],k=h[1],_=h[2],P=h[3];return u[0]=d[0]*F+d[4]*k+d[8]*_+d[12]*P,u[1]=d[1]*F+d[5]*k+d[9]*_+d[13]*P,u[2]=d[2]*F+d[6]*k+d[10]*_+d[14]*P,u[3]=d[3]*F+d[7]*k+d[11]*_+d[15]*P,u}var mul=multiply;(function(){var u=create();return function(h,d,F,k,_,P){var L,Q;for(d||(d=4),F||(F=0),k?Q=Math.min(k*d+F,h.length):Q=h.length,L=F;L<Q;L+=d)u[0]=h[L],u[1]=h[L+1],u[2]=h[L+2],u[3]=h[L+3],_(u,u,P),h[L]=u[0],h[L+1]=u[1],h[L+2]=u[2],h[L+3]=u[3];return h}})();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);
}`,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);
}`,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;
}`,fragLineShader=`#version 300 es
#line 189
precision highp int;
precision highp float;
uniform vec4 lineColor;
out vec4 color;
void main() {
color = lineColor;
}`,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;
}`,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);
}`,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);
}`,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);
}`,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);
}`,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) );
}`,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);
}`,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);
}`,fragOrientShaderU=`#version 300 es
uniform highp usampler3D intensityVol;
`,fragOrientShaderI=`#version 300 es
uniform highp isampler3D intensityVol;
`,fragOrientShaderF=`#version 300 es
uniform highp sampler3D intensityVol;
`,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;
}`,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;
}`,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;
}`,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;
case 176:
FragColor.r = 236.0/255.0; FragColor.g = 13.0/255.0; FragColor.b = 126.0/255.0;
break;
case 170:
FragColor.r = 119.0/255.0; FragColor.g = 159.0/255.0; FragColor.b = 176.0/255.0;
break;
case 171:
FragColor.r = 119.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 176.0/255.0;
break;
case 172:
FragColor.r = 119.0/255.0; FragColor.g = 100.0/255.0; FragColor.b = 176.0/255.0;
break;
case 173:
FragColor.r = 242.0/255.0; FragColor.g = 104.0/255.0; FragColor.b = 76.0/255.0;
break;
case 174:
FragColor.r = 206.0/255.0; FragColor.g = 195.0/255.0; FragColor.b = 58.0/255.0;
break;
case 175:
FragColor.r = 119.0/255.0; FragColor.g = 159.0/255.0; FragColor.b = 176.0/255.0;
break;
case 177:
FragColor.r = 119.0/255.0; FragColor.g = 50.0/255.0; FragColor.b = 176.0/255.0;
break;
case 178:
FragColor.r = 142.0/255.0; FragColor.g = 182.0/255.0; FragColor.b = 0.0/255.0;
break;
case 179:
FragColor.r = 19.0/255.0; FragColor.g = 100.0/255.0; FragColor.b = 176.0/255.0;
break;
case 180:
FragColor.r = 73.0/255.0; FragColor.g = 61.0/255.0; FragColor.b = 139.0/255.0;
break;
case 181:
FragColor.r = 73.0/255.0; FragColor.g = 62.0/255.0; FragColor.b = 139.0/255.0;
break;
case 182:
FragColor.r = 10.0/255.0; FragColor.g = 100.0/255.0; FragColor.b = 176.0/255.0;
break;
case 193:
FragColor.r = 0.0/255.0; FragColor.g = 196.0/255.0; FragColor.b = 255.0/255.0;
break;
case 194:
FragColor.r = 255.0/255.0; FragColor.g = 164.0/255.0; FragColor.b = 164.0/255.0;
break;
case 195:
FragColor.r = 196.0/255.0; FragColor.g = 196.0/255.0; FragColor.b = 0.0/255.0;
break;
case 196:
FragColor.r = 0.0/255.0; FragColor.g = 100.0/255.0; FragColor.b = 255.0/255.0;
break;
case 197:
FragColor.r = 128.0/255.0; FragColor.g = 196.0/255.0; FragColor.b = 164.0/255.0;
break;
case 198:
FragColor.r = 0.0/255.0; FragColor.g = 126.0/255.0; FragColor.b = 75.0/255.0;
break;
case 199:
FragColor.r = 128.0/255.0; FragColor.g = 96.0/255.0; FragColor.b = 64.0/255.0;
break;
case 200:
FragColor.r = 0.0/255.0; FragColor.g = 50.0/255.0; FragColor.b = 128.0/255.0;
break;
case 201:
FragColor.r = 255.0/255.0; FragColor.g = 204.0/255.0; FragColor.b = 153.0/255.0;
break;
case 202:
FragColor.r = 255.0/255.0; FragColor.g = 128.0/255.0; FragColor.b = 128.0/255.0;
break;
case 203:
FragColor.r = 255.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 0.0/255.0;
break;
case 204:
FragColor.r = 64.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 64.0/255.0;
break;
case 205:
FragColor.r = 0.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 255.0/255.0;
break;
case 206:
FragColor.r = 255.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 0.0/255.0;
break;
case 207:
FragColor.r = 128.0/255.0; FragColor.g = 128.0/255.0; FragColor.b = 255.0/255.0;
break;
case 208:
FragColor.r = 0.0/255.0; FragColor.g = 128.0/255.0; FragColor.b = 0.0/255.0;
break;
case 209:
FragColor.r = 196.0/255.0; FragColor.g = 160.0/255.0; FragColor.b = 128.0/255.0;
break;
case 210:
FragColor.r = 32.0/255.0; FragColor.g = 200.0/255.0; FragColor.b = 255.0/255.0;
break;
case 211:
FragColor.r = 128.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 128.0/255.0;
break;
case 212:
FragColor.r = 204.0/255.0; FragColor.g = 153.0/255.0; FragColor.b = 204.0/255.0;
break;
case 213:
FragColor.r = 121.0/255.0; FragColor.g = 17.0/255.0; FragColor.b = 136.0/255.0;
break;
case 214:
FragColor.r = 128.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 0.0/255.0;
break;
case 215:
FragColor.r = 128.0/255.0; FragColor.g = 32.0/255.0; FragColor.b = 255.0/255.0;
break;
case 216:
FragColor.r = 255.0/255.0; FragColor.g = 204.0/255.0; FragColor.b = 102.0/255.0;
break;
case 217:
FragColor.r = 128.0/255.0; FragColor.g = 128.0/255.0; FragColor.b = 128.0/255.0;
break;
case 218:
FragColor.r = 104.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 255.0/255.0;
break;
case 219:
FragColor.r = 0.0/255.0; FragColor.g = 226.0/255.0; FragColor.b = 0.0/255.0;
break;
case 220:
FragColor.r = 205.0/255.0; FragColor.g = 63.0/255.0; FragColor.b = 78.0/255.0;
break;
case 221:
FragColor.r = 197.0/255.0; FragColor.g = 58.0/255.0; FragColor.b = 250.0/255.0;
break;
case 222:
FragColor.r = 33.0/255.0; FragColor.g = 150.0/255.0; FragColor.b = 250.0/255.0;
break;
case 223:
FragColor.r = 226.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 0.0/255.0;
break;
case 224:
FragColor.r = 100.0/255.0; FragColor.g = 100.0/255.0; FragColor.b = 100.0/255.0;
break;
case 225:
FragColor.r = 197.0/255.0; FragColor.g = 150.0/255.0; FragColor.b = 250.0/255.0;
break;
case 226:
FragColor.r = 170.0/255.0; FragColor.g = 170.0/255.0; FragColor.b = 255.0/255.0;
break;
case 250:
FragColor.r = 255.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 0.0/255.0;
break;
case 251:
FragColor.r = 0.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 64.0/255.0;
break;
case 252:
FragColor.r = 0.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 112.0/255.0;
break;
case 253:
FragColor.r = 0.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 160.0/255.0;
break;
case 254:
FragColor.r = 0.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 208.0/255.0;
break;
case 255:
FragColor.r = 0.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 255.0/255.0;
break;
case 256:
FragColor.r = 0.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 0.0/255.0;
break;
case 257:
FragColor.r = 60.0/255.0; FragColor.g = 60.0/255.0; FragColor.b = 60.0/255.0;
break;
case 258:
FragColor.r = 150.0/255.0; FragColor.g = 150.0/255.0; FragColor.b = 200.0/255.0;
break;
case 259:
FragColor.r = 120.0/255.0; FragColor.g = 120.0/255.0; FragColor.b = 120.0/255.0;
break;
case 260:
FragColor.r = 119.0/255.0; FragColor.g = 159.0/255.0; FragColor.b = 176.0/255.0;
break;
case 261:
FragColor.r = 120.0/255.0; FragColor.g = 18.0/255.0; FragColor.b = 134.0/255.0;
break;
case 262:
FragColor.r = 119.0/255.0; FragColor.g = 159.0/255.0; FragColor.b = 176.0/255.0;
break;
case 263:
FragColor.r = 119.0/255.0; FragColor.g = 159.0/255.0; FragColor.b = 176.0/255.0;
break;
case 264:
FragColor.r = 119.0/255.0; FragColor.g = 159.0/255.0; FragColor.b = 176.0/255.0;
break;
case 331:
FragColor.r = 255.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 0.0/255.0;
break;
case 332:
FragColor.r = 255.0/255.0; FragColor.g = 80.0/255.0; FragColor.b = 0.0/255.0;
break;
case 333:
FragColor.r = 255.0/255.0; FragColor.g = 160.0/255.0; FragColor.b = 0.0/255.0;
break;
case 334:
FragColor.r = 255.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 0.0/255.0;
break;
case 335:
FragColor.r = 0.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 0.0/255.0;
break;
case 336:
FragColor.r = 255.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 160.0/255.0;
break;
case 337:
FragColor.r = 255.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 255.0/255.0;
break;
case 338:
FragColor.r = 255.0/255.0; FragColor.g = 50.0/255.0; FragColor.b = 80.0/255.0;
break;
case 339:
FragColor.r = 80.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 50.0/255.0;
break;
case 340:
FragColor.r = 160.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 50.0/255.0;
break;
case 341:
FragColor.r = 160.0/255.0; FragColor.g = 200.0/255.0; FragColor.b = 255.0/255.0;
break;
case 342:
FragColor.r = 0.0/255.0; FragColor.g = 255.0/255.0; FragColor.b = 160.0/255.0;
break;
case 343:
FragColor.r = 0.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 255.0/255.0;
break;
case 344:
FragColor.r = 80.0/255.0; FragColor.g = 50.0/255.0; FragColor.b = 255.0/255.0;
break;
case 345:
FragColor.r = 160.0/255.0; FragColor.g = 0.0/255.0; FragColor.b = 255.0/255.0;
brea