Three.js SVGLoader: Aus flacher Grafik ein 3D-Mesh machen
Lade SVG-Pfade in Three.js, erhalte echte Aussparungen, korrigiere die vertikale Ausrichtung und bestimme die Mesh-Größe mit einem reproduzierbaren Browserbeispiel.
Auf dieser Seite
- Mit den Formen beginnen, denen du Tiefe geben möchtest
- Das SVG laden und das Mesh rendern
- Die Ausrichtung vor dem Messen und Zentrieren festlegen
- Die Aussparung bestätigen, bevor du die Oberfläche dekorierst
- Tiefeneffekte erst nach einer funktionierenden einfachen Extrusion ergänzen
- Quellen- und Zielprüfungen getrennt halten
- FAQ
- Quellen
Um aus flacher SVG-Grafik ein Three.js-Mesh zu machen, lade das SVG, konvertiere seine Pfade in Formen und übergib diese dann an ExtrudeGeometry. Prüfe Aussparungen, vertikale Ausrichtung und Abmessungen, bevor du Effekte hinzufügst. Eine erkennbare Silhouette kann trotzdem einen gefüllten Innenraum oder eine auf dem Kopf stehende Ecke haben.
Diese Anleitung verwendet ein eigenes, von Hand geschriebenes Abzeichen mit einer quadratischen Aussparung und einer abgeschnittenen oberen rechten Ecke. Die Asymmetrie macht einen Ausrichtungsfehler sichtbar. Es ist ein Browser-Geometriebeispiel, kein PerfectVector-Konvertierungsergebnis und kein Fertigungstest.
Mit den Formen beginnen, denen du Tiefe geben möchtest
Verwende beim ersten Versuch ein kleines SVG mit geschlossenen, gefüllten Konturen. Speichere dies als badge.svg:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 180">
<path fill="#e64b35" fill-rule="evenodd"
d="M20 20H160L220 80V160H20Z M65 60H115V110H65Z"/>
</svg>Innerhalb eines Pfadelements liegen zwei geschlossene Teilpfade: eine äußere Grenze und ein inneres Quadrat. Die Füllregel evenodd macht diesen inneren Bereich zur Aussparung. Ein separates weißes Rechteck würde in einem flachen Bild nur die Fläche abdecken; es beschreibt nicht denselben leeren Bereich.
Die Grafik belegt 200 mal 140 Koordinateneinheiten innerhalb einer 240 mal 180 großen viewBox. Behalte diesen Unterschied beim Dimensionieren des Mesh im Blick. Leere Ränder gehören zum SVG-Darstellungsbereich, nicht zur extrudierten Silhouette.
Wenn du bereits ein bearbeitbares Vektororiginal hast, verwende es. Wenn ein PNG oder JPG deine einzige Quelle ist, kann PerfectVectors Bild-zu-Vektor-Ablauf dir helfen, SVG-Pfadgrafik vorzubereiten. Prüfe vor dem Laden in Three.js die Vorschau und heruntergeladenen Konturen, besonders die Negativräume. Die Vektorisierung liefert die 2D-Grafik; der Code unten liefert Tiefe, Materialien, Beleuchtung und Platzierung.
Das SVG laden und das Mesh rendern
Das Beispiel wurde mit Three.js 0.186.0 getestet. Halte Kernbibliothek und Addon auf derselben Version. Installiere in einem Browserprojekt mit Paketimporten three@0.186.0, stelle die Dateien über HTTP bereit und erstelle einen Container:
<div id="viewer"></div>
<script type="module" src="./main.js"></script>Dein Build-Werkzeug muss die three-Importe auflösen. Setze bei einer einfachen Browserseite ohne Build-Werkzeug diese Import-Map vor das Modulskript und verwende Dateien aus demselben installierten Paket:
<script type="importmap">
{
"imports": {
"three": "./node_modules/three/build/three.module.js",
"three/addons/": "./node_modules/three/examples/jsm/"
}
}
</script>Lege badge.svg neben die HTML-Seite. Die relative Lade-URL unten wird gegen die URL dieser Seite aufgelöst. Speichere anschließend dies als main.js:
import * as THREE from 'three';
import { SVGLoader } from 'three/addons/loaders/SVGLoader.js';
const data = await new SVGLoader().loadAsync('./badge.svg');
const artwork = new THREE.Group();
for (const path of data.paths) {
if (path.userData.style.fill === 'none') continue;
for (const shape of path.toShapes()) {
const geometry = new THREE.ExtrudeGeometry(shape, {
depth: 20, bevelEnabled: false, steps: 1
});
const material = new THREE.MeshStandardMaterial({
color: path.color, roughness: 0.65, metalness: 0
});
artwork.add(new THREE.Mesh(geometry, material));
}
}
if (!artwork.children.length) throw new Error('No filled shapes found');
// SVG y grows down; this scene uses y up.
artwork.scale.y = -1;
const bounds = new THREE.Box3().setFromObject(artwork);
const size = bounds.getSize(new THREE.Vector3());
const center = bounds.getCenter(new THREE.Vector3());
const scale = 4 / size.x;
artwork.scale.multiplyScalar(scale);
artwork.position.copy(center).multiplyScalar(-scale);
const scene = new THREE.Scene();
scene.background = new THREE.Color('#f1f3f5');
scene.add(artwork);
scene.add(new THREE.HemisphereLight(0xffffff, 0x596477, 2));
const light = new THREE.DirectionalLight(0xffffff, 3);
light.position.set(-3, 5, 7);
scene.add(light);
const camera = new THREE.PerspectiveCamera(35, 800 / 600, 0.1, 100);
camera.position.set(4, 3, 9);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(800, 600);
document.querySelector('#viewer').append(renderer.domElement);
renderer.render(scene, camera);SVGLoader ist ein separat importiertes Addon. loadAsync() liest die Datei; parse(svgText) ist die Alternative, wenn du das SVG-Markup bereits als Zeichenfolge hast.
Verwende in r186 path.toShapes(). Ältere Beispiele rufen häufig SVGLoader.createShapes(path) auf. Diese Hilfsfunktion wurde in r185 als veraltet markiert und delegiert in der getesteten Version an toShapes(). Prüfe deine installierte Version, bevor du Snippets verschiedener Tutorials vermischst.
Die Schleife überspringt fill="none" bewusst. Sie verarbeitet die einfarbigen Füllungen dieses Beispiels; sie ist kein vollständiger SVG-Renderer. Verläufe, Masken, eingebettete Bilder, Konturen, Deckkraft und überlappende Farbebenen erfordern jeweils eigene Entscheidungen. Du kannst nicht davon ausgehen, dass das flache Erscheinungsbild als identische 3D-Geometrie übernommen wird.

