Three.js: Bug SkinnedMesh saat jauh dari root scene (0,0,0)

Dibuat pada 9 Feb 2018  ·  113Komentar  ·  Sumber: mrdoob/three.js

Sepertinya saya menemukan bug tentang SkinnedMesh Anda (diuji pada iPhone 6 & 8).

Jika ini sudah dilaporkan, saya minta maaf, saya tidak menemukannya di daftar masalah :(

Tampaknya skinning GPU tidak berfungsi dengan benar dan menjadi gila di ponsel.
Saat SkinnedMesh bergerak atau digerakkan pada posisi bernilai tinggi (misal: x: 0, y: 0, z: 1000), skinning tidak akurat lagi dan memulai spider dance.

Skala mesh memengaruhi bug.

Tampaknya nilai tulang kerangka tidak dihitung dengan benar di setiap bingkai dan tulangTekstur / tulangMatrix pada shader menguliti mendorong simpul di tempat yang salah.
Ini hanya perasaan saya saja.

Saya menjalankan banyak tes sebelum memposting ini ... mencari petunjuk dalam ekspor animasi saya tetapi saya menemukan bug terjadi dengan semua jenis format (GLTF, FBX, Collada, JSON, ...) dan model dari repo ThreeJS.

Itu sangat menjengkelkan karena itu berarti kami tidak dapat mengembangkan game pelari sederhana dengan avatar yang berjalan (avatar.position.z meningkat kemudian) tanpa masalah ini: ((
Saya masih tidak tahu bagaimana saya akan mengelolanya karena morphTarget bukanlah pilihan :(

Semoga kalian bisa membantu di sini.

Saya membuat contoh yang jelas dengan sumber yang bersih untuk mengungkap masalah. Cukup mudah untuk memverifikasinya di ponsel pintar:

Hanya muncul di ponsel (z = 10000):
http://cornflex.org/webgl/skinning-bug.html

Dengan floatVertexTextures disetel ke false (z = 10000):
http://cornflex.org/webgl/skinning-bug2.html

Semakin parah dengan jarak (z bertambah):
http://cornflex.org/webgl/skinning-bug3.html

Sangat sangat jauh dari pusat (z = 70000000)> bug juga muncul di desktop tetapi pasti karena masalah presisi float:
http://cornflex.org/webgl/skinning-bug4.html

Pratinjau Video di lingkungan game saya:
Ini adalah dunia skala realistis (1.0m = 1.0 unit threejs).
Bug muncul hanya setelah 50-60m dari akar adegan dan semakin memburuk dengan jarak:
http://cornflex.org/webgl/skin-bug.mp4

SANGAT PENTING
Mesh yang digunakan dari repo ThreeJS terlalu besar. Tingginya seperti 20m.
Itu sebabnya nilai z harus lebih besar untuk melihat bugnya.
Jika mesh ini diperkecil pada ukuran realistis, maka bug mulai muncul bahkan pada 100m.

Versi Three.js
  • [x] Dev
  • [x] r89
  • [x] ...
Browser
  • [ ] Mereka semua
  • [] Chrome
  • [] Firefox
  • [ ] Internet Explorer
  • [x] Safari
OS
  • [ ] Mereka semua
  • [] Jendela
  • [] macOS
  • [] Linux
  • [] Android
  • [x] iOS
Persyaratan Perangkat Keras (kartu grafis, Perangkat VR, ...)

iPhone 6, 8

Bug

Komentar yang paling membantu

Saya ingin menyoroti bagian zeoverlord pengguna ini:

Hal yang bergetar adalah hal yang wajar untuk float, variabel akan kehilangan presisi semakin tinggi angkanya, jadi presisi adalah yang terbaik jika semakin mendekati 1.0. Sekarang ini sebenarnya bukan masalah tetapi itu berarti bahwa jika Anda melakukan banyak kalkulasi matriks dengan bilangan besar, Anda akan mengalami banyak degradasi presisi (alias jittering). Jadi, Anda perlu melakukan semua matematika di sekitar asal dengan angka yang masuk akal dan kemudian menerjemahkannya

Semua 113 komentar

Um, demo Anda terlihat bagus di Pixel saya.

Masalah yang dikonfirmasi pada iPhone SE saya -

img_6324

Masalah presisi WebGL di iOS mungkin

Tetapi perangkat iOS benar-benar menggunakan jalur kode berbasis tekstur float dari implementasi skinning, bukan? Bisakah Anda memverifikasi ini dengan tes kesesuaian berikut?

https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/extensions/oes-texture-float.html

iPhone SE memiliki lima kegagalan di halaman itu. 😕

Saya membuat screencast kecil untuk ditunjukkan kepada Anda dalam proyek saya:
http://cornflex.org/webgl/skin-bug.mp4

Jika avatar berjalan terlalu jauh dari 0,0,0, kulit mulai menjadi sangat buggy seperti yang Anda lihat.
Saya membuat profil yang dalam dari kerangka dan tulang. Semua tampak baik-baik saja kecuali geometri "ditarik kembali" dalam beberapa cara ... Saya berpikir tentang root animasi yang buruk tetapi sekali lagi, semua tampak baik-baik saja di Threejs dengan itu ...

Masalahnya jelas terkait dengan kerangka dan tekstur tulang dari shader Skinning.
Saya juga berpikir tentang presisi tetapi seperti yang dikatakan Mugen, perangkat iOS harus mendukungnya dengan mudah.

... mengapa hanya di iphone maka: /

Saya cukup macet ... Saya reorientasi ke urutan png sebagai rencana cadangan ... :(

Ini kemungkinan besar karena iphone 6 tidak cukup mendukung tulang.

Saya memiliki masalah yang sama persis.

Periksa batas tulang Anda di sini: https://virtulo.us/2/vr/test

Saya rasa tidak.
Jika skinnedmesh tetap di 0,0,0, tidak ada masalah sama sekali: /
Saya bahkan berpikir untuk memindahkan semua aset alih-alih avatar ... (ini adalah solusi saya # 2) tapi saya pasti lebih suka kerangka bekerja sebaik desktop tentunya.

Seorang teman baru saja melaporkan bug yang sama di iPhone 8

Setelah melihat sumber ThreeJS selama 2 hari ... Saya pikir ada masalah ketika boneTexture diperbarui.
Sepertinya tekstur ini tidak bergerak dengan benar dan kemudian mendorong kembali simpul ke posisi semula ... tapi saya bisa saja salah tentunya.

img_1411

Hmmm ... di sini saya mengalami GAGAL, ​​lihat:

img_1412

Mungkin masalahnya terkait dengan kegagalan ini. Pixel saya misalnya lulus semua tes.

Mari kita coba sesuatu: Pergi ke WebGLCapabilities dan setel nilai floatVertexTextures menjadi false (ini akan mencegah penggunaan tekstur float). Buat build dan gunakan versi three.js ini di aplikasi Anda. Saya ingin tahu apa yang terjadi 😊.

https://github.com/mrdoob/three.js/blob/099e4364541502fdf22fc7b1c0f54239d2ba1708/src/renderers/webgl/WebGLCapabilities.js#L105

Sudah mencoba floatVertexTextures = false pada perender.
Kulit berhenti menjadi gila tetapi tidak ada animasi lagi: /
Saya akan mendorong sampel.

Ini dia:
http://cornflex.org/webgl/skinning-bug2.html

renderer.capabilities.floatVertexTextures = false;

=> Tidak ada animasi yang berjalan lagi

img_1413

Ya, sama di Pixel saya (Desktop berfungsi). Saya kira kita mencapai batas seragam.

Saya membuat sampel terakhir, dengan bug yang semakin muncul:
http://cornflex.org/webgl/skinning-bug3.html

Mulai dari 0,0,0 dan terus maju ... tunggu beberapa detik ... kulit mulai menggila.

Cukup aneh semuanya OK di 0,0,0. bukan?

z: 1255> masih OKE
z: 18870> kulit gila

img_1415

img_1414

Seperti yang saya katakan, saya secara mendalam membuat profil semua kerangka dan posisi tulang di sisi CPU. Semua nilai tampaknya cukup baik. Satu-satunya petunjuk yang saya miliki adalah boneTextures dan boneMatrixes tidak berfungsi dengan benar di iOS ketika mesh semakin jauh dari 0,0,0.

Saya memeriksa posisi tulang karena itu adalah perilaku tipikal tulang stabil dari simpul akar atau hal-hal seperti itu .... tapi tidak ...

Saya memeriksa tentang presisi float di sisi GPU di shader kulit Anda, tetapi sekali lagi ... sepertinya tidak ada yang berdampak.

Sangat aneh tidak ada yang memindahkan SkinnedMesh ke dalam sebuah adegan dan tidak pernah melaporkan ini: /

Satu pertanyaan lagi: Apakah Anda memiliki masalah yang sama dengan Chrome?

Masalah yang sama ya.

img_1416

Kedengarannya seperti masalah presisi. Sudahkah Anda mencoba memperkecil tampilan? (11195 adalah 11 kilometer).

Pilihan lainnya adalah memindahkan adegan alih-alih karakter. Cenderung menjadi solusi umum untuk adegan besar.

Juga, saya kira kode skinningnya ada di ruang dunia. Kami bisa menyelidiki ini.

Saya melihat jumlah tulang Anda 67.

IPhone 6 saya (wifes) memiliki batas Maksimal Tulang Perangkat Keras 27.

Deformasi yang saya lihat identik dengan yang saya lihat di ponselnya di game saya (dan masalah yang sama yang saya alami sebelum animator memperbaiki armitures mesh). Saya akan terkejut jika ini bukan bagian dari masalah Anda.

Mengapa semakin buruk dari waktu ke waktu? Tidak ada ide. Orang lain menyebutkan sesuatu yang serupa, tidak yakin apakah itu terkait: https://discourse.threejs.org/t/updated-with-fiddle-as-animations-go-faster-there-is-increasing-error-in-accuracy/ 1707/6

Hal menjengkelkan lainnya yang saya temukan di iPhone (setidaknya iphone 6): Saya HARUS menggunakan presisi shader highp, mediump dan lowp jangan mengubah mesh dengan cara yang sama menakutkan (seperti masalah tulang saya di telepon), tetapi teksturnya terlihat aneh dan kacau / pixelated saat beranimasi.

Apa batasan tulang perangkat keras Anda pada perangkat yang Anda uji?

@mrdoob Saya sudah mencoba memperkecil tetapi skinning menjadi gila lebih cepat pada kenyataannya: /
Jika Anda menurunkan skala 0,1, maka bug muncul 10 kali lebih cepat.

Demo yang saya gunakan di sini untuk menjelaskan berasal dari contoh threejs.
Dalam permainan saya, skalanya tidak terlalu besar tetapi bugnya sama, hanya muncul lebih cepat.

Memang skinning tersebut seakan dilakukan di ruang dunia, atau ruang lokal tetapi semakin melebar ketika dipindahkan jauh dari pusat. Itulah mengapa ini berjalan cukup baik pada 0,0,0

Memindahkan seluruh dunia alih-alih avatar adalah pekerjaanku # 2.
Anda harus mengakui itu adalah pilihan yang buruk ketika Anda mengembangkan semua rutinitas permainan pelari di ruang dunia dengan fisika dan semuanya. Dan z = 11000 tidak terlalu jauh untuk permainan pelari: / ... dan itu hanya orang yang sedang berlari, bukan kapal.

Saya membuat banyak game dengan ThreeJS tetapi ini pertama kalinya saya menggunakan skinnedmesh. Bug iOS ini sangat mengganggu.

Workaroung # 1: Saya akan melakukan 6 urutan png sebagai animasi spritesheet. Lalu saya bisa menyimpan logika ruang dunia. Batas waktu tidak jauh :(

@titansoftime Masalahnya juga muncul di iPhone 8 istri saya. Ini tidak hanya terkait dengan iPhone 6.
Juga, jika Anda memiliki masalah tulang maksimal, maka itu akan menjadi buggy dari awal. Di sini, Anda dapat melihat itu bukan buggy di 0,0,0. Maka batas tulang bukanlah masalah. Perhitungan ruang dunia dari tulang dan tulang Matriks di skinning shader adalah, IMO.

Apakah Max Hardware Bones dari iPhone 8?

Saya tidak tahu. Dan saya tidak yakin itu tergantung perangkat.

Tapi sekali lagi ... IMO, ini sama sekali tidak terkait dengan nilai maxbones.

Sampel berfungsi dengan benar di iphone 6,8, X ... bahkan 5 ... hanya ketika SkinnedMesh tetap di 0,0,0
https://threejs.org/examples/webgl_loader_fbx.html

Jika maxbones menjadi masalah, kita tidak akan mendapatkan skinning yang bagus pada 0,0,0 juga.

Saya ingin menyoroti bagian zeoverlord pengguna ini:

Hal yang bergetar adalah hal yang wajar untuk float, variabel akan kehilangan presisi semakin tinggi angkanya, jadi presisi adalah yang terbaik jika semakin mendekati 1.0. Sekarang ini sebenarnya bukan masalah tetapi itu berarti bahwa jika Anda melakukan banyak kalkulasi matriks dengan bilangan besar, Anda akan mengalami banyak degradasi presisi (alias jittering). Jadi, Anda perlu melakukan semua matematika di sekitar asal dengan angka yang masuk akal dan kemudian menerjemahkannya

Mmmh, sangat menarik @ Mugen87! Sepertinya Anda melihat kebocorannya.

z: 1255> masih OKE
z: 18870> kulit gila

Kesalahannya mungkin ada di pihak Anda.
Kesalahan umum: pengubah kulit tidak diterapkan dengan benar.
Kesalahan 1: simpul dikendalikan oleh terlalu banyak tulang
Kesalahan 2: simpul tanpa bobot (atau dengan bobot yang sangat kecil).

Ketika SkinnedMesh dekat dengan asal (0,0,0) Anda tidak akan melihat kesalahan ini.
Tapi bila digerakkan jauh ... Anda akan menyalahkan presisi perangkat seluler.
Jadi hal pertama yang harus dilakukan adalah mendesain ulang (kali ini dengan benar) pengubah kulit.

@RemusMar Apakah Anda melihat sumber halaman?
Contoh yang saya ungkapkan datang langsung dari sumber ThreeJS.

Disebutkan dengan cukup baik dalam deskripsi saya;)

Saya menjalankan banyak tes sebelum memposting ini ... mencari petunjuk dalam ekspor animasi saya tetapi saya menemukan bug terjadi dengan semua jenis format (GLTF, FBX, Collada, JSON, ...)

Saya membuat contoh yang jelas dengan sumber yang bersih untuk mengungkap masalah tersebut. Cukup mudah untuk memverifikasinya di ponsel pintar:

http://cornflex.org/webgl/skinning-bug.html

Contoh yang saya ungkapkan datang langsung dari sumber ThreeJS.

Terus?

Bagaimana kesalahan bisa ada di pihak saya saat ini terjadi dengan semua contoh skinnedmesh dari ThreeJS :)

Kamu berkata:

Kesalahannya mungkin ada di pihak Anda.
Kesalahan umum: pengubah kulit tidak diterapkan dengan benar.
Kesalahan 1: simpul dikendalikan oleh terlalu banyak tulang
Kesalahan 2: simpul tanpa bobot (atau dengan bobot yang sangat kecil).

FBX berasal dari ThreeJS ... dan Anda dapat mencoba dengan GLTF atau format lainnya. Masalahnya sama.

var loader = new THREE.FBXLoader ();
loader.load ('https://threejs.org/examples/models/fbx/xsi_man_skinning.fbx', OnFBXLoaded);

@ Mugen87 telah menemukan petunjuk. Semoga saja orang yang membuat jaring berkulit GPU bisa memperbaikinya.

Bagaimana kesalahan bisa ada di pihak saya saat ini terjadi dengan semua contoh skinnedmesh dari ThreeJS

Saya berkata "Kesalahan mungkin ada di pihak Anda.".
Garis bawah:
Gunakan SkinnedMesh sederhana dengan pengubah kulit yang diterapkan dengan benar:

  • maks 4 tulang per simpul
  • semua bobot = 1,0000

Lihat apakah Anda dapat mereproduksi bug tersebut.

Apa kamu marah? :)
Bug ini tidak bisa berada di pihak saya ... model (fbx, gltf, dae, apa saja) dan sumber kode berasal dari ThreeJS.

Silakan baca posting @ Mugen87 .

Gunakan SkinnedMesh sederhana dengan pengubah kulit yang diterapkan dengan benar:

  • maks 4 tulang per simpul
  • semua bobot = 1,0000

Lihat apakah Anda dapat mereproduksi bug tersebut.

Aku harus pergi sekarang.
Bersulang

Hmmm. Anda tahu apa guys? Ini juga terjadi di desktop :(

Karena mesh contoh ThreeJS sangat besar (tinggi 100m), saya menempatkannya sangat jauh: z = 10000000
Dan lihat, masalah yang sama:
http://cornflex.org/webgl/skinning-bug4.html

Ini pasti sesuatu yang berhubungan dengan posisi tulang dan tulang ruang dunia Perhitungan matriks, seperti yang diungkapkan oleh @ Mugen87 :

https://www.opengl.org/discussion_boards/archive/index.php/t-159613.html
https://www.opengl.org/discussion_boards/archive/index.php/t-159364.html

Seperti yang dijelaskan sebelumnya kepada @mrdoob , saya sudah mencoba

Dalam permainan saya sendiri (dengan skala realistis 1: 1), bug sudah muncul di z: 100.

Anda terus menggunakan jerat berkulit yang dirancang dengan buruk ...
Pokoknya, untuk menutup pokok bahasan ini, berikut adalah studi kasus 1 sampai 1.000.000 (satu juta !!!):
http://necromanthus.com/Test/html5/Lara_1000000.html
Klik pada panggung untuk beralih antara Y = 0 dan Y = 1000000
Perubahan kecil pencahayaan global tersedia per sakelar.
Jadi jika jaring yang dikuliti dirancang dengan benar, hasilnya (mendekati) sempurna.
Bersulang

Kami akan memeriksanya setelah rilis bulan ini.

@mrdoob Terima kasih.

@RemusMar Anda terus mengabaikan apa yang dikatakan di sini. Silakan baca seluruh utas lagi :)

Saya baru saja memberi Anda contoh yang berfungsi tetapi Anda masih tidak mengerti.
http://necromanthus.com/Test/html5/Lara_1000000.html

Dan Anda terus berbicara tentang praktik buruk .
Harap perhatikan hal-hal berikut:
Jumlah digit floating point presisi tunggal adalah 7.
Itu mencakup 1234.567 dan 123456.7
Sebagian besar peta bobot hadir dengan 4 desimal, tetapi bahkan satu pun memberikan hasil yang layak.
Untuk alasan ini semua mesin 3D merekomendasikan nilai maksimal 10.000 untuk ukuran dunia.
Dari 0000.001 hingga 9999.999
Kita semua menginginkan dunia 3D yang "tak terbatas" atau besar, tetapi itu tidak mungkin.
Apa yang Anda lakukan benar-benar salah dari banyak sudut pandang:
desain game, pertunjukan, animasi, dan tabrakan.
Saya harap Anda mendapatkan gambaran utamanya sekarang.

@Remus
Saya cukup memahami apa yang Anda katakan tetapi sayangnya model Anda memiliki masalah yang sama ... dalam tingkat yang lebih rendah tetapi masih ada:
http://cornflex.org/webgl/skin-bug2.mp4

Sumber:
http://cornflex.org/webgl/skinning-bug5.html

Dan jika saya memberikan posisi lebih tinggi dari z = 60.000, itu menjadi lebih buruk ... dan hingga 100000 sama sekali tidak terlihat.

Kita semua menginginkan dunia 3D yang "tak terbatas" atau besar, tetapi itu tidak mungkin.

LOL, saya tidak ingin dunia besar yang tak terbatas ... Saya hanya ingin membuat game pelari, seperti yang saya lakukan berkali-kali sebelumnya dengan ThreeJS ... tapi kali ini saya membutuhkan skinnedmesh sebagai avatar.

Adegan saya: http://cornflex.org/webgl/skin-bug.mp4

Jika kita tidak dapat menganimasikan avatar yang berjalan lebih dari beberapa meter ... lalu apa gunanya ?? (dalam skala realistis 1m = 1 unit threejs, bug sudah muncul dari 100).

BTW, model Anda setinggi 150m ... ini bukan skala realistis.
EDIT:
Di sini pemandangan yang sama dengan skala (0,01, 0,01, 0,01) pada model Anda, untuk membuatnya berukuran realistis (sekitar 1,5 m kemudian). Seperti yang Anda lihat, itu sudah mengganggu z = 300 di ponsel:
http://cornflex.org/webgl/skin-bug3.mp4

Apa yang Anda lakukan benar-benar salah dari banyak sudut pandang:
desain game, pertunjukan, animasi, dan tabrakan.

LOL LOL ... Saya sarankan untuk mengunjungi website dan blog saya tentang membuat game (http://quentinlengele.com, http://cornflex.org, http://www.ddrsa.com, http://br9732.com )

EDIT: adegan Anda tidak terlihat di iOS, layar kosong (http://necromanthus.com/Test/html5/Lara_1000000.html).
img_1418

Menguliti tampaknya dilakukan di ruang dunia, atau ruang lokal tetapi semakin melebar ketika dipindahkan jauh dari pusat. Itulah mengapa ini berjalan cukup baik pada 0,0,0

Ayo lihat:

vec3 transformed = vec3( position );
...
#ifdef USE_SKINNING
    vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
    vec4 skinned = vec4( 0.0 );
    skinned += boneMatX * skinVertex * skinWeight.x;
    skinned += boneMatY * skinVertex * skinWeight.y;
    skinned += boneMatZ * skinVertex * skinWeight.z;
    skinned += boneMatW * skinVertex * skinWeight.w;
    transformed = ( bindMatrixInverse * skinned ).xyz;
#endif

tidak terlihat seperti ruang dunia bagi saya? dalam tautan biasa, transformed disetel ke atribut position - yaitu, koord lokal.

jadi apa pun yang terjadi akan terjadi di sisi js, di mana matriks ikatan dan tulang dihitung. mungkin matriks ikatan melakukan banyak regangan, dan matriks tulang dapat direkayasa untuk beroperasi dalam koordinat lain yang tidak memerlukan banyak regangan dalam matriks terikat ... atau sesuatu seperti itu

(edit: nvm, saya pikir saya salah paham)

me

@makc Sayangnya, saya tidak melihat cukup data revalant di copy / paste shader skinning Anda untuk mengetahui apakah kalkulasi dilakukan dalam coord ruang lokal atau dunia.

Seperti yang saya katakan, pasti ada yang salah dengan perhitungan matriks tulang atau mungkin urutan perhitungan matriks tersebut tidak benar. Seperti yang Anda lihat di forum OpenGL dan seperti yang disebutkan @ Mugen87 , ini adalah petunjuk yang paling relevan, setidaknya bagi saya:

Hal yang bergetar adalah hal yang wajar untuk float, variabel akan kehilangan presisi semakin tinggi angkanya, jadi presisi adalah yang terbaik jika semakin mendekati 1.0. Sekarang ini sebenarnya bukan masalah tetapi itu berarti bahwa jika Anda melakukan banyak kalkulasi matriks dengan bilangan besar, Anda akan mengalami banyak degradasi presisi (alias jittering). Jadi, Anda perlu melakukan semua matematika di sekitar asalnya dengan angka yang masuk akal dan kemudian menerjemahkannya

Sekali lagi, seperti yang dijelaskan, skala objek memengaruhi bug.
Contoh dengan sumber ThreeJS menampilkan bug itu hanya pada z = 100000 tetapi itu karena ukuran mesh (juga berasal dari sumber ThreeJS) sangat besar. Anak laki-laki yang berlari itu tingginya 150m.

Saat Anda melakukan permainan, Anda tidak menggunakan skala seperti itu tentunya. Anda selalu berusaha untuk menjaga dunia Anda dengan 1m = 1unit. Ini bahkan wajib untuk mendapatkan fisika dan perilaku yang baik.

Masalahnya di sini adalah ketika Anda menggunakan SkinnedMesh dengan ukuran realistis: bug sudah muncul di z = 300.

Di mesin apa pun, Anda dapat menjatuhkan SkinnedMesh dengan meletakkannya di x: 30000, y: 60000, z: 140000000 dan tidak ada masalah dengan tulang dan kulit. Tidak ada jittering.

Tentunya saya mengerti cukup baik kami sedang mengerjakan inti Javascript di sini ... tapi tetap saja.

Troll di sini berpura-pura "kita semua menginginkan dunia tanpa batas tetapi tidak mungkin" perlu kembali ke sekolah dan mempelajari transformasi matriks. Atau lebih baik lihat game dunia terbuka dan tanyakan pada mereka sendiri bagaimana avatar mereka bisa "dikuliti" begitu jauh dari root scene 0,0,0 ......

Saya harus mengatakan, bug ini menyenangkan. Di sini, saya dapat mereproduksinya di desktop, tetapi 60K tidak cukup untuk kehabisan presisi:
needs more zeroes

ok, jadi di z = 1e8, inilah yang kita miliki dengan shader saat ini:

screen shot 2018-02-14 at 1 15 56

dan inilah yang kita miliki jika kita mengubah shader menjadi ini (sedikit variasi dari tes off-the-top-of-my-head saya di atas yang saya edit):

#ifdef USE_SKINNING
    vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
    vec4 skinned = vec4( 0.0 );
    skinned += ( bindMatrixInverse * boneMatX ) * skinVertex * skinWeight.x;
    skinned += ( bindMatrixInverse * boneMatY ) * skinVertex * skinWeight.y;
    skinned += ( bindMatrixInverse * boneMatZ ) * skinVertex * skinWeight.z;
    skinned += ( bindMatrixInverse * boneMatW ) * skinVertex * skinWeight.w;
    transformed = skinned.xyz;
#endif

screen shot 2018-02-14 at 1 16 54

masih goyah, tetapi terlihat jauh lebih baik :) sekarang, apa artinya ini dalam konteks masalah ini?

Pertama, Anda tidak bisa hanya menyalin-tempel peretasan ini di shader. Maksud saya, Anda bisa, tetapi ini menggantikan perkalian 1 matriks dengan 4. yang saya usulkan adalah a) menggabungkan matriks tulang dengan invers matriks bind di sisi js dan lolos sebagai satu seragam, atau b) membuat seragam lain hanya untuk ini sepotong shader. Ini kemudian akan menyelesaikan masalah ini (agak) dan mengurangi jumlah perkalian matriks di shader (dengan 1).

oh, dan

Troll di sini berpura-pura "kita semua menginginkan dunia tanpa batas tetapi itu tidak mungkin"

Saya pikir apa yang mereka coba katakan adalah bahwa Anda dapat mengatasi masalah tanpa memperbaiki perpustakaan di pihak Anda. Tidak perlu harus, tapi bisa.

@makc Terima kasih banyak atas waktu Anda dalam hal ini.
Sayangnya sudah terlambat. Saya harus mengantarkan hari Jumat. Saya menggunakan urutan PNG sebagai solusinya.

Jika Anda ingin men-debug ini cukup dalam. Bisakah Anda mencoba menggunakan ukuran jaring yang realistis?
Sekali lagi, model Lara ini juga setinggi 60m jika saya ingat dengan baik.

Saya cukup penasaran untuk melihat apakah tambalan Anda bekerja pada skala realistis juga tentunya :)

Oh dan ... apakah Anda melakukan pengujian di bawah iOS?
Seperti yang dijelaskan di utas ini, ini terutama terjadi pada perangkat iOS (6, 8).
Di Desktop, hanya nilai yang sangat besar yang menimbulkan masalah.

Terima kasih lagi

@OrtOfOn Anda dapat mencoba patch @makc dengan menambahkan ini di bagian atas kode Anda:

THREE.ShaderChunk.skinning_vertex = `
#ifdef USE_SKINNING
    vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
    vec4 skinned = vec4( 0.0 );
    skinned += ( bindMatrixInverse * boneMatX ) * skinVertex * skinWeight.x;
    skinned += ( bindMatrixInverse * boneMatY ) * skinVertex * skinWeight.y;
    skinned += ( bindMatrixInverse * boneMatZ ) * skinVertex * skinWeight.z;
    skinned += ( bindMatrixInverse * boneMatW ) * skinVertex * skinWeight.w;
    transformed = skinned.xyz;
#endif
`;

TIGA.WebGLShader: Shader tidak dapat dikompilasi. : /

patch

Oh man. Anda berakhir dengan kutipan yang salah dan format satu baris. bagaimana Anda menyalin-tempel seperti itu?

juga, saya melakukannya untuk melihat gambar-gambar aneh ini, yang memuaskan rasa ingin tahu saya. Saya percaya bahwa orang lain akan mengambilnya dari sini :)

