Libreria three.js
func3d è costruito su three.js, la libreria JavaScript di riferimento per la grafica 3D nel browser, e sul suo controllo di camera OrbitControls. Qui il perché della scelta, come è usata nel sito e quali sviluppi apre per i progetti di ricerca.
three.js in breve
three.js incapsula WebGL (la API grafica accelerata dalla GPU presente in ogni browser) in una scena a oggetti: geometrie, materiali, luci, camere. È un progetto open source maturo, con un ecosistema vastissimo di add-on ed esempi, ed è di fatto lo standard per la 3D sul web.
OrbitControls è l'add-on ufficiale per l'esplorazione orbitale: rotazione attorno a un target, zoom con la rotella, pan; è il modello di interazione naturale per l'ispezione di dati (a differenza dei controlli "in prima persona" pensati per i giochi).
Come sono usati nel sito
- Versioni: dal rilascio r150 three.js distribuisce solo moduli ES (niente più build globale UMD). Il sito storico resta su r128 (build globale, usata dai visualizzatori delle suite di fluidodinamica e fisica nucleare), mentre func3d è isolato su r185 tramite import‑map e un bootstrap a moduli che pubblica la libreria per la catena applicativa classica. I due mondi convivono senza conflitti.
- Fat lines (add-on Line2/LineMaterial): spessori di linea reali per i wireframe — WebGL di suo disegna linee da 1 pixel.
- InstancedMesh: le punte a cono delle frecce del campo vettoriale sono un'unica mesh istanziata (una draw call per migliaia di frecce).
- ShaderMaterial: le nubi di punti usano shader dedicati con colore e dimensione per punto (doppia codifica) e code sfumate con trasparenza per vertice (traiettorie temporali).
- Geometria parametrica: le superfici (u,v) (armoniche sferiche, Möbius, tori annodati...) sono griglie campionate trasformate in mesh indicizzate con scala uniforme — le proporzioni reali si conservano.
- CanvasTexture: la mappa a bande riempite delle isolinee è una texture generata al volo da canvas 2D e appoggiata sul piano base.
- Gestione del colore: dalle versioni recenti three.js lavora in spazio lineare e converte in sRGB in uscita; tutta la pipeline colore di func3d (colormap, colorbar, bande) ne tiene conto per avere colori coerenti tra scena e legende.
- Spessore delle linee: in WebGL l'attributo
linewidthdiLineBasicMaterialè ignorato — ogni linea esce da un pixel, qualunque valore si scriva. E' una trappola silenziosa: il comando esiste, il valore arriva al materiale, e non succede niente. L'unico modo di avere uno spessore vero è passare aLine2, che disegna la linea come geometria; per questo assi, griglie, wireframe e curve la usano quando lo spessore richiesto è maggiore di uno. - Taglio della vista: sei
THREE.Planeformano una scatola e vengono assegnati ai materiali (clippingPlanes, conlocalClippingEnabledsul renderer). Agendo sui materiali il taglio si aggiorna senza ricostruire la scena, e si può escludere ciò che deve restare intero — assi e griglie — semplicemente non assegnandolo ai loro materiali. - Curve fat line: le curve parametriche usano gli stessi add-on Line2 con un oggetto per ogni tratto continuo (i punti non finiti spezzano la linea) e colore per vertice lungo il parametro. Attenzione a due dettagli che si pagano subito: la risoluzione del materiale va riaggiornata a ogni ridimensionamento — per tutti i tratti, o la linea cambia spessore a pezzi — e la geometria istanziata va liberata percorrendo il gruppo, perché un gruppo non ha né geometria né materiale propri e le geometrie dei figli resterebbero nella GPU a ogni ricostruzione.
- Piani immagine: un
PlaneGeometryconMeshBasicMateriala doppia faccia sulla texture del registro. Se il piano è semitrasparente si disattiva la scrittura nel depth buffer: altrimenti nasconde ciò che gli sta dietro pur lasciandolo intravedere, che è il difetto classico dei piani trasparenti. - Bussola degli assi: una piccola scena secondaria in un angolo, con camera e renderer propri. Il contesto WebGL è una risorsa limitata (una quindicina per pagina), quindi va distrutta esplicitamente quando il grafico viene ricostruito.
- Librerie locali:
classi.js(classificazione: Jenks esatto, quantili, deviazione standard, numeri tondi, logaritmica, passo fisso) ecampionamento.js(scelta dei punti base: uno ogni k, FPS, k‑means++ con generatore riproducibile) sono moduli UMD indipendenti dal renderer, con collaudo headless in Node: si possono provare senza aprire un browser e riusare in altre pagine. - Export vettoriale: la scena si esporta anche in SVG — etichette degli
assi, valori dei tick, titolo, riquadro della legenda e colorbar (queste come
linearGradient, cioè colori interpolati da chi visualizza e non pixel), con l'immagine WebGL come sfondo raster. Posizioni, corpi, famiglie e colori si leggono dallo stile calcolato degli elementi veri, e la linea di base del testo si chiede al browser invece di stimarla: il file combacia con quello che si vede a schermo. Con la casella Scena in vettoriale entra in giocoSVGRendererdi three.js e anche la superficie esce in poligoni (un tracciato per triangolo, ombreggiatura piatta per faccia): una decina di megabyte, utili quando il disegno va ritoccato in un editor. Il profilo di sezione, che è un disegno 2D, esce invece completamente vettoriale già di suo.
Perché conviene
- GPU nel browser: griglie fitte, migliaia di punti e frecce restano interattivi senza installare nulla — funziona anche su tablet;
- riproducibilità e condivisione: una visualizzazione è un URL, non un software da installare (lo stato della scena viaggia nel link);
- ecosistema: controlli, loader (glTF, PLY...), esempi e documentazione abbondanti; competenze facilmente reperibili;
- longevità: progetto attivo da oltre quindici anni, con una comunità enorme e retrocompatibilità gestita in modo prevedibile.
Sviluppi possibili nei progetti di ricerca
- WebGPU: three.js offre già un renderer WebGPU; per i dataset grandi (milioni di punti, compute shader per l'interpolazione o le particelle) sarà il passo naturale quando il supporto dei browser si consolida.
- Rendering volumetrico: campi scalari 3D (concentrazioni, densità) via ray‑marching su texture 3D — il complemento naturale di superfici e nubi.
- Streamline e particle tracing: integrazione delle traiettorie nei campi vettoriali (oggi visualizzati a frecce), con semina interattiva.
- Grandi dataset: level‑of‑detail, decimazione progressiva e streaming dei frame temporali dal backend (netCDF via gateway) per superare i limiti della memoria del browser.
- WebXR: ispezione immersiva (VR/AR) delle scene già costruite — con three.js è un'estensione, non una riscrittura.
- GIS 3D: per i dati georiferiti su globo restano preferibili strumenti dedicati (CesiumJS, deck.gl); func3d copre lo spazio "cartesiano" dell'analisi di laboratorio e di modello.
Keywords: three.js, WebGL, OrbitControls, rendering 3D, WebGPU, visualizzazione scientifica