Pixi.js: Dukungan SVG nyata

Dibuat pada 29 Jun 2017  ·  30Komentar  ·  Sumber: pixijs/pixi.js

Akan sangat bagus jika Pixi dapat membuat representasi hierarki Grafik dari SVG (tidak hanya memuat tekstur seperti saat ini).

@psyrendust ^ Hei, bisakah kamu PR yang kamu buat menjadi Pixi? :D

Stale 🙏 Feature Request

Komentar yang paling membantu

Saya pikir ini melakukan apa yang Anda inginkan menggunakan webpack.
https://github.com/blunt1337/pixi-svg-loader

Semua 30 komentar

Anda mungkin ingin memeriksa perpustakaan ini yang saya buat:
https://github.com/bigtimebuddy/pixi-svg
https://bigtimebuddy.github.io/pixi-svg/example/

Karena keterbatasan menggambar di Pixi, tidak semua fitur svg didukung.

@trusktr bisakah Anda memberikan kasus penggunaan? Maksud Anda seperti memiliki grup sebagai Wadah dan set primitif sebagai Sprite?

Karena ini adalah sesuatu yang saya pikirkan. Dimungkinkan untuk membuat atlas tekstur dan menggunakan terjemahan dan rotasi dari SVG untuk membuat hierarki Sprite.

Satu masalah yang saya lihat dengan pendekatan ini adalah jangkar (jika kita ingin menghidupkan sesuatu). Misalnya Inkscape menambahkan jangkar sebagai atribut khusus tetapi tidak dalam afaik standar. Contoh yang saya maksud:

2017-07-01 08_56_56-_new document 1 - inkscape

Jangkar dari grup tiga jalur tersebut (kiri atas kotak biru) didefinisikan sebagai inkscape:transform-center-x dan inkscape:transform-center-y .

    <g
       id="g4512"
       inkscape:transform-center-x="-65.892627"
       inkscape:transform-center-y="43.567609"
       transform="rotate(-5.9407468,27.740957,88.735118)">
      <path
         inkscape:connector-curvature="0"
         id="rect4485"
         d="m 24.502618,78.898505 h 50.619309 c 3.986749,0 7.196297,3.209548 7.196297,7.196296 v 70.274069 c 0,3.98675 -3.209548,7.1963 -7.196297,7.1963 H 24.502618 c -3.986748,0 -7.196296,-3.20955 -7.196296,-7.1963 V 86.094801 c 0,-3.986748 3.209548,-7.196296 7.196296,-7.196296 z"
         style="opacity:1;fill:#005e92;fill-opacity:1;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" />
      <path
         inkscape:connector-curvature="0"
         id="rect4485-4"
         d="m 66.160572,123.8869 h 50.619318 c 3.98675,0 7.1963,3.20955 7.1963,7.1963 v 70.27406 c 0,3.98675 -3.20955,7.19631 -7.1963,7.19631 H 66.160572 c -3.986734,0 -7.196284,-3.20956 -7.196284,-7.19631 V 131.0832 c 0,-3.98675 3.20955,-7.1963 7.196284,-7.1963 z"
         style="opacity:1;fill:#920000;fill-opacity:1;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" />
      <path
         inkscape:connector-curvature="0"
         id="rect4485-3"
         d="m 106.60403,73.994048 h 50.61931 c 3.98675,0 7.1963,3.209548 7.1963,7.196296 v 70.274066 c 0,3.98675 -3.20955,7.19631 -7.1963,7.19631 h -50.61931 c -3.98675,0 -7.196288,-3.20956 -7.196288,-7.19631 V 81.190344 c 0,-3.986748 3.209538,-7.196296 7.196288,-7.196296 z"
         style="opacity:1;fill:#009228;fill-opacity:1;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" />
    </g>

Meskipun saya menghargai usaha Anda @bigtimebuddy, saya tidak berpikir itu ide yang baik untuk membuat primitif SVG di pixi.

Lihat ini juga:
https://css-tricks.com/rendering-svg-paths-in-webgl/

Saya pikir ini melakukan apa yang Anda inginkan menggunakan webpack.
https://github.com/blunt1337/pixi-svg-loader

