SVGLoader Three.js: Ubah Artwork Datar Menjadi Mesh 3D
Muat path SVG ke Three.js, pertahankan bukaan sungguhan, perbaiki orientasi vertikal, dan atur ukuran mesh ekstrusi dengan contoh browser kecil yang dapat direproduksi.
Di halaman ini
Untuk mengubah artwork SVG datar menjadi mesh Three.js, muat SVG, konversikan path-nya menjadi shape, lalu berikan shape tersebut ke ExtrudeGeometry. Periksa lubang, orientasi vertikal, dan dimensi sebelum menambahkan efek. Siluet yang dapat dikenali masih dapat memiliki ruang kosong yang terisi atau sudut yang terbalik.
Panduan ini menggunakan lencana orisinal buatan tangan dengan satu bukaan persegi dan sudut kanan atas yang dipotong. Asimetrinya membuat kesalahan orientasi terlihat. Ini adalah contoh geometri browser, bukan hasil konversi PerfectVector atau pengujian manufaktur.
Mulailah dengan bentuk yang ingin Anda beri kedalaman
Gunakan SVG kecil dengan kontur tertutup dan berisian untuk percobaan pertama. Simpan ini sebagai 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>Ada dua subpath tertutup di dalam satu elemen path: batas luar dan persegi dalam. Aturan isian evenodd membuat wilayah dalam itu menjadi bukaan. Persegi panjang putih terpisah hanya akan menutupi permukaan dalam gambar datar; bentuk itu tidak mendeskripsikan wilayah kosong yang sama.
Artwork menempati 200 kali 140 unit koordinat di dalam viewBox 240 kali 180. Ingat perbedaan itu ketika mengatur ukuran mesh. Margin kosong adalah bagian viewport SVG, bukan bagian siluet yang diekstrusi.
Jika Anda sudah memiliki vektor asli yang dapat diedit, gunakan. Jika PNG atau JPG adalah satu-satunya sumber Anda, alur kerja gambar-ke-vektor PerfectVector dapat membantu menyiapkan artwork path SVG. Periksa pratinjau dan kontur yang diunduh, terutama ruang negatif, sebelum memuat file ke Three.js. Vektorisasi menyediakan artwork 2D; kode di bawah menyediakan kedalaman, material, pencahayaan, dan penempatan.
Muat SVG dan render mesh
Contoh diuji dengan Three.js 0.186.0. Pertahankan pustaka inti dan addon pada versi yang sama. Dalam proyek browser dengan impor paket, instal three@0.186.0, sajikan file melalui HTTP, dan buat kontainer:
<div id="viewer"></div>
<script type="module" src="./main.js"></script>Build tool Anda harus dapat menyelesaikan impor three. Untuk halaman browser biasa tanpa build tool, letakkan import map ini sebelum skrip module, menggunakan file dari paket terinstal yang sama:
<script type="importmap">
{
"imports": {
"three": "./node_modules/three/build/three.module.js",
"three/addons/": "./node_modules/three/examples/jsm/"
}
}
</script>Letakkan badge.svg di samping halaman HTML. URL pemuatan relatif di bawah diselesaikan terhadap URL halaman itu. Kemudian simpan ini sebagai 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 adalah addon yang diimpor secara terpisah. loadAsync() membaca file; parse(svgText) merupakan alternatif ketika Anda sudah memiliki markup SVG sebagai string.
Dalam r186, gunakan path.toShapes(). Contoh lama sering memanggil SVGLoader.createShapes(path). Helper itu ditandai deprecated dalam r185 dan mendelegasikan ke toShapes() pada versi yang diuji. Periksa rilis terinstal Anda sebelum mencampurkan cuplikan dari tutorial berbeda.
Loop sengaja melewati fill="none". Loop menangani isian solid dalam contoh ini; loop bukan renderer SVG lengkap. Gradien, mask, gambar tertanam, stroke, opacity, dan lapisan warna yang tumpang tindih membutuhkan keputusan masing-masing, bukan asumsi bahwa tampilan datar akan menjadi geometri 3D yang identik.

