hbauzan's picture
Release v4.17.7 — sync from GitHub main
819a47f
Raw
History Blame Contribute Delete
2.94 kB
// Vertex Shader: Calcula tamaño y posición
export const vertexShader = `
attribute float intensity;
attribute float vertexIndex;
varying float vIntensity;
varying float vIsHighlight;
uniform float highlightIndex;
uniform float pointSpacing;
uniform float dotSize; // Tamaño visual independiente del spacing
void main() {
vIntensity = intensity;
// Use explicit attribute for index
float index = vertexIndex;
// Si este punto es el seleccionado, marcamos highlight
if (abs(index - highlightIndex) < 0.1) vIsHighlight = 1.0;
else vIsHighlight = 0.0;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
float dist = length(mvPosition.xyz);
// Tamaño dinámico basado en dotSize (independiente del pointSpacing)
float size = dotSize;
if (vIsHighlight > 0.5) size *= 2.5;
gl_PointSize = clamp(size * (300.0 / dist), 3.0, 120.0);
gl_Position = projectionMatrix * mvPosition;
}
`;
// Fragment Shader: Colormap perceptual Viridis
export const fragmentShader = `
varying float vIntensity;
varying float vIsHighlight;
uniform float opacity;
uniform vec3 color; // Base color from Uniform
vec3 sampleViridis(float t) {
float clampedT = clamp(t, 0.0, 1.0);
float scaled = clampedT * 8.0;
int idx = int(floor(scaled));
float frac = fract(scaled);
vec3 c0 = vec3(0.267004, 0.004874, 0.329415);
vec3 c1 = vec3(0.282327, 0.160431, 0.457811);
vec3 c2 = vec3(0.253935, 0.265254, 0.529983);
vec3 c3 = vec3(0.191090, 0.364218, 0.548574);
vec3 c4 = vec3(0.127568, 0.456911, 0.550996);
vec3 c5 = vec3(0.121148, 0.547463, 0.506309);
vec3 c6 = vec3(0.236780, 0.636730, 0.420680);
vec3 c7 = vec3(0.460673, 0.723062, 0.303117);
vec3 c8 = vec3(0.993248, 0.906157, 0.143936);
if (idx == 0) return mix(c0, c1, frac);
if (idx == 1) return mix(c1, c2, frac);
if (idx == 2) return mix(c2, c3, frac);
if (idx == 3) return mix(c3, c4, frac);
if (idx == 4) return mix(c4, c5, frac);
if (idx == 5) return mix(c5, c6, frac);
if (idx == 6) return mix(c6, c7, frac);
return mix(c7, c8, frac);
}
vec4 getActivationColor(float v) {
float clampedV = clamp(v, -1.0, 1.0);
float t01 = (clampedV + 1.0) * 0.5;
vec3 col = sampleViridis(t01);
return vec4(col, 1.0);
}
void main() {
vec2 coord = gl_PointCoord - vec2(0.5);
if (length(coord) > 0.5) discard; // Círculo perfecto
vec4 activation = getActivationColor(vIntensity);
vec3 finalColor = activation.rgb * opacity;
float alpha = 1.0;
// Si está seleccionado, brilla en BLANCO PURO
if (vIsHighlight > 0.5) {
finalColor = vec3(1.0, 1.0, 1.0);
}
gl_FragColor = vec4(finalColor, alpha);
}
`;