@OSUblake keren, sepertinya memang melakukan apa yang saya maksud. Harus mencobanya. 👍

@bigtimebuddy Terima kasih! Saya membuka masalah baru di sana. Akan sangat bagus untuk memiliki grafik adegan Pixi penuh.

@RanzQ

@trusktr bisakah Anda memberikan kasus penggunaan? Maksud Anda seperti memiliki grup sebagai Wadah dan set primitif sebagai Sprite?

Ya, tetapi primitif akan menjadi objek Graphics daripada sprite.

Satu masalah yang saya lihat dengan pendekatan ini adalah jangkar (jika kita ingin menghidupkan sesuatu). Misalnya Inkscape menambahkan jangkar sebagai atribut khusus tetapi tidak dalam afaik standar. Contoh yang saya maksud:

Saya tidak keberatan tidak mendukung hal-hal non-standar, saya bisa hidup hanya dengan API standar. Mungkin ada plugin untuk mendukung hal-hal khusus inkscape.

Meskipun saya menghargai usaha Anda @bigtimebuddy, saya tidak berpikir itu ide yang baik untuk membuat primitif SVG di pixi.

Mengapa tepatnya Anda berpikir demikian?

@OSUblake

Saya pikir ini melakukan apa yang Anda inginkan menggunakan webpack.
https://github.com/blunt1337/pixi-svg-loader

Itu cukup keren, kecuali terbatas pada Webpack, dan juga terbatas pada lingkungan alat, tidak berjalan di klien. Saya mencari API yang dapat saya gunakan dengan Pixi.js saat runtime (bukan waktu pembuatan).


Apa yang saya inginkan (saya pikir, tapi saya bukan pengguna Pixi.js yang paling ahli, jadi saran jika ada hal lain yang lebih baik seperti menggunakan sprite) adalah memiliki grafik adegan DisplayObject yang strukturnya sama dengan DOM SVG yang digunakan untuk menghasilkan pohon Pixi dari. Bagi saya, ini sangat kuat untuk manipulasi dan animasi, tanpa harus merender ulang seluruh SVG setiap frame hanya untuk menganimasikan satu primitif (mungkin ratusan atau ribuan).

Apa yang saya pikir saya akan lakukan, jika sesuatu yang open source belum ada, adalah untuk mengambil @bigtimebuddy 's pixi-svg atau @saschagehlich' s pixi-svg-grafis , dan memodifikasi mereka (atau menggunakan konsep serupa) untuk membuat Pohon Pixi Graphics mencerminkan pohon SVG daripada hanya menggambar ke satu objek Graphics .

@trusktr Saya mengerti, untuk animasi berbasis primitif mungkin berguna untuk membuat objek Graphics alih-alih Sprites . Tetapi saya pikir solusinya dapat mendukung keduanya, Graphics untuk SVG sederhana dan Sprites untuk SVG yang lebih kompleks.

Alasan saya pikir itu bukan ide yang baik adalah kenyataan bahwa ada banyak upaya untuk membuat perender SVG khusus dan menurut pengalaman saya, mereka selalu berakhir dengan TODO dari hal-hal yang tidak didukung ini.

Itu akan menjadi masalah bagi seorang seniman karena kita perlu tahu fitur apa yang bisa digunakan dan apa yang tidak. Kami sudah memiliki perender SVG yang bagus, browser. Tetapi jika SVG hanya berisi primitif sederhana tanpa efek, maka mungkin tidak masalah menguraikannya sebagai objek Graphics .

Contoh di mana sprite akan bekerja lebih baik , peta terlihat sangat renyah (mungkin hanya hilang antialiasing) dan berkinerja buruk karena jalurnya rumit.

Membuat tekstur dari SVG cukup mudah menggunakan kanvas 2d dan api Path2D .

var path = new Path2D("M10 10 h 80 v 80 h -80 Z");
context.fill(path);

Demo perubahan jalur
https://codepen.io/osublake/pen/oWzVvb

Saya akan mengerjakan polyfill yang lebih baik karena yang dari Google mengalami masalah dalam mengurai jalur SVG yang kompleks.
https://github.com/google/canvas-5-polyfill