Die Ausrichtung vor dem Messen und Zentrieren festlegen
Die vertikalen SVG-Koordinaten wachsen nach unten. Diese Szene blickt auf die Grafik mit positivem y nach oben, weshalb artwork.scale.y = -1 die erwartete Ausrichtung wiederherstellt. Die abgeschnittene Ecke ist die Prüfung: Sie gehört nach oben rechts.
Dieser Vorzeichenwechsel gehört zu dieser Koordinateneinrichtung. Füge keine zweite Spiegelung hinzu, nur weil das Mesh nach einer Drehung der Kamera oder eines übergeordneten Objekts noch falsch aussieht. Vergleiche zuerst ein bekanntes asymmetrisches Merkmal aus der Quelle mit der gerenderten Szene.
Die nächsten Zeilen messen die gespiegelte Gruppe, berechnen eine gleichmäßige Skalierung und verschieben ihre skalierte Mitte zum Ursprung. Box3.setFromObject() misst Begrenzungen einschließlich untergeordneter Objekte und deren Transformationen. Hier hat die Gruppe beim Messen kein transformiertes übergeordnetes Objekt und keine Grafikdrehung.
Die ursprüngliche Extrusion misst 200 mal 140 mal 20. Die Breite auf 4 zu setzen ergibt einen Skalierungsfaktor von 4 / 200, also 0.02. Weil diese Skalierung auf alle drei Achsen wirkt, betragen die resultierenden Abmessungen 4 mal 2.8 mal 0.4. Eine Tiefe von 20 im Konstruktor bleibt nach der Gruppenskalierung nicht 20.
Das sind Szeneneinheiten. Das Beispiel behauptet nicht, dass eine Einheit einem Millimeter entspricht. Wenn deine Anwendung eine bestimmte physische Interpretation benötigt, definiere sie ausdrücklich und validiere sie über den Zielablauf.
Die Aussparung bestätigen, bevor du die Oberfläche dekorierst
Der Test erzeugte einen geladenen Pfad, eine Form und eine Aussparung. Wir haben außerdem einen Strahl durch die quadratische Aussparung und einen anderen durch den festen Bereich geschickt: Die Aussparung lieferte keinen Mesh-Treffer, der feste Bereich dagegen einen Treffer. Strahlen durch die abgeschnittene obere rechte und die feste untere rechte Ecke bestätigten die vertikale Ausrichtung unabhängig von der schrägen Ansicht.
Du kannst in deiner eigenen Szene mit einer einfacheren Sichtprüfung beginnen: Betrachte die Vorderseite gerade und dann schräg vor einem kontrastierenden Hintergrund. Die Aussparung sollte den Hintergrund zeigen, und ihre Seitenwände sollten sichtbar werden, wenn sich die Kamera bewegt. Eine weiße Fläche, die den Bereich abdeckt, ist ein anderes Ergebnis.
Wenn ein Innenraum gefüllt wird, isoliere diese eine Form. Prüfe, ob die Quelle Teilpfade, separate gefüllte Objekte, einen Beschneidungspfad oder eine Maske verwendet. Versuche nicht, das Problem mit einer Materialfarbe zu verbergen. Der Leitfaden zu unerwünscht gefüllten SVG-Aussparungen erklärt die Unterschiede in der Quelldatei; die Extrusionsdiagnose behandelt Konturreparaturen bei fehlerhafter Ausgangsgrafik.
Tiefeneffekte erst nach einer funktionierenden einfachen Extrusion ergänzen
Das Beispiel deaktiviert Abschrägungen, damit sich die anfänglichen Abmessungen leicht prüfen lassen. Die ExtrudeGeometry-Optionen steuern Tiefe, Abschrägungsgröße, Abschrägungsdicke und Kurvenabtastung separat. Prüfe kleine Aussparungen und Begrenzungen erneut, wenn du Abschrägungen aktivierst. Eine dekorative Kante verändert die gerade gemessene Geometrie.
Prüfe bei gekrümmter Grafik die Mesh-Silhouette in der Größe und Kameradistanz, die deine Anwendung verwenden wird. Erhöhe die Kurvenabtastung nur, wenn die sichtbare Facettierung es erfordert; unnötige Knoten der Eingabe zu reduzieren ist eine separate Bearbeitungsaufgabe. Keine dieser Einstellungen stellt Details wieder her, die in der Quelle fehlten.
Eine reine Konturzeichnung benötigt ebenfalls eine andere Entscheidung. Der Loader bietet pointsToStroke() für Konturgeometrie, aber die obige Schleife für gefüllte Formen lässt diese Pfade bewusst aus. Soll die sichtbare Linie zu einem extrudierten Band werden, entscheide zuerst, welche geschlossene Kontur dieses Band definiert. Soll sie eine Linie in der Szene bleiben, baue stattdessen eine Linien- oder Konturdarstellung auf.
Führe in einer React-Anwendung das ausschließlich für den Browser bestimmte Laden und Rendern auf dem Client aus und gib die zugehörige Geometrie, Materialien und den Renderer frei, wenn die Ansicht entfernt wird. Das kompakte Beispiel rendert einmal in fester Größe; ein produktiv eingesetzter Viewer benötigt außerdem Größenanpassung und einen eigenen Ressourcenlebenszyklus.
Quellen- und Zielprüfungen getrennt halten
Ein Browser-Mesh ist hilfreich für ein interaktives Abzeichen, eine Logovorschau oder Szenendekoration. Es belegt nicht, dass das Ergebnis ein wasserdichtes, maßlich geeignetes Bauteil ist. Wenn Fertigung das Ziel ist, verwende den separaten Bild-zu-SVG-Ablauf für 3D-Druck und prüfe dort das importierte Modell.
Halte für den Bildschirmablauf drei Dateien oder Stufen auseinander: die bearbeitbare SVG-Quelle, das abgeleitete Mesh und die Szenenpräsentation. Dadurch lässt sich leichter erkennen, ob ein schlechtes Ergebnis von Pfadgeometrie, Mesh-Aufbau oder Kamera und Beleuchtung stammt. Weitere Leitfäden zu SVG-Workflows behandeln die Quellseite, wenn die Grafik vor dem Laden repariert werden muss.
FAQ
Warum steht mein SVG in Three.js auf dem Kopf? Vertikale SVG-Koordinaten wachsen nach unten. In einer Szene mit positivem y nach oben und Blick auf die Vorderseite der Grafik kann das Spiegeln der y-Skalierung der Grafikgruppe die Quellausrichtung wiederherstellen. Prüfe ein asymmetrisches Merkmal, bevor du eine weitere Spiegelung oder Drehung hinzufügst.
Sollte ich createShapes oder toShapes verwenden? Dieses Beispiel verwendet path.toShapes() mit Three.js 0.186.0. SVGLoader.createShapes() wurde in r185 als veraltet markiert. Verwende die für deine installierte Projektversion dokumentierte API und halte Kernpaket und Addon auf derselben Version.
Verwandelt SVGLoader ein PNG innerhalb eines SVG in ein Mesh? Ein eingebettetes Rasterbild liefert nicht die gefüllten Konturen dieses Beispiels. Beschaffe zuerst geeignete Pfadgrafik oder verwende das Bild als Textur, wenn der Erhalt seines Erscheinungsbilds das eigentliche Ziel ist.
Erhält Extrusion die SVG-Konturbreite? Dieses Beispiel extrudiert gefüllte Formen und überspringt Pfade mit fill gleich none. Konturgeometrie benötigt einen separaten Ablauf; eine dick gezeichnete Linie ist nicht automatisch die geschlossene Kontur eines extrudierten Bands.
Quellen
- Three.js — SVGLoader — Dokumentiert Addon-Import, Parsing- und Lademethoden, Konturhilfsfunktion und die Kennzeichnung von createShapes als veraltet.
- Three.js — ShapePath — Dokumentiert das Konvertieren von Pfadsammlungen in Formen mit toShapes.
- Three.js — ExtrudeGeometry — Definiert Formextrusion, Tiefe, Abschrägung und Kurvenabtastungsoptionen.
- Three.js — Box3 — Dokumentiert das Messen transformierter Objektbegrenzungen und das Ermitteln ihrer Größe und Mitte.
Du arbeitest mit einem Emblem, das nur als Rasterbild vorliegt? Erstelle einen SVG-Kandidaten, prüfe seine gefüllten Konturen und Aussparungen und teste diese Datei dann in der kleinen Szene, bevor du den vollständigen Betrachter aufbaust.
Mehr aus dem Blog

SVG in Unreal Engine: Motion-Design-Geometrie prüfen
Bereite ein SVG für Unreal Engine Motion Design vor, prüfe Löcher und separate Teile und unterscheide Szenengeometrie von Texturen und UI-Bildern zur Laufzeit.

SVG in Rhino: Kurven, Schraffuren oder Flächen wählen
Wähle die passende SVG-Importoption in Rhino 8, prüfe Objekttypen und Öffnungen und entscheide vor dem Modellieren, ob ein Rasterlogo nachgezeichnet werden muss.