| 91 | if (!mountRef.current) return; |
| 92 | |
| 93 | function makePaletteTexture(stops: string[]): THREE.DataTexture { |
| 94 | let arr: string[]; |
| 95 | if (Array.isArray(stops) && stops.length > 0) { |
| 96 | arr = stops.length === 1 ? [stops[0], stops[0]] : stops; |
| 97 | } else { |
| 98 | arr = ["#ffffff", "#ffffff"]; |
| 99 | } |
| 100 | const w = arr.length; |
| 101 | const data = new Uint8Array(w * 4); |
| 102 | for (let i = 0; i < w; i++) { |
| 103 | const c = new THREE.Color(arr[i]); |
| 104 | data[i * 4 + 0] = Math.round(c.r * 255); |
| 105 | data[i * 4 + 1] = Math.round(c.g * 255); |
| 106 | data[i * 4 + 2] = Math.round(c.b * 255); |
| 107 | data[i * 4 + 3] = 255; |
| 108 | } |
| 109 | const tex = new THREE.DataTexture(data, w, 1, THREE.RGBAFormat); |
| 110 | tex.magFilter = THREE.LinearFilter; |
| 111 | tex.minFilter = THREE.LinearFilter; |
| 112 | tex.wrapS = THREE.ClampToEdgeWrapping; |
| 113 | tex.wrapT = THREE.ClampToEdgeWrapping; |
| 114 | tex.generateMipmaps = false; |
| 115 | tex.needsUpdate = true; |
| 116 | return tex; |
| 117 | } |
| 118 | |
| 119 | const paletteTex = makePaletteTexture(colors); |
| 120 | // Hard-code transparent background vector (alpha 0) |