@makc CTRL + C / CTRL + V ... hanya dari sini ...: /

Sayangnya, bug tersebut kurang kuat dari sebelumnya tetapi masih ada :(

Diuji di iOS (tambalan diterapkan):

Mesh pada skala 1.0 (persis avatar sekitar 20m), posisi z = 10000
http://cornflex.org/webgl/skin-patch1.mp4

Mesh pada skala 0.1 (tinggi avatar sekitar 2m), posisi z = 3000
http://cornflex.org/webgl/skin-patch2.mp4

@mrdoob Saya akan mencoba untuk mereproduksi :) Itu muncul dalam satu baris. Saya sedang menulis di halaman ketika saya melihat balasan Anda muncul dan tidak muncul seperti biasanya, saya berjanji: p ... Saya akan mendapatkan poin bonus ini, Anda akan melihat :)

EDIT: BTW Anda mengedit posting Anda? :)

Saya percaya efek sisa mungkin tidak terkait dengan skinning dan benar-benar mempengaruhi segalanya tetapi Anda tidak menyadarinya karena tidak ada animasi.

@OrtOfOn di tempat Anda, saya akan mencoba untuk membungkus seluruh adegan Anda (dengan kamera) di Object3D ekstra dan mengatur objek ini coords menjadi -1 * avatar coords setiap frame. Ini akan menyimpannya di 0,0,0 coord dunia selamanya.

