Shader khusus yang diterapkan ke instans Teks dapat mengaktifkan beberapa efek animasi yang sangat bagus. Untuk banyak dari ini, Anda ingin memperlakukan setiap karakter/mesin terbang secara independen, dan untuk itu Anda memerlukan sesuatu di shader yang memberi tahu Anda karakter mana yang sedang dirender.
Secara teoritis gl_InstanceID
dapat digunakan untuk ini, karena kami menggunakan instance untuk paha depan mesin terbang. Dan semacam ini berfungsi: https://codesandbox.io/s/zealous-water-m8lzq?file=/src/index.js -- tetapi gl_InstanceID
hanya tersedia di WebGL2, dan tampaknya rusak dalam implementasi ANGLE ketika digunakan dalam fungsi selain void main
. Jadi itu tidak realistis digunakan untuk ini sekarang.
Sebagai gantinya, kita bisa menambahkan atribut instance kita sendiri, seperti attribute float charIndex;
, yang hanya menampung indeks karakter yang bertambah. Shader khusus kemudian dapat memanfaatkannya.
Saya mungkin ingin menjadikannya fitur keikutsertaan, seperti textmesh.includeCharIndexInShader = true
, hanya untuk menghindari pembuatan larik atribut tambahan jika tidak diperlukan.
Mungkin juga: wordIndex
, lineIndex
...?
kata dan baris akan diaktifkan per baris dan per animasi kata, seperti https://greensock.com/splittext/ (yang dapat kami anggap sebagai contoh bagus tentang apa yang akan diaktifkan oleh perubahan ini)
Apakah saya benar dengan asumsi ini juga akan memungkinkan perubahan per-token (char, Word, line) di shader fragmen?
Apakah saya benar dengan asumsi ini juga akan memungkinkan perubahan per-token (char, Word, line) di shader fragmen?
Anda harus meneruskannya dari simpul ke fragmen sebagai variasi, tapi ya. :)
Menuruni lubang kelinci kita pergi...
Saya dapat memikirkan kegunaan untuk semua indeks berikut, ditambah jumlah total untuk masing-masing indeks:
Kami ingin membuat semua keikutsertaan ini dan melakukan beberapa pengemasan cerdas untuk meminimalkan jumlah atribut glsl baru yang kami perkenalkan. Saya harus lebih memikirkan API untuk ini.
kita bisa membiarkan pengguna memilih SEMUA dari mereka dengan bendera, jadi
{
split: { kata: benar, karakter: benar, baris: benar }
}
lakukan beberapa pengepakan cerdas
Pikiran memperluas ini? aku penasaran
Saya suka gagasan membiarkan pengguna memilih pemisahan.
Dengan mengemas, maksud saya, kami tidak ingin menambahkan 12 deklarasi attribute float foo
baru atau kami akan mencapai batas (saya pikir total 16 atribut di webgl), tetapi kami dapat mengemasnya menjadi maksimal 3 baru attribute vec4 foo
, dan kemudian membongkarnya ke variabel float
yang tampak lebih bagus di dalam shader.
Oh ya, masuk akal, terima kasih!
Haruskah charIndex
menyertakan spasi putih dalam penambahannya? Atau hanya kenaikan untuk mesin terbang yang terlihat? Saya condong ke arah mesin terbang yang hanya terlihat.
Menghitung spasi putih akan membuat kejutan aneh saat menganimasikan berdasarkan indeks, jadi saya juga condong ke arah yang terlihat
Saya memiliki banyak pembersihan yang harus dilakukan, tetapi saya memiliki POC awal dari jumlah di atas. Berikut adalah contoh menggunakan berbagai pasangan indeks/total untuk mengubah warna dalam shader fragmen:
charIndex / totalChars:
charInWordIndex / totalCharsInWord:
charInLineIndex / totalCharsInLine:
wordIndex / totalWords: (terlihat sangat mirip dengan charIndex/totalChars dalam contoh ini tetapi ada sedikit perbedaan)
wordInLineIndex / totalWordsInLine:
lineIndex / totalLines:
Saya berhasil memasukkan semua data ke dalam maksimal 3 seragam + 2 atribut, yang cukup bagus. Saya masih ingin menjadikannya opsional.
Luar biasa! Beri tahu saya jika Anda memiliki versi uji coba
Saya sedang mencari untuk melakukan fitur yang dapat diatasi ini. Saya memiliki banyak label 3 huruf untuk diletakkan di sekitar bola. Saya membuatnya selalu menghadap penonton dan membuat penyesuaian sehingga di layar ukurannya selalu sama, tidak peduli penskalaan yang diterapkan dalam matriks tampilan atau matriks pemodelan.
Saat ini, saya membuat satu objek Text
per label dan menerapkan transformasi.
Saya berpikir saya bisa mendapatkan kinerja yang jauh lebih baik dengan mengemas semua label dalam satu teks dan memiliki atribut untuk memiliki posisi pada bidang setiap label untuk melakukan transformasi yang benar di shader vertex.
@lojjic dapatkah Anda mendokumentasikan cara membuat shader khusus? Saya pikir menambahkan atribut seharusnya tidak sulit seperti metode yang ada setAttribute
dari BufferGeometry
harus dilakukan.
Opsi lain yang saya pertimbangkan adalah rendering instance, karena semua label saya memiliki 3 huruf. Tapi itu pasti membutuhkan WebGL 2 dan mungkin terlalu rumit untuk dilakukan, setidaknya di awal.
@FunMiles Saya pikir Anda benar, ini dapat memfasilitasi hal semacam itu. Jika saya memahaminya dengan benar, pengoptimalan dapat melibatkan dua bagian:
Untuk 1, lihat komentar ini , yang mungkin sebenarnya sudah cukup untuk kebutuhan Anda. Itu juga merupakan demonstrasi yang bagus tentang cara menerapkan shader khusus, pada dasarnya hanya menetapkannya sebagai material
. Saya telah menggunakan utilitas createDerivedMaterial Troika untuk itu di sana, tetapi Anda juga dapat meneruskan ShaderMaterial
atau materi apa pun dengan modifikasi onBeforeCompile
sendiri.
Untuk 2, saya pikir Anda benar, Anda dapat membuat satu Teks dan kemudian menggunakan atribut _some_ untuk menggantikan karakter individu di sekitar bola Anda. Atribut indeks karakter/kata baru yang dijelaskan dalam masalah ini mungkin dapat membantu, tetapi saya tidak yakin itu diperlukan. Anda mungkin bisa mengkodekan perpindahan tersebut ke InstancedBufferAttribute baru, di mana masing-masing vektornya menampung perpindahan untuk satu karakter (geometri Teks adalah segi empat sederhana yang dibuat untuk setiap mesin terbang, jadi InstancedBufferAttributes tambahan akan dilangkahi untuk setiap mesin terbang.)
Saya tertarik untuk melihat apakah Anda beruntung melakukan ini!
@lojjic Anda mengerti dengan benar. Dan kode yang Anda tautkan melakukan 90% dari apa yang saya butuhkan untuk (1). Demo Anda sangat cocok dengan kasus penggunaan saya.
Jika saya dapat meminta Anda untuk mengoreksi pemahaman saya, inilah cara saya melihat apa yang Anda lakukan:
mvPosition
diinisialisasi dengan posisi titik referensi dalam ruang tampilan model. Saya menganggap titik referensi itu sebagai titik jangkar. Apakah itu benar?position
adalah offset dari titik referensi itu dan saya kira itu hanya memiliki koordinat x dan y bukan nol. (yang membuat saya berpikir Anda dapat melewatkan penghitungan komponen z dari skala?) (PS: Melihat kode render vertex shader yang diinstruksikan, tampaknya seseorang dapat memutar teks, dalam hal ini komponen z tidak akan menjadi nol)position
yang diskalakan ditambahkan, dan jika komponen z adalah nol, kontribusi ini menjaga posisi dalam bidang sejajar dengan bidang proyeksi.Perubahan bagi saya untuk kode ini hanya untuk melakukan (1) sebagian besar dalam penskalaan dan sedikit pergeseran koordinat sehingga teks tetap berada di luar bidang yang saya miliki.
Anda memang mengerti 2 juga. Namun saya agak bingung ketika membaca kodenya. Saya tidak menyadari bahwa rendering teks sudah menjadi rendering instan. Yang membingungkan saya adalah Anda memiliki GlyphsGeometry
yang diturunkan dari InstancedBufferAttribute
namun Text
adalah subkelas dari Mesh
dan bukan dari InstancedMesh
. Saya kira saya harus menggali lebih dalam ke Three.js.
Jika tidak, karena setiap karakter di-instance, saya hanya perlu atribut dengan vektor untuk mengimbangi position
untuk setiap instance mesin terbang. Apakah itu benar?
Saya harus menjauh dari ini sebentar, tetapi inilah pembaruan status cepat:
PR #109 terasa cukup solid dalam hal mengumpulkan dan mengekspos berbagai hitungan. Saya ingin membuat mereka ikut serta tetapi sebaliknya saya senang dengan tempatnya.
Namun, saya memiliki firasat kuat bahwa animasi berbasis shader akan membutuhkan tidak hanya hitungan baru ini, tetapi juga mungkin akses ke beberapa data lain seperti:
Beberapa di antaranya secara teknis sudah ada di shader, tetapi jika pengguna akan bergantung pada mereka maka mereka harus diekspos dengan nama yang ramah dan didokumentasikan sebagai kontrak yang andal.
Jika ada yang punya waktu untuk bermain dengan cabang PR itu dan mencoba menerapkan beberapa animasi shader, dan beri tahu saya bagian info apa yang hilang, itu akan sangat membantu.
@lojjic Hanya ingin mengungkapkan minat saya pada fitur ini
Saya menyelesaikan beberapa konflik gabungan dengan master terbaru di sini: https://github.com/canadaduane/troika/tree/char-indices
Saya belum memiliki kesempatan untuk mengujinya, tetapi berniat untuk melakukannya dalam beberapa hari ke depan.
Saya sudah lama meninggalkan diskusi ini. Namun saya hanya diingatkan bahwa saya ingin kembali melihatnya.
Di akhir posting ini adalah contoh dari sesuatu yang saya lakukan menggunakan createDerivedMaterial
.
Namun, saat ini, ada satu jaring per label dan ketika jumlah label menjadi sangat besar, rendering menjadi tersendat-sendat pada ponsel kelas bawah. Saya berasumsi itu karena panggilan CPU untuk setiap label. Untuk mengatasinya, saya ingin mengganti beberapa mesh dengan satu mesh dengan semua label dan menggunakan vertex shader yang ditingkatkan untuk melakukan sisanya.
Saya pikir, seperti yang disebutkan @lojjic , saya perlu beberapa batasan pada kata-katanya. Atau setidaknya, untuk saya gunakan, pusat dari setiap kata.
Adakah saran lain tentang cara melakukannya atau tentang cara mendapatkan pusat itu?
Komentar yang paling membantu
Saya memiliki banyak pembersihan yang harus dilakukan, tetapi saya memiliki POC awal dari jumlah di atas. Berikut adalah contoh menggunakan berbagai pasangan indeks/total untuk mengubah warna dalam shader fragmen:
charIndex / totalChars:
charInWordIndex / totalCharsInWord:
charInLineIndex / totalCharsInLine:
wordIndex / totalWords: (terlihat sangat mirip dengan charIndex/totalChars dalam contoh ini tetapi ada sedikit perbedaan)
wordInLineIndex / totalWordsInLine:
lineIndex / totalLines:
Saya berhasil memasukkan semua data ke dalam maksimal 3 seragam + 2 atribut, yang cukup bagus. Saya masih ingin menjadikannya opsional.