@RanzQ

Kami sudah memiliki perender SVG yang bagus, browser.

Tapi itu sangat slooooooow. Apakah itu dirender di GPU atau CPU? Bagi saya kinerja yang saya alami tidak sebanding dengan kecepatan hal serupa yang digambar dengan Pixi.js, misalnya. Sepertinya saya bahwa mesin SVG asli melakukan terlalu banyak pekerjaan.

Bahkan kanvas 2d lambat dibandingkan dengan WebGL. Bandingkan di sini perbedaan antara WebGL dan Canvas: http://pixijs.github.io/pixi-particles-editor/ (gulir ke bawah untuk beralih antara rendering WebGL dan Canvas). Kanvas terutama lebih lambat.

Saya hanya ingin menggambar SVG dan membuatnya secepat mungkin. Sejauh ini, setidaknya secara konseptual, sepertinya menggambar SVG dengan API WebGL seperti Pixi.js atau Two.js adalah cara tercepat untuk melakukannya. Satu-satunya kelemahan saat ini adalah tidak semua fitur SVG didukung sepenuhnya.

@OSUblake

Membuat tekstur dari SVG cukup mudah menggunakan kanvas 2d dan api Path2D.

Canvas 2D masih terasa lebih lambat dari WebGL, lihat demo yang baru saja saya tautkan dua paragraf ke atas.

Demo perubahan jalur
https://codepen.io/osublake/pen/oWzVvb

Demonya keren! Dalam hal ini, Anda menganimasikan jalur sederhana di PathProxy. Ini cukup cepat untuk kasus penggunaan mungkin. Tapi bayangkan menggambar banyak hal dalam SVG, seperti 100 node, dan menganimasikan semuanya, lalu menginginkan semuanya itu sebagai tekstur untuk membungkus sebuah bola.

Atau, bayangkan partikel dalam demo itu dilakukan dengan SVG dan menganimasikan simpul DOM SVG, kemudian mengambil rendering sebagai tekstur dengan drawImage di kanvas dan akhirnya meletakkannya di quad dari aplikasi webgl 3D. Itu akan terlalu lambat!

Demo Anda cepat karena animasi partikel itu ada di WebGL melalui Pixi.

Jika rendering SVG dengan Pixi adalah fitur yang didukung, dan hierarki yang mencerminkan hierarki SVG telah dibuat, maka perubahan dapat dipetakan ke elemen display:none <svg> ( display:none sehingga diharapkan dapat mencegah mesin SVG browser melakukan pekerjaan karena tidak ada yang perlu dirender) menjadi perubahan pada pohon Pixi.js.

Saya pikir ini akan menjadi cara tercepat untuk menggambar SVG karena Pixi lebih cepat, sambil memberikan kenyamanan DOM yang dapat dimanipulasi oleh React, Angular, dll. Saya ingin memiliki pohon DOM SVG yang dapat saya manipulasi, siapa yang akan merender lebih cepat daripada mesin SVG lambat Browser. Mungkin aku terlalu banyak bertanya. Sepertinya dengan teknologi saat ini, rendering SVG terlalu lambat menurut standar umum (kami menginginkan kecepatan mesin game).

@trusktr

Tapi itu sangat slooooooow.

Maksud saya, kita dapat menggambar tekstur SVG menggunakan browser, lambat tetapi mendukung semua fitur. Anda tidak akan melakukan animasi seperti itu tentu saja. Anda dapat membuat atlas tekstur dan menganimasikan sprite setelahnya. Jika Anda ingin membuat karakter tulang belakang 2D misalnya, itulah caranya.

Saya pikir ini adalah contoh dari apa yang Anda cari: https://github.com/bodymovin/bodymovin/issues/184

Tugasnya tidak sederhana dan animasi itu misalnya cukup rumit untuk diputar perlahan di ponsel Android lama saya yang memainkan adegan Pixi berbasis sprite dengan baik. Saya tidak melihat perbedaan dalam versi SVG dan Pixi. Mungkin hanya masalah pengoptimalan.

Lihat ini juga: https://www.gatherdigital.co.uk/community/post/high-performance-webgl/78