@markc Saya sangat tidak suka menipu seperti ini. Gameplay dan adegannya tidak dirancang untuk disiksa seperti itu dan sebagai game mobile first, tentu saja performanya harus optimal.

Juga ... bukan kasus saya tetapi bayangkan ini dengan beberapa musuh di SkinnedMesh, datang dari mana-mana ...

Saya tidak punya pilihan karena tenggat waktu dan saya mengganti SkinnedMesh dengan animasi spritesheet (klien OK). Kalau tidak, saya tidak kecuali menemukan sesuatu seperti ini. Saya menggunakan ThreeJS di hampir setiap proyek web dan saya sangat senang dengannya.

Kami tidak menginginkan "dunia tanpa batas" tetapi kami ingin dapat menggunakan fitur SkinnedMesh dan animasi yang bagus ini dalam koordinat ruang dunia, seperti yang kami lakukan di mesin terkenal :)

Saya agak kecewa ... karena saya membuat skrip Animator yang sangat keren berdasarkan fitur crossfade dan terinspirasi dari mecanim ... Untuk proyek selanjutnya pasti: /

@markc Saya sangat tidak suka menipu seperti ini.

Saya tidak berpikir itu curang sama sekali. Begitulah cara kerja semua simulasi ruang. Faktanya, rendering 3D realtime pada dasarnya mengimbangi seluruh pemandangan sehingga bagian tengahnya adalah tempat kamera berada.

