Spaces:
Sleeping
Sleeping
| // 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); | |
| } | |
| `; | |