Tetapkan orientasi sebelum mengukur dan memusatkan
Koordinat vertikal SVG meningkat ke bawah. Scene ini memandang ke arah artwork dengan y positif mengarah ke atas, sehingga artwork.scale.y = -1 memulihkan orientasi yang diharapkan. Sudut terpotong adalah pemeriksaannya: sudut itu seharusnya berada di kanan atas.
Perubahan tanda itu berlaku untuk pengaturan koordinat ini. Jangan menambahkan pembalikan kedua karena mesh masih terlihat salah setelah memutar kamera atau objek induk. Bandingkan fitur asimetris yang diketahui dari sumber dengan scene yang dirender terlebih dahulu.
Baris berikutnya mengukur grup yang dibalik, menghitung skala seragam, dan menggeser pusat yang diskalakan ke titik asal. Box3.setFromObject() mengukur batas termasuk objek anak dan transformasinya. Di sini, grup tidak memiliki induk yang ditransformasikan dan tidak ada rotasi artwork saat diukur.
Ekstrusi asli berukuran 200 kali 140 kali 20. Mengatur lebar menjadi 4 memberikan skala 4 / 200, atau 0.02. Karena skala itu berlaku pada ketiga sumbu, batas yang dihasilkan adalah 4 kali 2.8 kali 0.4. Kedalaman 20 dalam konstruktor tidak tetap 20 setelah penskalaan grup.
Ini adalah unit scene. Contoh ini tidak mengklaim bahwa satu unit adalah satu milimeter. Jika aplikasi Anda membutuhkan interpretasi fisik tertentu, definisikan secara eksplisit dan validasi melalui alur kerja tujuan.
Konfirmasi lubang sebelum menghias permukaan
Pengujian menghasilkan satu path dimuat, satu shape, dan satu lubang. Kami juga menembakkan ray melalui bukaan persegi dan ray lain melalui area solid: bukaan tidak mengembalikan hit mesh, sementara area solid mengembalikan hit. Ray melalui sudut kanan atas terpotong dan sudut kanan bawah solid mengonfirmasi orientasi vertikal secara independen dari tampilan bersudut.
Anda dapat memulai dengan pemeriksaan visual lebih sederhana dalam scene sendiri: lihat permukaan dari depan, lalu pada sudut tertentu dengan latar belakang kontras. Bukaan seharusnya menampilkan latar belakang, dan dinding sampingnya seharusnya terlihat ketika kamera bergerak. Permukaan putih yang menutupi area adalah hasil yang berbeda.
Jika ruang kosong terisi, isolasi bentuk tersebut. Periksa apakah sumber menggunakan subpath, objek berisian terpisah, clipping path, atau mask. Jangan mencoba menyembunyikan masalah dengan warna material. Panduan lubang SVG yang terisi menjelaskan perbedaan file sumber; diagnosis ekstrusi membahas perbaikan kontur ketika artwork yang mendasarinya rusak.
Tambahkan efek kedalaman hanya setelah ekstrusi sederhana bekerja
Contoh menonaktifkan bevel agar dimensi awal mudah diperiksa. Opsi ExtrudeGeometry mengendalikan kedalaman, ukuran bevel, ketebalan bevel, dan pengambilan sampel kurva secara terpisah. Periksa kembali bukaan kecil dan batas ketika Anda mengaktifkan bevel. Tepi dekoratif mengubah geometri yang baru Anda ukur.
Untuk artwork melengkung, periksa siluet mesh pada ukuran dan jarak kamera yang akan digunakan aplikasi Anda. Tingkatkan pengambilan sampel kurva hanya ketika kurva yang tampak bersegi perlu diperhalus; mengurangi node input yang tidak perlu adalah tugas pengeditan terpisah. Kedua pengaturan tidak memulihkan detail yang tidak ada dalam sumber.
Gambar yang hanya memiliki stroke juga membutuhkan keputusan berbeda. Loader menyediakan pointsToStroke() untuk geometri stroke, tetapi loop shape berisian di atas sengaja mengabaikan path tersebut. Jika garis yang terlihat harus menjadi pita ekstrusi, tentukan dahulu outline tertutup yang mendefinisikan pita itu. Jika garis harus tetap menjadi garis dalam scene, bangun representasi garis atau stroke.
Untuk aplikasi React, jalankan pekerjaan pemuatan dan renderer khusus browser di klien dan lakukan dispose pada geometri, material, serta renderer yang Anda miliki ketika tampilan dihapus. Contoh ringkas ini merender sekali pada ukuran tetap; viewer produksi juga membutuhkan penanganan perubahan ukuran dan siklus hidup sumber dayanya sendiri.
Pisahkan pemeriksaan sumber dan tujuan
Mesh browser berguna untuk lencana interaktif, pratinjau logo, atau dekorasi scene. Mesh itu tidak membuktikan bahwa hasilnya adalah komponen dengan mesh tertutup tanpa celah (watertight) dan dimensi yang sesuai. Jika fabrikasi adalah tujuannya, gunakan alur kerja gambar-ke-SVG untuk pencetakan 3D yang terpisah dan periksa model yang diimpor di sana.
Untuk alur kerja layar, pisahkan tiga file atau tahap: SVG sumber yang dapat diedit, mesh turunan, dan presentasi scene. Itu memudahkan penentuan apakah hasil buruk berasal dari geometri path, konstruksi mesh, atau kamera dan pencahayaan. Panduan alur kerja SVG lainnya membahas sisi sumber ketika artwork perlu diperbaiki sebelum dimuat.
FAQ
Mengapa SVG saya terbalik di Three.js? Koordinat vertikal SVG meningkat ke bawah. Dalam scene yang menggunakan y positif ke atas dan melihat bagian depan artwork, membalik skala y grup artwork dapat memulihkan orientasi sumber. Periksa fitur asimetris sebelum menambahkan pembalikan atau rotasi lain.
Haruskah saya menggunakan createShapes atau toShapes? Contoh ini menggunakan path.toShapes() dengan Three.js 0.186.0. SVGLoader.createShapes() ditandai deprecated dalam r185. Gunakan API yang didokumentasikan untuk versi terinstal dalam proyek Anda, dengan paket inti dan addon pada rilis yang sama.
Apakah SVGLoader mengubah PNG di dalam SVG menjadi mesh? Gambar raster tertanam tidak menyediakan kontur berisian yang digunakan contoh ini. Dapatkan artwork path yang sesuai terlebih dahulu, atau gunakan gambar sebagai tekstur ketika mempertahankan tampilannya adalah tujuan sebenarnya.
Apakah ekstrusi mempertahankan lebar stroke SVG? Contoh ini mengekstrusi shape berisian dan melewati path dengan fill yang diatur ke none. Geometri stroke membutuhkan alur kerja terpisah; garis tebal yang diwarnai tidak otomatis menjadi outline tertutup pita ekstrusi.
Sources
- Three.js — SVGLoader — Mendokumentasikan impor addon, metode penguraian dan pemuatan, helper stroke, dan deprekasi createShapes.
- Three.js — ShapePath — Mendokumentasikan konversi kumpulan path menjadi shape dengan toShapes.
- Three.js — ExtrudeGeometry — Mendefinisikan ekstrusi shape, kedalaman, bevel, dan opsi pengambilan sampel kurva.
- Three.js — Box3 — Mendokumentasikan pengukuran batas objek yang ditransformasikan dan pengambilan ukuran serta pusatnya.
Bekerja dari lambang yang hanya tersedia sebagai raster? Siapkan kandidat SVG, periksa kontur berisian dan bukaannya, lalu uji file itu dalam scene kecil ini sebelum membangun viewer lengkap.
Lebih banyak dari blog

Impor SVG Unreal Engine: Periksa Geometri Motion Design
Siapkan SVG untuk Motion Design Unreal Engine, periksa lubang dan bagian terpisah, dan bedakan geometri scene dari tekstur atau alur kerja gambar UI runtime.

Impor SVG Rhino: Pilih Kurva, Hatch, atau Permukaan
Pilih opsi impor SVG Rhino 8 yang tepat, periksa jenis objek dan lubang, dan tentukan kapan logo raster membutuhkan penelusuran sebelum mulai memodelkan desain.