@mrdoob ya saya tahu kamera bahkan tidak ada. Kekuatan matriks :) (Saya melakukan beberapa pengembang WebGL / OpenGL asli sendiri).

Bagaimanapun, menempatkan semua adegan ke dalam objek permainan tampaknya agak barbar bagi saya ... terutama untuk membuat animasi berkulit berfungsi.

@OrtOfOn sebenarnya Anda dapat menggunakan adegan itu sendiri. Misalnya dalam contoh lara, lakukan ini:

scene.add(camera);
scene.position.z = -60000;

dan tidak apa-apa (edit: namun, ada yang salah dengan cahaya saat Anda melakukan ini .... @mrdoob ?)

@makc Terima kasih sekali lagi untuk mengusulkan tambalan.

Saya sama sekali tidak ingin menjadi pesimis, tetapi sesuatu memberi tahu saya pencahayaan bukan satu-satunya masalah dengan melakukan manipulasi semacam ini. Itu sebabnya saya menyebut trik dan kecurangan ini karena ketidakpastian hasil dan konsekuensi ke bagian lain dari pipa.

Sayangnya, orang yang membuat game memiliki fisika, raycasters, partikel, ... banyak hal yang dirancang dan harus dirancang untuk berada di luar angkasa dengan skala realistis.

Juga, saya cukup penasaran untuk melihat patch ini beraksi dengan lebih dari satu SkinnedMesh, seperti musuh yang bersembunyi atau bertelur di beberapa tempat di tempat kejadian. Karena apa gunanya dibatasi untuk satu avatar skinnedmesh di 0,0,0 lalu?

Saya akan menggali lebih dalam sumbernya secepat saya bisa tetapi saya harus mengirimkan sesuatu dalam 2 hari ... jadi animasi spritesheet saya cukup baik untuk saat ini semoga.

Karena apa gunanya dibatasi untuk satu avatar skinnedmesh di 0,0,0 lalu?

Intinya adalah sangat kecil kemungkinannya Anda akan merender skin secara bersamaan pada 0,0,0 dan skin lain pada z = 60000. Hanya sedikit kulit di sekitar 0,0,0 yang akan muncul di layar, dan mereka tidak akan cukup jauh untuk memicu bug.

@makc Sekali lagi, tambalan Anda valid di bawah desktop tetapi Anda tidak menguji kasus pada perangkat iOS, di mana bug sudah muncul beberapa meter dari 0,0,0 dengan mesh berskala realistis. Saya membuat cukup banyak video untuk menunjukkannya. Yang ini, misalnya, menampilkan bug hanya pada z = 100: /
http://cornflex.org/webgl/skin-bug.mp4

Apakah Anda selalu menggunakan avatar dengan tinggi 20m di game Anda? :)
Karena nomor yang Anda fokuskan (60000) hanya digunakan untuk mengekspos bug di desktop (dengan lara yang sangat besar atau sampel fbx threejs yang sangat besar) ... bukan di seluler. Dan avatar saya tentu saja tidak sejauh itu ...

Saya akan mengonfirmasi ini sebagai masalah iOS. Sejak setidaknya generasi 6S / 6S +, iOS mengalami masalah dengan floatVertexTextures. Perbaikan yang kami gunakan adalah menonaktifkan fitur itu di iOS. Ini membatasi tulang yang dapat kami gunakan, tetapi kami tetap harus membatasinya untuk mendukung ponsel yang lebih jelek.

Karena perangkat iOS gagal dalam uji kesesuaian yang diposting oleh @ Mugen87 , mungkin ide yang baik untuk menonaktifkan floatVertexTextures, atau bahkan mungkin floatFragmentTextures, di iOS secara default, karena jelas tidak mengimplementasikan fitur yang diiklankan untuk didukung dengan benar.

@ daniel-nth Saya rasa itu masuk akal. Namun ... @OrtOfOn mengatakan z = 60K mereproduksi masalah di desktop ... Saya tidak memiliki masalah pada 60K di desktop, hanya 1e8 yang cukup bagi saya untuk "mereproduksi". Jadi, mungkin masalah ini sebenarnya adalah setidaknya 3 masalah terpisah:

  • tekstur mengambang di ios,
  • sesuatu di 60K di desktop @OrtOfOn ,
  • kehabisan presisi pada 1e8 karena urutan perkalian matriks yang buruk di tulang shader bit (yang saya ganggu di atas),
  • mungkin sesuatu yang lain di vertex shader, karena gadis itu masih agak gemetar setelah tambalan.

Hai kawan,
Pertama, terima kasih telah kembali ke bug ini. Saya masih tidak menemukan waktu untuk menggali di dalamnya :(

@ daniel-nth Skala objek mempengaruhi bug:

Di iOS, dengan objek "Lara" yang sangat besar ini (tinggi = 120, skala = 1), bug memang muncul di z = 60000. Tetapi, jika Anda mengambil mesh berukuran realistis (tinggi = 1,8, skala = 1), itu sudah muncul hanya pada z = 100.

lebih besar skinnedmesh, lebih jauh terjemahannya harus untuk melihat bug.

Seperti yang telah diuji dan dilaporkan di utas ini, menonaktifkan floatTextures pada hasil iOS tanpa skinning sama sekali.

Saya juga menduga perkalian matriks yang buruk atau urutan bar dari perkalian matriks tulang.

Di iOS, dengan objek "Lara" yang sangat besar ini (tinggi = 120, skala = 1), bug muncul di z = 60000

@OrtOfOn tunggu, terus ios? tapi kamu juga bilang:

nomor yang Anda fokuskan (60000) hanya digunakan untuk mengekspos bug di desktop (dengan lara yang sangat besar atau sampel fbx threejs yang sangat besar) ... bukan di seluler.

Di iOS, dengan objek "Lara" yang sangat besar ini (tinggi = 120, skala = 1), bug memang muncul di z = 60000.

Sama sekali tidak besar.
Dan Anda masih belum memahami hubungan antara ukuran model dan skala dunia.
Untuk terakhir kalinya:
http://necromanthus.com/Test/html5/Lara_1000000.html
Tinggi modeil kira-kira = 75 dan skala dunia = 9.999.999.
Dari Z = 0 sampai Z = 1.000.000 (satu juta !!!)
Karena jumlah digit angka floating point presisi tunggal adalah 7, tidak ada desimal yang tersisa !!!
Ini berjalan sempurna di semua laptop dan desktop yang saya miliki.
Bahkan lebih:
ini berjalan sempurna di Android 6 & 7 dan berbagai ponsel Samsung.

lara_1000000

@RemusMar dalam contoh Anda, masukkan ini ke konsol:

camera.position.z += 1e8;
scene.children[2].position.z += 1e8;

Anda akan melihat sesuatu seperti ini:
screen shot 2018-03-03 at 15 48 53

screen shot 2018-03-03 at 15 51 41
itu trippy

Saya akan memberi tahu Anda bahwa z = 1e6 juga tidak terlihat buruk. sekitar 1e7 itu sudah terlihat, dan 1e8 gila

@OrtOfOn Mengatur kapabilitas.floatVertexTextures ke false berfungsi untuk kami di iOS. Saya menduga model Anda menggunakan banyak tulang untuk dimasukkan ke dalam seragam.

Saya akan memberi tahu Anda bahwa z = 1e6 juga tidak terlihat buruk. sekitar 1e7 itu sudah terlihat, dan 1e8 gila

Saya tahu, tetapi untuk nilai-nilai itu Anda tidak tepat.
Untuk presisi bobot simpul jaring berkulit, ukuran dunia maksimal adalah 9.999.999
Itu berarti jarak maksimal beberapa juta, tidak lebih.
Bersulang

@makc Memang, saya mendapatkan nomor yang salah untuk desktop. Itu harus sangat besar, Anda benar dan saya sebutkan di utas sebelumnya sebenarnya: / https://github.com/mrdoob/three.js/issues/13288#issuecomment -364650679

@ daniel-nth Senang mengetahui tetapi apakah Anda yakin? Berikut adalah tes yang saya lakukan di sini di utas ini, dengan model 3d dari sumber threejs. Anda masih dapat melihat kodenya. @ Mugen87 membuat umpan balik yang sama juga, tidak ada animasi dengan model ini. https://github.com/mrdoob/three.js/issues/13288#issuecomment -364572653

Oh, saya lihat modelnya sudah tidak ada lagi. 404 di https://threejs.org/examples/models/fbx/xsi_man_skinning.fbx

@ daniel-nth Jika Anda menggunakan model baru dengan lebih sedikit tulang, maka saya percaya Anda;)

@RemusMar Cukup setuju dengan Anda tentang jarak yang ditimbulkan dalam posting terbaru. Angka (1e6, 1e8, 1e9, ...) pasti akan menghasilkan presisi yang buruk. Tidak diragukan lagi. Tapi tolong berhenti mengejekku. Berhentilah berpura-pura saya tidak mengerti apa-apa dan tanyakan pada diri Anda apakah jaring avatar dengan tinggi 120 tidak besar. Bagi saya, ini sangat besar dan tidak terlalu dapat digunakan dalam permainan game dengan objek berskala realistis lainnya yang dibuat oleh seniman, siaran sinar, fisika, pencahayaan ... dan akan dikirimkan dalam 3 minggu.

Saya bersikeras: menjaga aset dalam skala realistis dengan satuan metrik adalah sesuatu yang wajib untuk membangun game berbasis fisik dengan benar :)

Sayang sekali, di iOS, saya tidak dapat menjalankan avatar saya lebih dari 100m dalam kondisi skala realistis ini: /

PEMBARUAN: Bagaimanapun, @ daniel-nth sepertinya memberi tahu kami bahwa sekarang bekerja dengan floatTextures mati dan jumlah tulang yang sangat terbatas.

Tapi tolong berhenti mengejekku
Saya bersikeras: menjaga aset dalam skala realistis dengan satuan metrik adalah sesuatu yang wajib untuk membangun game berbasis fisik dengan benar :)

Aku tidak sedang mengejekmu.
Tapi 1,5 unit bukan berarti 1,5 meter
Bersulang

@Tokopedia

Saya bersikeras: menjaga aset dalam skala realistis dengan satuan metrik adalah sesuatu yang wajib untuk membangun game berbasis fisik dengan benar :)

tetapi skala ini adalah nilai yang dipaksakan sendiri secara sewenang-wenang. Anda bisa saja memutuskan untuk menggunakan sentimeter, dan kemudian "jaring avatar dengan tinggi 120" sebenarnya lebih kecil dari rata-rata.

@makc Tentu, tetapi mesin fisika / libs mengharapkan Anda untuk menggunakan nilai metrik. Apakah Anda sudah mencoba melakukan beberapa fisika pada objek berskala atau dengan nilai non-metrik? Ini menjadi sangat buruk untuk berkembang dan Anda mendapatkan hasil yang tidak terduga dan tidak realistis. Semua kekuatan Anda harus ditinjau dan ditingkatkan juga. Ini akan berhasil, tetapi tidak akurat.

Tentu saja, ini bergantung pada tingkat presisi yang Anda butuhkan untuk mencapai dan nilai seperti 1e6, 1e7, ... terlalu besar dan akan menghadirkan masalah presisi. Dan Anda tidak perlu bergerak sejauh itu. Kami setuju tentang itu. Tapi, di iOS, kita harus bisa memindahkan gpu skinnedmesh (setinggi 1,5 unit) setidaknya dalam kisaran beberapa ratus unit.

tetapi mesin fisika / libs mengharapkan Anda untuk menggunakan nilai metrik.

Itu tidak benar.
Meter, sentimeter, inci, dll tidak relevan.
Seperti yang saya katakan (beberapa kali) sebelumnya, yang terpenting adalah ukuran dunia (skala) dan keakuratannya.
Perhatikan hal-hal berikut:
jika Anda memiliki jaring berkulit dengan tinggi = 1,5 unit, Anda dipaksa oleh peta bobot simpul untuk menggunakan setidaknya 2-3 desimal.
Untuk mesin fisika (jika ada) Anda mungkin memerlukan 3-4 desimal untuk mendapatkan hasil yang dapat diterima.
Jika akurasi global memerlukan 4 desimal, ukuran dunia maksimal Anda adalah 999 (karena jumlah digit floating point presisi tunggal adalah 7).
Dengan kata lain, Anda dapat menggunakan jarak beberapa ratus jika Anda menginginkan animasi yang layak dan fisika yang layak.
Saya harap Anda mendapatkan gambaran lengkapnya kali ini.
Bersulang

@RemusMar Saya akan berhenti di sini. Tampaknya Anda tidak atau tidak ingin menguji kasus Anda pada perangkat iOS. Anda tidak dapat menggunakan "jarak beberapa ratus" pada perangkat ini dengan gpu skinnedmeshes. Jala menjadi gila dengan sangat cepat. Itulah inti dari utas ini dan saya hanya ingin melaporkannya dari awal. Jadi begitulah.

Saya harap Anda mendapatkan fakta bahwa semua proposisi dan sampel Anda tidak berfungsi pada perangkat iOS, seperti yang dilaporkan oleh orang lain di sini dan oleh tangkapan layar saya: /

Anda tidak dapat menggunakan "jarak beberapa ratus" pada perangkat ini dengan gpu skinnedmeshes.

Kamu salah lagi
Lihat screenshot di atas (Android 7 - ponsel Samsung).
Tinggi model = 75 (radius bola batas kira-kira 38) dan jarak 1.000.000 (satu juta !!!)
Atau tinggi model = 1,5 dan jarak 20.000.

ps
Bukankah masalah saya bahwa iOS selalu merupakan kumpulan bug.

@RemusMar saya tidak salah, Anda troll. Saya berbicara tentang iOS dan Anda berbicara tentang perangkat lain ... apakah Anda gila ??

Bukan masalah saya jika Anda sangat membenci Apple. Ketika salah satu klien saya menginginkan game berbasis web 3D dengan ThreeJS, saya tidak mengatakan kepadanya "persetan dengan iphones Anda" ... Jika Anda melakukannya, saya minta maaf untuk Anda.

Akhir transmisi di sini ... Saya tidak bisa mengikuti ini lagi.

@OrtOfOn Ya, model yang saya gunakan memiliki 19 tulang, 404 fbx memiliki 67.

https://github.com/mrdoob/three.js/issues/13288#issuecomment -364550036 memiliki link ke halaman yang menunjukkan batas tulang yang seragam. Rumus yang digunakan halaman adalah Math.floor((data.webgl.params.MAX_VERTEX_UNIFORM_VECTORS - 20) / 4); Tidak yakin apakah itu 100% akurat untuk three.js, tetapi ia melaporkan 27 bahkan pada iPhone X, yang sayangnya kurang dari setengah bahkan Galaxy S3, tetapi masih banyak untuk game WebGL seluler. Saya dengan cepat memahami folder kerja saya dan di 26 proyek WebGL, hanya satu yang memiliki model dengan lebih banyak tulang, dan model itu tetap di 0,0,0.

@OrtOfOn : Saya mengalami masalah yang sama dengan adegan tetap dan memindahkan karakter berkulit di sekitar adegan. karakternya sangat gugup di iOS. jumlah tulang adalah 22. dimensi pemandangan itu masuk akal. Saya percaya masalahnya adalah bahwa menggunakan tekstur vertex membatasi Anda ke float 32-bit, ditambah dengan pernyataan di atas bahwa Threejs menghitung skinning di ruang dunia!

Saya melihat pernyataan ruang dunia sekarang, dan mudah-mudahan akan menerapkan cara yang tepat untuk menghitung posisi vert dalam ruang lokal dan kemudian menerjemahkan objek - sebagaimana mestinya. Saya belum pernah mendengar ada orang yang menggunakan skinning untuk menempatkan objek di luar angkasa, jadi saya tidak yakin mengapa pelaksana melakukan hal seperti itu.

saya akan posting kembali ketika saya punya solusi.

Perlu diketahui, tekstur float di ios tidak hanya rusak dengan vertex shader. Saya baru-baru ini mengubah tekstur float menjadi tekstur integer untuk memperbaiki pita warna pada ios, jadi ini masalah universal ios. Anda mungkin dapat menggunakan tekstur integer untuk memperbaiki tulang di ios, juga, jika Anda benar-benar menginginkannya - berikut cuplikan yang relevan dari shader orang lain:

vec2 encodeFloatRG( float v )
{
    vec2 kEncodeMul = vec2(1.0, 255.0);
    float kEncodeBit = 1.0/255.0;
    vec2 enc = kEncodeMul * v;
    enc = fract (enc);
    enc.x -= enc.y * kEncodeBit;
    return enc;
}

float decodeRGFloat( vec2 enc )
{
    vec2 kDecodeDot = vec2(1.0, 1.0/255.0);
    return dot( enc, kDecodeDot );
}

... sebenarnya, Anda mungkin bisa (saya berasumsi di sini, tidak benar-benar mencoba sesuatu seperti itu) membuat tekstur tulang apung bekerja, juga, jika Anda menerima presisi ios sebagai batas presisi global dan menyimpan dua pelampung dalam tekstur, bukan satu

Saya telah menyelesaikan masalah sepenuhnya dengan meminta threejs melakukan komputasi skinning di ruang lokal - tempatnya - dan menerjemahkan model ke dunia nyata dengan cara standar melalui matriks ruang dunia.

Masalah di atas benar-benar diperbaiki untuk skinning di iOS. Saya juga harus menunjukkan bahwa solusi ini bersifat universal - berfungsi dengan sempurna di semua browser desktop serta perangkat Android yang telah saya uji. Menguliti ruang lokal IMHO adalah cara yang benar untuk digunakan di hampir semua kasus, dan metode ini harus menjadi default untuk ThreeJS. @mrdoob : apa pendapat Anda tentang ini?

mesh = new THREE.SkinnedMesh(geo.geometry, mat);
mesh.bindMode = 'detached';
var skel = new THREE.Skeleton(bones, boneInvs);
var bsm = new THREE.Matrix4().fromArray(geoPrims.bsm);
mesh.bind(skel, bsm);

// make bsmInv identity for models that have multiple skins
mesh.bindMatrixInverse = new THREE.Matrix4();

// patch SkinnedMesh's updateMtxWorld:
// we're using local skinning, so don't keep resetting binMatrixInverse (leave identity)
// the reason we're using .bind here is for models that have more than one skin
mesh.updateMatrixWorld = PatchSkinnedMeshUpdateMW.bind(mesh);

// re-normalize since input data has been compressed
mesh.normalizeSkinWeights();

// remove bone roots and add to bone root list
for (var bi = 0, bl = bones.length ; bi < bl ; bi++) {
    if (bones[bi].parent && !bones[bi].parent.isBone) {
        bones[bi].parent.remove(bones[bi]);
        boneRoots.push(bones[bi]);
    }
}

Di mana 'boneRoots' harus ditambahkan ke objek adegan akar (sehingga mereka mendapatkan pembaruan matriks tetapi tidak mewarisi semua matriks dalam hierarki yang mengarah ke skinnedmesh sebenarnya). Tambahkan boneRoots ini ke root scene Anda (kode tidak ditampilkan).

Dan berikut adalah tambalan untuk menggantikan implementasi ThreeJS 'SkinnedMesh (perhatikan ini hanya diperlukan karena updatematrixworld threejs clobber bindMatrixInverse yang ingin kita simpan sebagai identitas). Alternatifnya, Anda dapat mengikat ke THREE.Mesh..prototype.UpdateMatrixWorld secara langsung daripada menggunakan fungsi tambalan.

function PatchSkinnedMeshUpdateMW( force ) {
    THREE.Mesh.prototype.updateMatrixWorld.call( this, force );
}

@ denbo-ft Menurut saya kedengarannya bagus. Apakah Anda ingin membuat PR untuk itu?

@ denbo-ft Terima kasih banyak atas usaha Anda. Maaf atas balasan terlambat, saya tidak mengikuti utas ini lagi.

kami juga memiliki masalah ini di produk kami - browser apa pun (jika Anda mendapatkan cukup jauh dari 0,0,0) tetapi lebih terlihat di iOS karena itu terjadi segera setelah Anda berjarak sekitar 2-3 unit. Penting bagi kami, tetapi setidaknya kami tertawa terbahak-bahak saat melihat ini
image

Oke, sepertinya masih banyak orang yang membutuhkan ini. Saya tidak pernah berkontribusi pada proyek open source github tetapi saya akrab dengan git dan akan mencoba membuat PR. :)

Sama disini. Penampilan SkinnedMesh saya seperti episode Dr. Katz, Terapis Profesional di iPhone.

FYI, posting saya dari 21 Mei memiliki solusi lengkap. Tidak banyak perbaikan untuk sumber ThreeJS - sebagian besar perbaikan ada pada pemuat dan / atau kode penyiapan adegan untuk masing-masing proyek Anda.

Perbaikan dasarnya adalah dengan menggunakan mode 'terlepas' (yang tidak terdokumentasi, btw), dan menempatkan hierarki tulang ke dalam adegan Anda di tingkat adegan akar - bukan pada tempatnya dengan hierarki karakter yang dapat dirender sebenarnya. Kemudian perbaiki satu hal sederhana dari mesin (SkinnedMesh.update), dan Anda harus melakukannya dengan baik.

Edit:
Kami memiliki format file dan pemuat yang sepenuhnya disesuaikan untuk TJS, jadi sayangnya untuk membuat PR lengkap dengan solusi contoh, saya harus memperbaiki salah satu pemuat kaleng yang disediakan (seperti Collada). Saya akan berusaha melakukannya sekarang

terima kasih, saya akan mengalokasikan waktu untuk mencoba memahami dan juga menerapkan solusi Anda dengan cara yang lebih umum (solusi Anda tampak agak spesifik untuk proyek Anda). Bisakah Anda membagikan lebih banyak konteks untuk kode Anda?

Katz, Terapis Profesional

Aku tidak ketagihan atau apapun, tapi sial .

EDIT:

Saya telah berhasil membuat permintaan tarik - beri tahu saya jika ada hal lain yang dapat saya lakukan.

Posting asli:

Saya memiliki cabang lokal dengan perubahan, tetapi saya tidak bisa mendorong ke asal. Bahkan memberikan kredibilitas github saya, saya mendapatkan kesalahan ini:

Mendorong ke https://github.com/mrdoob/three.js.git
remote: Izin ke mrdoob / three.js.git ditolak untuk denbo-ft.
fatal: tidak dapat mengakses ' https://github.com/mrdoob/three.js.git/ ': URL yang diminta mengembalikan kesalahan: 403

Akan sangat menyukai beberapa saran karena ini adalah kontribusi pertama saya ke github. Terima kasih!

FYI jika PR berfungsi untuk mrdoob dan terintegrasi, ada mode bind baru "lokal" yang mendukung perubahan ini. Saya tidak ingin menambal atau mengubah mode pengikatan "terlepas" yang tidak berdokumen karena tidak ada indikasi siapa atau apa yang menggunakannya dan saya tidak ingin merusak sesuatu yang tidak saya sadari. Tetapi bagi saya tampaknya hal itu mungkin dimaksudkan untuk tujuan ini.

Semua binMode = "local" tidak mengubah bindMatrixInverse selama update, tidak seperti "detached", yang menyetel ulang ke invers dari bindMatrix, bukannya meninggalkan identitas.

Lihat contoh webgl_loader_collada_skinning.html dalam PR ini untuk melihat beberapa perubahan yang diperlukan pada level adegan untuk mendapatkan skinning lokal yang tepat pada karakter yang bergerak di sekitar scene.

Demo pemuat DAE stormtrooper digunakan untuk menguji perbaikan ini. Karakter dipindahkan 2000 unit dari asalnya untuk tes ini. Tangkapan layar di bawah.

Gambar di bawah ini berasal dari iPhone X / Safari 11

Sebelum perubahan ini (pada 2000,2000,2000):
img_0658

Setelah perubahan ini:
img_0659

Menurut Anda, apakah ada cara untuk mencapai ini tanpa memiliki tulang di level adegan dasar dan (0,0,0)? Saya menggunakan tulang untuk melampirkan barang ke avatar, membuatnya melihat titik, dll. Dan saya rasa saya bukan satu-satunya

Anda memiliki dua pilihan:

1) Jaga tulang di ruang dunia pada akar untuk mendapatkan manfaat dari skinning lokal seperti yang diterapkan di threejs. Kemudian lakukan transformasi ekstra jika Anda benar-benar perlu memasang senjata ke Bone, misalnya, untuk memasukkannya ke dalam ruang avatar.

2) Tinggalkan Bones di ruang avatar apa adanya dan lakukan warping di iOS.

Saya pasti akan melakukan # 1. Anda selalu dapat melakukan penghitungan untuk mengetahui di mana objek yang dapat dilampirkan harus berada pada bingkai mana pun saat Anda sudah memiliki posisi tulang dan posisi karakter. Namun, tidak ada solusi untuk # 2 karena pembengkokan disebabkan oleh pengemasan pada level HAL perangkat iOS dan tidak ada yang dapat Anda lakukan. Tentu, Anda dapat menambahkan peretasan tambahan dengan mencoba menggunakan berbagai pengepakan HalfWord dll di atas tetapi semuanya mengurangi masalah, tidak membuatnya hilang. Masalah skinning di ios akan hilang sama sekali jika Anda melakukan skinning di ruang lokal (lebih khusus lagi, pertahankan agar tulang tetap terpusat pada asal dunia agar jumlahnya sekecil mungkin). Kemudian xform menjadi ruang karakter untuk lampiran.

Info lebih lanjut:

Masalah dengan cara penerapannya di TJS bukanlah TJS secara spesifik, tetapi untuk memecahkan masalah batas tulang karena jumlah seragam yang dibatasi per program shader, BoneTextures digunakan. Ini adalah solusi yang cukup standar. Namun, di iOS, float dalam tekstur dikuantisasi - dikemas / dikompresi - menjadi sesuatu yang lebih kecil dari 32-bit. Hal ini menyebabkan "belalang sembah" atau efek aneh lainnya dari karakter ketika ukuran / besaran angkanya "besar", yaitu lebih dari beberapa ratus.

Oke bagus, apa yang kita lakukan sekarang? Nah, setiap fitur besar dari game Anda (sebenarnya mesin game), biasanya membutuhkan Standar Praktik. Contoh: beri tahu artis untuk memusatkan karakter tentang asal. Tempatkan simpul akar karakter a pada kaki / tanah, tulis tulang dan kulit dengan cara tertentu. Kemudian tulis seorang eksportir (atau importir dalam kasus TJS) dan importir yang mengetahui aturan proses Anda. Kemudian dukung fitur terakhir di mesin saat memuat aset yang memiliki konfigurasi ini. Inilah cara kami melakukan berbagai hal di industri game.

Tidak dapat diatur dan tidak dapat ditentukan (keduanya merupakan hal yang buruk untuk pengembangan game) untuk mengharapkan metode authoring APAPUN, format file APAPUN, dan loader generik APAPUN untuk menangani semua fitur game Anda dengan sempurna. Harus ada beberapa standar dan proses di sepanjang jalan.

Jika karakter Anda menggunakan skinning dan juga perlu melampirkan geo untuk senjata atau apa pun, pikirkan tentang apa yang diperlukan untuk mesin ke skin, lalu bekerjalah dengan itu. Saya telah menawarkan satu solusi seperti itu sebagai contoh. Sayangnya, PR tidak diterima karena karena alasan tertentu mereka tidak mau mengganti loader. Bagaimanapun, saya harap saya sudah menjelaskan masalahnya, dan solusinya di utas di atas, serta PR yang saya kirimkan.

Saya tidak dapat berkontribusi lebih dari yang sudah saya miliki. Saya harap saya telah membantu beberapa orang ...

Semoga berhasil!

Masalah skinning di ios akan hilang sama sekali jika kamu melakukan skinning di ruang lokal

Seperti yang saya katakan dari awal, itu adalah solusi untuk batasan iOS (bug) dan Anda harus membuang daya pemrosesan untuk itu.
Itu bukan solusi!
Solusi sebenarnya adalah meningkatkan akurasi floating point di iOS (ke nilai normal 7 digit).
http://davenewson.com/posts/2013/unity-coordinates-and-scales.html

@ denbo-ft Saya benar-benar mengimplementasikan PR Anda (kami memiliki loader sendiri) jadi terima kasih atas kontribusi Anda, itu sangat kami hargai. Saya berharap untuk pendekatan lain karena kami memiliki banyak avatar dalam adegan kami, mereka bergerak, mengambil item, berinteraksi satu sama lain, dll. Dan memiliki kerangka di 0,0,0 akan memaksa kami untuk mengubah banyak barang di kami. kode, berisiko mengalami masalah baru, dll.

Saya menghabiskan waktu untuk memikirkan masalah tersebut tetapi tidak menemukan solusi yang lebih baik. (Masih mencoba)

@Remus

Solusi sebenarnya adalah meningkatkan akurasi floating point di iOS

mungkin seseorang harus bertanya terlebih dahulu pada @grorg and co apa masalahnya dengan tekstur mengambang di sana, dan kenapa bisa seperti itu? karena saya merasa ini bukan hanya bug tetapi juga "solusi" apel untuk beberapa masalah lain

Saya memiliki perasaan bahwa ini bukan hanya bug tetapi "solusi" apel untuk beberapa masalah lain

Mungkin benar.
Serupa dengan masalah di Firefox Android: bug dilaporkan, diverifikasi oleh dev, tetapi tidak diperbaiki dalam 5 bulan terakhir (2 rilis)!?!

Beginilah cara kerja pengembangan perangkat lunak hari ini:
alih-alih memperbaiki di tempat yang tepat, ada solusi di pihak ke-3.
Hasil akhir: kumpulan bug, resource yang terbuang, dan bloatware !!!

@tokopedia
Saya akan merekomendasikan menjaga hierarki tulang di root dan cukup menambahkan fungsi untuk mengambil posisi WS terakhir dari tulang apa pun dengan mengalikannya dengan martixWorld dari matriks lokasi aktual avatar. Ini sangat sederhana dan akan memberi Anda kembali apa yang Anda miliki sebelum memperbaikinya.

Alternatifnya, jika Anda memiliki chops, Anda dapat kembali ke metode asli (dengan bug), menyertakan matriks lokal dalam tekstur tulang, menggandakan penggunaan teksturnya, Kemudian memodifikasi fragmen shader untuk melakukan penghitungan ekstra pada gpu selama skinning . Ingatlah bahwa solusi ini, meskipun "lebih bersih" dari perspektif kode, menggandakan (mungkin empat kali lipat) jumlah tekstur yang diunggah ke GPU setiap frame, dan oleh karena itu jauh lebih efisien daripada saran di atas. Tetapi untuk alasan apa pun yang mungkin Anda miliki yang tidak saya sadari, mungkin lebih bermanfaat bagi Anda untuk melakukannya dengan cara yang terakhir.

Dari apa yang sebelumnya tidak ada solusi, sekarang ada beberapa opsi di sini agar kompatibel dengan SEMUA perangkat, yang merupakan persyaratan yang jelas untuk sebagian besar proyek.

Sepertinya saya harus pergi dengan tulang di 0,0,0 dan melakukan beberapa perhitungan matriks tambahan untuk hal-hal lainnya. Terima kasih!

@ denbo-ft benar. Ini adalah masalah three.js yang disebabkan oleh menguliti di luar angkasa.

Sebagai referensi, di sinilah perubahan world-space-skinning dilakukan: https://github.com/mrdoob/three.js/pull/4812.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

clawconduce picture clawconduce  ·  3Komentar

fuzihaofzh picture fuzihaofzh  ·  3Komentar

seep picture seep  ·  3Komentar

ghost picture ghost  ·  3Komentar

makc picture makc  ·  3Komentar