Jadi menurut saya, ada dua jenis kebutuhan SVG yang berbeda. Satu dengan lebih sedikit fitur SVG, dipecah menjadi primitif, yang lain dengan atlas yang dirender oleh browser, sprite menjadi node <g> misalnya.

Pendekatan lain mungkin untuk menemukan format atau alat yang dapat dioperasikan lebih baik untuk grafik vektor daripada SVG. Jika Anda menginginkan sesuatu yang skalabel, SVG memiliki keterbatasan di PixiJS karena alasan @RanzQ sudah diartikulasikan. Ada begitu banyak fitur yang tidak didukung dalam kemampuan menggambar Pixi yang tersedia di SVG sehingga terjemahan gambar primitif apa pun akan menjadi yang terbaik.

Pendekatan lain yang saya sarankan adalah PixiAnimate (https://github.com/jiborobot/pixi-animate-extension) ini adalah ekstensi asli (penafian, saya menulis ini) untuk Adobe Animate yang melakukan pekerjaan dengan baik mengekspor Grafik yang akurat. Plus Anda dapat membuat hierarki apa pun yang Anda inginkan menggunakan simbol dan lapisan bersarang atau bernyawa.

@bigtimebuddy Apakah ada alur kerja untuk membuat atlas tekstur dari grafik vektor menggunakan Animate? Saya telah mencari alur kerja seperti itu di mana adegan Pixi dapat dibuat dengan bantuan UI.

Tampaknya mungkin untuk membuat atlas dalam rilis baru Animate tetapi apakah Anda sudah mencoba ekstensi Anda untuk ini: http://blogs.adobe.com/contentcorner/2017/07/03/create-a-texture-atlas-with -animate-cc-untuk-mesin-game-favorit Anda/

@RanzQ , ya PixiAnimate dapat mengekspor gambar atau spritesheet terpisah dalam format atlas TexturePackers. Bentuk vektor, bagaimanapun, tidak secara otomatis dikonversi ke tekstur. Anda perlu menggunakan "Konversi ke Bitmap" untuk melakukannya di Animate.

@trusktr

Demo Anda cepat karena animasi partikel itu ada di WebGL melalui Pixi.

Tepat. Saya tidak menyarankan untuk menggunakan kanvas sebagai penyaji utama. Hanya untuk menghasilkan tekstur/sprite ketika geometri berubah. Itu harus cukup cepat untuk sebagian besar kasus penggunaan. Saya pikir begitulah cara Two.js melakukan rendering jalur di WebGL.

Dan menggunakan objek Path2D dapat meningkatkan kinerja kanvas karena browser akan men-cache vektor untuk sebuah jalur. Ini memungkinkan Anda untuk menggunakan objek jalur yang sama lebih dari sekali, bahkan dengan konteks dan resolusi kanvas yang berbeda.

@OSUblake

Tepat. Saya tidak menyarankan untuk menggunakan kanvas sebagai penyaji utama. Hanya untuk menghasilkan tekstur/sprite ketika geometri berubah. Itu harus cukup cepat untuk sebagian besar kasus penggunaan. Saya pikir begitulah cara Two.js melakukan rendering jalur di WebGL.

Ya, ini terdengar seperti pendekatan yang bagus. Misalnya, jika satu-satunya atribut yang dimodifikasi pada elemen <circle> adalah cx dan cy , ini berarti bahwa pengoptimalan akan menerjemahkan mesh atau sprite yang ada tanpa membuat yang baru.

Berikut perbandingan antara Pixi, Two, dan SVG asli:

Mengapa Pixi terasa lebih lambat? Apakah karena menghitung ulang (menguji ulang atau meraster ulang) berdasarkan perintah undian setiap frame?

Dengan Two.js, Lingkaran adalah objek dengan properti x, y, dan radius. Jelas dengan API itu bahwa lingkaran tidak perlu diuji ulang/diubah ulang jika hanya memodifikasi x dan y.

Tidak begitu jelas bagaimana pengoptimalan ini akan dibuat dengan gaya perintah-gambar dari Pixi.

@trusktr

Mengapa Pixi terasa lebih lambat? Apakah karena menghitung ulang (menguji ulang atau meraster ulang) berdasarkan perintah undian setiap frame?

Tidak. Itu hanya menciptakan banyak segitiga, yang mematikan kinerja GPU. Anda dapat melihat perbedaannya jika Anda menggambar persegi panjang tanpa gaya garis. Ini akan menjadikannya sebagai sprite, sehingga kinerjanya akan jauh lebih baik. 10.000 persegi.
https://codepen.io/osublake/pen/PjrbWq/

Sudahkah Anda melihat penggunaan bidang jarak untuk rasterisasi? Saya tahu ini bekerja dengan baik dengan font jika Anda tidak memperbesar terlalu banyak. Saya ingin tahu apakah itu bisa digunakan untuk menganimasikan data jalur.
https://github.com/Tw1ddle/WebGL-Distance-Fields/tree/master/sdf

https://www.shadertoy.com/view/ltXSDB

Contoh saya sebelumnya benar-benar tidak akurat karena saya tidak menyadari bahwa JSBin keluar dari loop for lebih awal, jadi di Macbook Pro saya hanya merender 500 lingkaran (bahkan jika saya menyetel n ke 10000 ). Saya telah memperbarui contoh, jadi semuanya membuat 2000 lingkaran tanpa pemutusan loop JSBin:

Contoh SVG masih paling lambat saat menganimasikan hanya posisi lingkaran (bukan radius).

Berikut adalah Two.js dan SVG yang juga menganimasikan radius:

Saya tidak menyertakan versi Pixi.js karena saya tidak yakin bagaimana memodifikasi versi animasi non-radius. Bagaimana Anda memperbarui versi animasi tanpa radius menggunakan Pixi.js untuk menyertakan animasi radius?

Bagaimana Anda memperbarui versi animasi tanpa radius menggunakan Pixi.js untuk menyertakan animasi radius?

Performa mungkin benar-benar mulai menurun di sini. Anda harus menghapus objek grafis, yang mengatur ulang semuanya.
https://codepen.io/osublake/pen/8217810e590672c5a5327596e33c4b1a?editors=0010

Sekarang lihat demo ini menggunakan kanvas 2d untuk menghasilkan tekstur. 3.000 lingkaran berjalan pada 60fps yang solid di mesin saya.
https://codepen.io/osublake/full/MoMeMg/

Yah, bagaimanapun, saya pikir ada kasus penggunaan yang baik untuk ini, seperti yang ditunjukkan oleh contoh: ini bisa lebih cepat di WebGL dalam beberapa kasus.

@OSUblake Ups, saya menjawab yang terakhir sebelum melihat jawaban baru Anda.

Performa mungkin benar-benar mulai menurun di sini. Anda harus menghapus objek grafis, yang mengatur ulang semuanya.
https://codepen.io/osublake/pen/8217810e590672c5a5327596e33c4b1a?editors=0010

Itu yang saya takutkan, yang tidak ideal. Itu mulai mendekati kelambatan SVG asli.

Sekarang lihat demo ini menggunakan kanvas 2d untuk menghasilkan tekstur. 3.000 lingkaran berjalan pada 60fps yang solid di mesin saya.
https://codepen.io/osublake/full/MoMeMg/

Astaga, wah! Oke! Jadi, ini dia, saat ini cara terbaik untuk melakukannya (dan bahkan dengan 3000 <canvas> )!

Mengapa itu jauh lebih cepat? Mungkin pelaksana SVG asli dapat belajar dari ini (serta Pixi.js dan Two.js)?

Mungkin menggunakan pendekatan ini di Pixi.js akan memerlukan perubahan pada tabrakan/pemilihan? Akan ada tekstur persegi panjang, bukan mesh.

@trusktr Alasan yang cepat adalah Anda menggambar di kanvas sekali, lalu mengunggahnya sebagai tekstur ke GPU. Dalam contoh itu ada tekstur terpisah yang dihasilkan untuk setiap jari-jari yang dibulatkan menjadi langkah 4px (jika saya memahaminya dengan benar ). Animasinya cukup cepat sehingga Anda tidak akan melihat pertukaran tekstur.

Anda dapat melakukan hal serupa dengan API gambar Pixi dengan menyimpan objek Grafik dalam cache ( cacheAsBitmap ). Dengan begitu Anda dapat menggambar primitif Anda sekali dan menggambar ulang dengan cepat dari cache.

Dalam contoh itu ada tekstur terpisah yang dihasilkan untuk setiap jari-jari yang dibulatkan menjadi langkah 4px (jika saya memahaminya dengan benar )

Ini sebenarnya pembulatan ke kenaikan 0,25. Berapa banyak akurasi sub-piksel yang benar-benar dapat Anda lihat?

Jika itu lucu, lihat cara kerja CanvasTinter Pixi. Atau bagaimana animasi sprite sheet bekerja. Anda mengorbankan beberapa memori sebagai ganti kinerja, dan dengan strategi caching yang baik itu bisa berhasil.

Anda dapat melakukan hal serupa dengan API gambar Pixi dengan menyimpan objek Grafik (cacheAsBitmap). Dengan begitu Anda dapat menggambar primitif Anda sekali dan menggambar ulang dengan cepat dari cache.

Menggunakan cacheAsBitmap mungkin tidak terlihat bagus karena grafiknya akan memiliki alias. Untuk mendapatkan grafik antialias, Anda perlu menggunakan generateCanvasTexture. Jadi bagaimanapun Anda berakhir dengan kanvas, tetapi menggunakan api grafis Pixi Anda tidak dapat melakukan hal-hal sederhana, seperti mengubah garis dasbor pada goresan.

Anda dapat melakukan hal serupa dengan API gambar Pixi dengan menyimpan objek Grafik (cacheAsBitmap).

Untuk mendapatkan grafik antialias, Anda perlu menggunakan generateCanvasTexture

Dengan salah satu dari dua opsi itu, dapatkah saya menganimasikan radius seperti pada contoh Anda @OSUblake ?

(Omong-omong, terima kasih teman-teman, membuka mata saya untuk teknik rendering yang tidak pernah saya bayangkan sebelumnya).

@trusktr Ya, Anda hanya perlu membuat banyak objek Grafik dengan radius berbeda dan membuat peta tekstur yang dihasilkan (sehingga Anda dapat menggunakan tekstur cache untuk setiap radius). Dengan cacheAsBitmap Anda akan memetakan objek Grafik alih-alih tekstur tetapi Anda tidak akan memiliki antialiasing seperti yang dikatakan @OSUblake .

Jenis animasi ini adalah animasi sprite sheet. Ketika Anda dapat menganimasikan menggunakan transformasi maka cache tekstur tidak diperlukan. Seperti jika Anda tidak peduli bahwa goresan lingkaran juga berskala, animasi skala sederhana akan melakukannya.

Tapi saya setuju, kanvas memiliki API menggambar yang lebih baik jadi saya akan menggunakannya. Dan untuk SVG, hierarki dapat dibagi menjadi atlas, seperti yang dilakukan pixi-svg-loader (saya pikir?). Atau jika Anda ingin sprite sheet seperti animasi, itu juga mungkin dengan menggambar status animasi di kanvas.

Mungkin menggunakan pendekatan ini di Pixi.js akan memerlukan perubahan pada tabrakan/pemilihan? Akan ada tekstur persegi panjang, bukan mesh.

Meskipun tidak secepat poligon, kanvas memang memiliki metode untuk melakukan pengujian hit di jalur, isPointInPath . Lihat itu bekerja di peta ini.
https://codepen.io/osublake/pen/dzYzab/?editors=0010

Tampaknya ada svgloader di three.js, mungkin sesuatu yang dapat dipetakan ke pixi.js
https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/SVGLoader.js

Masalah ini secara otomatis ditandai sebagai basi karena tidak ada aktivitas terbaru. Ini akan ditutup jika tidak ada aktivitas lebih lanjut yang terjadi. Terima kasih atas kontribusi Anda.

Utas ini telah dikunci secara otomatis karena tidak ada aktivitas terbaru setelah ditutup. Silakan buka edisi baru untuk bug terkait.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat