Three.js: GLTFLoader: Hasil model Normal-Tangent Test salah

Dibuat pada 3 Jun 2017  ·  30Komentar  ·  Sumber: mrdoob/three.js

Deskripsi masalah

Saya mencoba menampilkan model Tes Normal-Tangent .
Namun, hasil yang ditampilkan tampaknya berbeda dari sampel Khronos.

Hasil model Three.js + Normal-Tangent Test:
image

Pemuat sampel Khronos + Hasil model Tes Normal-Tangen:
image

Saya rasa model sampel ini harus memiliki hasil kiri dan kanan yang sama.

Terkait: https://emackey.github.io/testing-pbr/normal-tangent-readme.html

/ cc @emackey

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

ThinkPad X260 + Windows 10 + Intel HD Graphics 520

Bug Loaders

Komentar yang paling membantu

Saya ingin menyebutkan satu kalimat dari spesifikasi glTF pada peta normal khususnya:

Vektor normal menggunakan konvensi OpenGL di mana + X benar dan + Y atas. + Z menunjuk ke arah penampil.

Kalimat inilah yang memungkinkan model dikirim tanpa vektor bersinggungan, menghemat ruang.

Mari kita uji. Di sini saya telah membuat peta ketinggian yang buruk (peta benjolan) dari percikan dalam program pengecatan:

TestHeightMap

Mari tentukan bidang ketinggian ini sebagai tonjolan luar, di mana piksel putih lebih dekat ke penampil, dan piksel hitam lebih jauh.

Menggunakan konverter online (dengan kualitas yang dipertanyakan, tetapi kita akan memeriksa hasilnya sebentar lagi), saya telah mengubahnya dari peta ketinggian ke peta normal. Perlu diingat bahwa tidak ada model 3D di sini, tidak ada koordinat UV atau kalkulasi mikktspace atau geometri apa pun. Hanya peta ketinggian yang diubah menjadi peta normal. Saya harus secara manual mengkonfigurasi konverter online sesuai instruksi glTF, seperti X benar, Y atas, dan Z menghadap penampil. Inilah hasilnya:

TestNormalMap

Mari kita bawa itu kembali ke program pengecatan dan hancurkan saluran warna untuk melihat di mana titik vektor ini. Di bawah ini, setiap saluran warna telah dipisahkan menjadi gambar grayscale-nya sendiri. Ingatlah bahwa ini akan ditafsirkan sedemikian rupa sehingga hitam berarti -1.0 , abu-abu tengah berarti 0.0 , dan putih berarti +1.0 .

TestNormalMap-Decomposed

Jadi saya pikir konverter online melakukan apa yang diminta glTF, setidaknya setelah mengkonfigurasinya dengan benar. Pada gambar Merah (X), kita bisa melihat kemiringan di sebelah kanan memiliki piksel putih (+1.0), menunjuk vektor X di tepi kanan gambar. Di sisi kiri gambar Merah, piksel hitam (-1.0) menunjuk vektor X di sisi kiri gambar. Pada gambar Hijau (Y), piksel putih di sepanjang kemiringan atas titik lonjakan vektor Y di bagian atas gambar. Nilai Z adalah yang paling tidak intuitif, tetapi ingat bahwa ujung tonjolan dan pelat belakang itu sendiri mengarah ke penampil, dan lereng di semua sisi mengarah menjauh, jadi semuanya lebih gelap secara merata.

Bagaimana jika kita memuat ini ke Blender Eevee, yang (seperti glTF) menerima peta normal gaya OpenGL? Apa yang terjadi jika peta UV diputar, atau bahkan diskalakan untuk dibalik?

NormalSpinTest

Ternyata, ini berfungsi dengan baik. Memang, inti dari mendefinisikan ruang tangen dengan cara ini bukanlah untuk memungkinkan perangkat lunak menjadi gila dengan vektor, itu untuk memungkinkan seniman tekstur kewarasan dengan memastikan bahwa peta normal mereka akan berada di sisi kanan terlepas dari geometrinya.

Namun, tidak semua perangkat lunak menggunakan konvensi OpenGL. Beberapa menggunakan konvensi yang berbeda (terkadang disebut konvensi DirectX), di mana vektor Y menunjuk ke bagian bawah gambar, bukan di atas. Berikut saluran Y yang membusuk dari gambar saya dalam formulir ini. Piksel yang lebih terang adalah piksel yang menghadap ke bagian bawah gambar.

TestNormalMap_DirectX-Green

Jika saya memuat salah satu peta normal gaya DirectX ini ke dalam Blender Eevee, apakah saya masih dapat mengharapkannya untuk berfungsi?

NormalSpinTest_DirectX_v3

Tidak. Blender mengharapkan + Y up. Perhitungannya salah, dan garis cakrawala yang dipantulkan berputar ke sekeliling.
Hal yang sama terjadi jika Anda memuat peta normal gaya OpenGL ke mesin yang mengharapkan + Y turun.

Inilah yang coba diuji oleh model NormalTangentTest. Setiap baris memutar koordinat UV ke orientasi yang berbeda, mencoba memastikan bahwa pantulan tetap menghadap kanan dalam orientasi yang berbeda ini.

Semua 30 komentar

Terima kasih telah menulis ini di @ cx20.

Untuk konteks selengkapnya, berikut beberapa info & masalah terkait:

  • Saya melaporkan masalah serupa pada @donmccurdy 's ThreeJS glTF viewer, donmccurdy / tiga gltf-viewer # 10. Tapi sekarang saya pikir ini adalah bug di loader glTF ThreeJS, bukan di penampil. Jadi, masalah baru ini ditempatkan lebih baik daripada masalah lama saya.

  • Dalam edisi lama di atas, model dulu menghadap ke langit, tetapi kemudian saya memutarnya untuk menghadap cakrawala. Ini membuatnya lebih mudah untuk melihat ketika pantulannya tidak tepat, karena cakrawala berputar dengan gila-gilaan, seperti yang ditunjukkan di atas.

  • Penggunaan model peta normal sendiri dikonfirmasi benar dengan diskusi di KhronosGroup / glTF # 952.

  • Penanganan peta normal ThreeJS dipertanyakan di # 11315.

  • BabylonJS baru-baru ini mengalami masalah serupa, dilaporkan di sini , dan diperbaiki di sini . Berikut adalah demo langsung loader glTF 2.0 BabylonJS dengan perbaikan yang diterapkan .

Tulisan yang bagus, terima kasih!

Model tampaknya dirender dengan benar dengan penambahan baris ini:

materialParams.normalScale = new THREE.Vector2(-1, 1);

Tapi saya tidak yakin saya memahami masalahnya dengan baik. Memahami # 11315 mungkin bisa membantu di sini.

@donmccurdy Terima kasih atas saran Anda.
Saya mengerti itu meningkatkan dengan menyesuaikan skala normal.
Namun, jika model glTF benar, menurut saya lebih baik untuk menggunakan glTF Loader.

@ cx20 setuju, perbaikan ini sekarang digabungkan menjadi THREE.GLTF2Loader.

Saya telah mengonfirmasi bahwa ini sedang diperbaiki.

Hasil model Three.js + Normal-Tangent Test:
image

Ini telah mengalami kemunduran, antara r101 dan r104:
Screenshot from 2019-06-11 16-38-27

Lihat https://github.com/mrdoob/three.js/pull/15749 - regresi disengaja, dan dapat dihindari dengan menyertakan garis singgung dalam model.

Idealnya kita akan memiliki implementasi JS untuk menghasilkan garis singgung mikktspace, untuk menyelesaikannya sepenuhnya, tetapi itu cukup kompleks.

Saya tidak menyadari # 15749 sampai sekarang. Saya terkejut dengan hal ini, saya pikir kami telah melakukan pekerjaan yang cukup baik dalam mendefinisikan garis singgung di glTF sehingga setidaknya dapat diperkirakan pada saat runtime.

Perhatikan bahwa pengekspor Blender tidak akan mengekspor garis singgung glTF apa pun secara default, karena ini membantu menjaga ukuran file tetap rendah, dan implementasi utama glTF semuanya lulus pengujian ini tanpa garis singgung. Saya menduga perubahan ini mungkin telah merusak pemetaan normal untuk sebagian besar model glTF di ThreeJS.

Saya memerlukan waktu untuk membaca semua masalah terkait untuk mendapatkan pemahaman yang lebih dalam tentang apa yang terjadi dan mengapa. Tapi saya pikir komunitas glTF harus mempertimbangkan prioritas tinggi ini untuk mendapatkan model tanpa garis singgung rendering dengan benar lagi, karena saya yakin sebagian besar model berada dalam kategori itu secara default.

Membuka kembali 😅

Saya menduga perubahan ini mungkin telah merusak pemetaan normal untuk sebagian besar model glTF di ThreeJS.

Saya tidak percaya itu sesuatu yang parah - kami selalu menghasilkan garis singgung waktu nyata di shader dengan turunan, dan kami masih melakukannya. Kami sebelumnya menyertakan peretasan ( normalScale.y *= -1 ) yang terjadi untuk memperbaiki model pengujian khusus ini, tetapi juga kebetulan merusak beberapa contoh lainnya. Saya tidak memiliki penjelasan kapan itu membantu, atau tidak, jadi kami menghapus peretasan setelah kami mendukung garis singgung yang tersimpan - dalam hal ini pasti salah. Sekarang model yang mengandalkan peretasan (dan tidak menyertakan garis singgung) rusak, dan model yang dirusak oleh peretasan (dan tidak menyertakan garis singgung) diperbaiki.

Tapi saya pikir komunitas glTF harus mempertimbangkan prioritas tinggi ini untuk mendapatkan model tanpa garis singgung rendering dengan benar lagi, karena saya yakin sebagian besar model berada dalam kategori itu secara default.

Lihat di atas. Secara umum, saya yakin kami membuat model tanpa garis singgung secara memadai. Namun, kami tidak membuat garis singgung mikktspace seperti yang disyaratkan oleh spesifikasi glTF. Sepengetahuan saya, tidak ada implementasi JS yang ada, dan implementasi shader berbasis turunan kami hanyalah perkiraan "sebagian besar cukup baik". Model sampel ini adalah kasus ekstrem yang sengaja didemonstrasikan oleh batas-batas perkiraan tersebut.

Kami akan senang memiliki implementasi generasi tangen mikktspace JS; itu akan menjadi tambahan yang bagus untuk THREE.BufferGeometryUtils. Tetapi kode mikktspace resmi (asli) cukup panjang, dan saya belum menggali cukup banyak untuk melihat berapa banyak yang diperlukan untuk menghasilkan garis singgung.

Kami sebelumnya menyertakan peretasan ( normalScale.y *= -1 ) yang terjadi untuk memperbaiki model pengujian khusus ini, tetapi juga kebetulan merusak beberapa contoh lainnya

Apakah itu merusak model glTF lain secara khusus, atau hanya contoh secara umum?

Ada dua jenis peta normal ruang singgung di alam liar. Substance Painter menyebutnya "DirectX Normals" dan "OpenGL Normals", yang bukan merupakan nama terbesar untuk itu. Perbedaannya adalah secara khusus saluran y dibalik, yang berarti semua nilai saluran hijau dalam tekstur dibalik. Mengalikan y *= -1 adalah cara yang benar untuk mengonversi satu ke yang lain. Yang disebut "DirectX Normals" menggunakan sistem koordinat tangan kiri, dan glTF mendefinisikan sistem koordinat tangan kanan untuk normal / tangen / bitangen.

Apa yang saya curigai terjadi adalah bahwa ketika ThreeJS menghitung garis singgung secara otomatis, ia mengharapkan peta normal telah dibuat dengan gaya Y (DirectX) yang dibalik, dan membuat saluran itu mundur untuk glTF, jadi pembalikan diperlukan. Namun, ketika garis singgung diberikan, pembalikan seperti itu tidak diperlukan.

Pertanyaan tentang mikktspace menurut saya terpisah dari ini. Sangat disayangkan bahwa spesifikasi memanggil mikktspace dan sebagian besar implementasi memperkirakannya dengan turunan ruang-layar. Saya tidak tahu seberapa mirip keduanya, tetapi, peta normal yang dihasilkan di mikktspace tampaknya berfungsi dengan cukup baik ketika ditampilkan dengan perkiraan, selama peta kidal / kidal dilakukan dengan benar.

(Ada juga beberapa diskusi tentang ini dari tahun lalu di KhronosGroup / glTF-Sample-Models # 174)

Saya ingin menyebutkan satu kalimat dari spesifikasi glTF pada peta normal khususnya:

Vektor normal menggunakan konvensi OpenGL di mana + X benar dan + Y atas. + Z menunjuk ke arah penampil.

Kalimat inilah yang memungkinkan model dikirim tanpa vektor bersinggungan, menghemat ruang.

Mari kita uji. Di sini saya telah membuat peta ketinggian yang buruk (peta benjolan) dari percikan dalam program pengecatan:

TestHeightMap

Mari tentukan bidang ketinggian ini sebagai tonjolan luar, di mana piksel putih lebih dekat ke penampil, dan piksel hitam lebih jauh.

Menggunakan konverter online (dengan kualitas yang dipertanyakan, tetapi kita akan memeriksa hasilnya sebentar lagi), saya telah mengubahnya dari peta ketinggian ke peta normal. Perlu diingat bahwa tidak ada model 3D di sini, tidak ada koordinat UV atau kalkulasi mikktspace atau geometri apa pun. Hanya peta ketinggian yang diubah menjadi peta normal. Saya harus secara manual mengkonfigurasi konverter online sesuai instruksi glTF, seperti X benar, Y atas, dan Z menghadap penampil. Inilah hasilnya:

TestNormalMap

Mari kita bawa itu kembali ke program pengecatan dan hancurkan saluran warna untuk melihat di mana titik vektor ini. Di bawah ini, setiap saluran warna telah dipisahkan menjadi gambar grayscale-nya sendiri. Ingatlah bahwa ini akan ditafsirkan sedemikian rupa sehingga hitam berarti -1.0 , abu-abu tengah berarti 0.0 , dan putih berarti +1.0 .

TestNormalMap-Decomposed

Jadi saya pikir konverter online melakukan apa yang diminta glTF, setidaknya setelah mengkonfigurasinya dengan benar. Pada gambar Merah (X), kita bisa melihat kemiringan di sebelah kanan memiliki piksel putih (+1.0), menunjuk vektor X di tepi kanan gambar. Di sisi kiri gambar Merah, piksel hitam (-1.0) menunjuk vektor X di sisi kiri gambar. Pada gambar Hijau (Y), piksel putih di sepanjang kemiringan atas titik lonjakan vektor Y di bagian atas gambar. Nilai Z adalah yang paling tidak intuitif, tetapi ingat bahwa ujung tonjolan dan pelat belakang itu sendiri mengarah ke penampil, dan lereng di semua sisi mengarah menjauh, jadi semuanya lebih gelap secara merata.

Bagaimana jika kita memuat ini ke Blender Eevee, yang (seperti glTF) menerima peta normal gaya OpenGL? Apa yang terjadi jika peta UV diputar, atau bahkan diskalakan untuk dibalik?

NormalSpinTest

Ternyata, ini berfungsi dengan baik. Memang, inti dari mendefinisikan ruang tangen dengan cara ini bukanlah untuk memungkinkan perangkat lunak menjadi gila dengan vektor, itu untuk memungkinkan seniman tekstur kewarasan dengan memastikan bahwa peta normal mereka akan berada di sisi kanan terlepas dari geometrinya.

Namun, tidak semua perangkat lunak menggunakan konvensi OpenGL. Beberapa menggunakan konvensi yang berbeda (terkadang disebut konvensi DirectX), di mana vektor Y menunjuk ke bagian bawah gambar, bukan di atas. Berikut saluran Y yang membusuk dari gambar saya dalam formulir ini. Piksel yang lebih terang adalah piksel yang menghadap ke bagian bawah gambar.

TestNormalMap_DirectX-Green

Jika saya memuat salah satu peta normal gaya DirectX ini ke dalam Blender Eevee, apakah saya masih dapat mengharapkannya untuk berfungsi?

NormalSpinTest_DirectX_v3

Tidak. Blender mengharapkan + Y up. Perhitungannya salah, dan garis cakrawala yang dipantulkan berputar ke sekeliling.
Hal yang sama terjadi jika Anda memuat peta normal gaya OpenGL ke mesin yang mengharapkan + Y turun.

Inilah yang coba diuji oleh model NormalTangentTest. Setiap baris memutar koordinat UV ke orientasi yang berbeda, mencoba memastikan bahwa pantulan tetap menghadap kanan dalam orientasi yang berbeda ini.

Masih perlu ada rumus konkret dalam spesifikasi cara menghitung tangen untuk primitif tunggal, diberi primitif dan koordinat UV-nya, dan tanda W mana yang akan digunakan untuk bitangen. "OpenGL normals" dan "DX normals" tidak cukup tepat untuk mendapatkan rumusnya. Mereka mungkin mengacu pada konvensi, tetapi saya tidak tahu sebagai pelaksana apa yang harus dilakukan dengan itu.

Apa yang saya lakukan saat ini adalah emit membalik TangentW dari MikkTSpace untuk mencocokkan dengan sampel khusus ini, tapi itulah yang terjadi untuk berhasil.

Apakah itu merusak model glTF lain secara khusus, atau hanya contoh secara umum?

Bug yang dilaporkan terkait dengan model glTF, khususnya. Meski begitu, saya ragu ada cukup kepercayaan dalam ekspor material melalui FBX atau COLLADA untuk mengatakan bahwa konvensi peta normal tersebut juga pernah dipahami dan diuji secara menyeluruh.

Perbedaannya adalah secara khusus saluran y dibalik, yang berarti semua nilai saluran hijau dalam tekstur dibalik. Mengalikan y * = -1 adalah cara yang benar untuk mengonversi satu sama lain.

Terima kasih, ini adalah pembenaran yang jauh lebih baik untuk "peretasan" kami daripada saat kami menerapkannya. 😇

Sangat disayangkan bahwa spesifikasi memanggil mikktspace dan sebagian besar implementasi memperkirakannya dengan turunan ruang-layar.

Spesifikasinya benar bahwa MikkTSpace adalah cara paling kuat untuk menghasilkan garis singgung, menurut saya, itu bukan pilihan yang tepat secara universal untuk melakukan ini secara otomatis saat runtime. Jika alternatif yang lebih murah terlihat benar untuk model tertentu, tidak ada alasan untuk melakukan sesuatu yang lebih mahal yang tidak terlihat lebih baik. Bahasa spesifikasi dapat dilonggarkan untuk memungkinkan perkiraan tetapi saya tidak merasa kuat tentang ini.

Masih perlu ada rumus konkret dalam spesifikasi cara menghitung tangen untuk primitif tunggal, diberi primitif dan koordinat UV-nya, dan tanda W mana yang akan digunakan untuk bitangen.

Saya tidak yakin algoritma MikkTSpace begitu mudah untuk direpresentasikan sebagai rumus diskrit ... apakah Anda meminta alternatif untuk kode MikkTSpace kanonik? Atau beberapa informasi tambahan di luar instruksi untuk menggunakan MikkTSpace? @Tokopedia


Untuk masalah aslinya, sepertinya kita harus mengembalikan pengganda normal.y *= -1 suatu tempat. Ada tiga tempat yang memungkinkan untuk melakukan ini:

  • (a) di GLTFLoader, untuk mata jaring yang tidak memiliki garis singgung
  • (b) di GLTFLoader, untuk semua mata jaring
  • (c) di WebGLRenderer, untuk semua mesh

Jika threejs benar-benar menggunakan konvensi DirectX dan misalnya Blender tidak, saya bisa melihat kasus untuk (c). Untuk mendapatkan solusi yang cepat dan aman, saya cenderung memilih (a).

Apa yang saya curigai terjadi adalah bahwa ketika ThreeJS menghitung garis singgung secara otomatis, ia mengharapkan peta normal telah dibuat dengan gaya Y (DirectX) yang dibalik.

Tidak, three.js tidak mengasumsikan bahwa ...

three.js mengasumsikan + Y adalah "atas" untuk ruang tangen, dan peningkatan-V adalah "atas" untuk ruang uv.

Artinya, three.js mengasumsikan uv (0, 0) berada di pojok kiri bawah tekstur, sedangkan spesifikasi glTF mengasumsikan kiri atas. Inilah mengapa GLTFLoader menetapkan texture.flipY menjadi false . (three.js menetapkan texture.flipY menjadi true secara default.)

Jika garis singgung tidak ada, three.js menggunakan turunan ruang layar untuk memperkirakan garis singgung. Itu dilakukan dengan menggunakan aturan rantai. Asumsi dalam perhitungan tersebut adalah bahwa ruang singgung dan ruang uv memiliki orientasi yang sama.

Untuk model glTF yang ditulis dengan benar, asumsi tersebut salah. Namun, Anda harus dapat mengkompensasinya dengan menyetel normalScale.y = - 1 untuk model apa pun yang _ benar-benar sesuai dengan spesifikasi glTF_.

Menurut saya, kami juga dapat memperbaiki ini secara otomatis dengan menghormati bendera flipY di shader.

Jika pengaturan normalScale.y tidak berfungsi, maka sesuatu yang lain sedang terjadi.

Terima kasih atas klarifikasi ini. Saya pikir kami memiliki jalan ke depan di sini.

Tampaknya juga bagi saya kami dapat memperbaiki ini secara otomatis dengan menghormati bendera flipY di shader.

Ya, dengan pengecualian kasus di mana glTF memasok vektor tangennya sendiri, bukan? Saya berharap hanya garis singgung yang dihitung otomatis yang memerlukan tes flipY dan negasi yang sesuai dari y .

Jika bukan itu masalahnya ... itu berarti bahwa model NormalTangentMirrorTest memiliki garis singgung yang salah dikodekan ke dalamnya, yang berarti pengekspor Blender glTF itu sendiri menempatkan garis singgung yang salah ke dalam model glTF.

Sunting: Saya yakin saya telah mengkonfirmasi kebenaran dari vektor tangen yang diekspor, dan mereka tidak memerlukan pembalikan Y apa pun. Saya dapat memposting lebih detail tentang itu jika diperlukan.

Tapi sepertinya tindakan yang benar adalah membalik normalScale.y hanya ketika garis singgung yang dibuat secara otomatis (tidak disediakan garis singgung) digunakan dengan bendera flipY . Pikiran?

Dalam posting saya sebelumnya, saya menjelaskan cara mengkompensasi normals terbalik secara manual ketika atribut singgung tidak ada. Seharusnya tidak ada yang dapat dikompensasikan saat ada garis singgung karena turunan ruang layar tidak digunakan.

Saya juga menyarankan agar kami dapat memperbaiki ini secara otomatis dengan menghormati bendera flipY di shader. Saya tidak mengatakan kami akan memperbaiki ini secara otomatis menjadi membalik normalScale.y , namun. Saya rasa kita tidak perlu mengubah pengaturan pengguna.

Bagaimanapun, sebelum kita menempuh jalan itu, saya pikir sangat penting bagi kita untuk memverifikasi hipotesis ini:

[Y] ou harus dapat mengkompensasi dengan menyetel normalScale.y = - 1 untuk model apa pun yang sesuai dengan spesifikasi glTF.

Kita harus memiliki penjelasan untuk setiap model yang tidak ditampilkan dengan benar.

Saya rasa kita tidak perlu mengubah pengaturan pengguna.

Ya, maaf, saya tidak bermaksud mendikte detail implementasi seperti itu. Saya hanya mencoba untuk memastikan tidak ada kesalahpahaman tentang apa _honoring flipY flag_ artinya secara matematis, untuk tujuan pembuatan garis singgung ruang layar.

Kita harus memiliki penjelasan untuk setiap model yang tidak ditampilkan dengan benar.

Kedengarannya seperti itu berpotensi menjadi kumpulan besar. Jika memang ada model di luar sana yang melakukan sesuatu yang sangat berbeda dari model pengujian resmi, namun masih dapat dianggap sebagai penggunaan yang valid dari peta normal di glTF, itu penting untuk diketahui. Model uji dimaksudkan untuk mencakup penggunaan yang valid dari peta normal pada geometri statis (tidak berubah). Seharusnya tidak ada cara, terutama saat mengandalkan vektor tangen yang dihasilkan penampil, untuk membangun model dalam beberapa sistem koordinat lain, namun mengklaim bahwa itu adalah glTF yang valid.

Saya menganggap ini terkait erat dengan masalah ini? https://github.com/KhronosGroup/glTF-Sample-Models/issues/174

@WestLangDi sini yang saya temukan sejauh ini. Secara default, khronos-NormalTangentTest (tidak ada garis singgung yang disertakan) terlihat salah:
NormalTangentTest
Jika saya menetapkan normalScale.y = -1, itu masih salah:
NormalTangentTestNegY
Jika saya menetapkan normalScale.x = -1, ini terlihat benar:
NormalTangentTestNegX
Dengan pengecualian yang mungkin bahwa rendering terlihat sedikit berpiksel, terutama pada reflektor emas. Apakah ini diharapkan dengan perkiraan ruang layar, atau indikator bug lain?

Jika ada yang memiliki model uji bagus lainnya tanpa garis singgung, kirimkan ke cara saya. Saya ingin memastikan bahwa saya memiliki sampel yang representatif, dan menentukan apakah ada yang tidak sesuai dengan spesifikasi glTF.

@elalish Testbed itu tidak masuk akal bagi saya, tidak pernah masuk akal bagi saya, dan mungkin tidak akan pernah. Jadi ... Saya tidak akan membantu Anda dalam mencoba menjelaskannya.

Contoh itu adalah IMHO terlalu kabur. Kami membutuhkan kasus uji yang koheren yang memberikan visual yang cukup untuk memahami apa yang terjadi.

BTW, kami dulu memiliki VertexTangentHelper (# 3511), yang dapat dihidupkan kembali untuk mendukung geometri buffer.

@ WestLangley Seandainya saya tahu cara membuat NormalTangentTest lebih jelas. Itu tidak melakukan sesuatu yang aneh, itu hanya memutar orientasi (dalam ruang UV) dari setiap sampel. Tiga kolom itu hanya untuk menguji bahan yang berbeda, kolom emas itu sendiri sudah cukup. Selain itu, menurut saya model pengujian tidak bisa menjadi lebih sederhana dan masih menguji orientasi UV yang berbeda ini.

Terlepas dari rotasi UV, gambar peta normal cukup konsisten tentang ke arah mana vektor menunjuk, ketika peta normal dilihat sebagai gambar 2D. Dalam tampilan 2D gambar, sisi kanan semua belahan memiliki nilai saluran merah yang tinggi, dan tepi atas semua belahan memiliki nilai saluran hijau yang tinggi, terlepas dari koordinat UV. Ini mengikuti spesifikasi glTF yang menunjuk merah (+ X) di sisi kanan tekstur di ruang UV, dan titik hijau (+ Y) di tepi atas tekstur di ruang UV. Seseorang tidak perlu menyediakan vektor tangen untuk membuat ini bekerja: perkiraan ruang-layar sederhana yang umumnya arah sumbu + U untuk segitiga tertentu sudah cukup untuk menghitung vektor tangen dan bi-tangen, seperti yang dilakukan BabylonJS dan CesiumJS, dan tentu saja ThreeJS juga melakukannya tetapi dengan beberapa flip sumbu normalScale yang belum dapat dijelaskan.

Ada titik kebingungan yang diketahui dengan penggunaan bendera flipY oleh glTF, membalikkan koordinat V di ruang UV, yang saya yakin sudah Anda sadari dengan baik. Saya sudah lama menduga ini berperan dalam flip normalScale yang tidak dapat dijelaskan.

Ada juga kesalahan kecil saat memanggang pada gambar (salah saya, saya adalah pengguna baru Substance Painter pada saat itu, bertahun-tahun yang lalu). Jahitan sedikit diagonal terlihat terutama di bagian datar dari belahan emas. Tapi ini seharusnya tidak mengurangi efek keseluruhan. Porsi bulat utama dari kue keluar dengan baik, dan menunjukkan dengan baik efek "atas" dan "kanan" yang konstan di seluruh gambar 2D dari tekstur normal, terlepas dari koordinat 3D atau UV yang diputar ke semua arah yang berbeda, dan garis singgung dihilangkan.

Ini adalah efek penting bagi seniman yang membuat tekstur peta normal berulang sebelum geometri 3D dibuat, karena seniman tidak memerlukan akses ke koordinat UV atau garis singgung sebelum membuat gambar tekstur.

@WestLangley Saya suka tes ini hanya karena ini yang terbaik yang pernah saya lihat, alias satu-satunya. Saya akan senang menggunakan model pengujian lain yang saya tunjuk.

Juga, plotnya menebal: Tes aslinya adalah material dua sisi. Karena # 17804, saya memutuskan untuk mencobanya sebagai satu sisi. Ini masih salah secara default, tetapi sekarang saya mendapatkan jawaban yang benar ketika saya mengatur normalScale.y = -1:
NormalTangentTestFrontNegY
Setidaknya saya harap kita bisa setuju bahwa mengubah doubleSided tidak akan mempengaruhi render sisi depan?

@emackey Model uji lain yang dapat membantu Saya pikir akan menjadi kubus mengkilap dengan normals dilas dan peta normal yang sesuai dirancang untuk membuatnya berbentuk kubus bukannya bulat. Mungkin dua versi, satu dengan dan satu tanpa garis singgung yang diberikan. Sayangnya, saya kurang memiliki keterampilan menulis untuk melakukannya sendiri. Yang bisa saya persembahkan adalah banyak terima kasih jika Anda membuatnya untuk kami: berdoa:

@emackey Terima kasih atas semua pekerjaan Anda dalam hal ini. Saya sangat menghargainya. Saya memahami semua berbagai masalah yang bisa muncul dengan seniman - dan masalah yang harus diatasi.

Mungkin Anda bersedia bekerja dengan @elalish dan menyediakan model glb apa pun yang dia minta. Saya berharap itu akan membantu kita memahami.

@elalish Kami telah membahas masalah ini sebelumnya. Pada satu titik, saya mendapat kesan bahwa semuanya bekerja dengan baik. Jika ada kasus uji sederhana, saya dapat menggunakan bisect untuk mengidentifikasi di mana barang rusak.

kubus mengkilap dengan normals dilas dan peta normal yang sesuai dirancang untuk membuatnya berbentuk kubus, bukan bulat.

Selesai: normal_map_flat.zip . Saya mengambil contoh garis singgung, yang ditulis oleh tim Draco, dan membuat versi tambahan tanpa atribut tangent.

Pada satu titik, saya mendapat kesan bahwa semuanya bekerja dengan baik.

Saya pikir kami mencapai keadaan di mana semuanya bekerja _if_ model menyertakan garis singgung. Jika tidak, biasanya semuanya baik-baik saja, tetapi ada beberapa casing tepi yang memungkinkan terutama di sekitar lapisan UV. Dalam hal ini kami akan menyarankan pengguna untuk menambahkan garis singgung. Atau, seperti yang disebutkan @emackey di https://github.com/mrdoob/three.js/issues/11438#issuecomment -507027586, mungkin kita harus mengembalikan flip normalScale.y *= -1 di GLTFLoader, hanya dalam kasus di mana tautan menghilangkan garis singgung simpul.

@DonorTerimakasih . Saya kehabisan waktu untuk masalah ini hari ini tetapi saya masih berjuang dengan sisi kubus datar. Jika Anda mengedit model Anda agar memiliki permukaan yang mengkilap ( metallicFactor: 1, roughnessFactor: 0.1 ), Anda akan melihat pantulan di sisi kubus cukup banyak.

Saya melihat efek yang sama dalam model pengujian saya sendiri. Lebih buruk lagi, efeknya berbeda jika saya melakukan pemanggangan biasa di Substance Painter vs. memanggangnya di Blender Cycles. Setiap program memanggangnya agar benar untuk viewport-nya sendiri, tetapi tidak datar sempurna saat dimuat ke program lain, bahkan tanpa glTF dalam campuran. Ini sangat dekat, tetapi pada permukaan yang datar perbedaan terkecil mengubahnya menjadi cermin funhouse, dan bukan dengan cara yang baik.

Saya pikir saya melihat perbedaan halus dalam cara vektor normal (atau ruang TBN) diinterpolasi antara simpul di permukaan segitiga, di SP vs Blender vs berbagai mesin WebGL. Saya menggunakan Gimp untuk menjalankan "perbedaan" dari kue SP vs kue Blender, dan hasilnya berwarna hitam (nilai RGB yang identik) di setiap simpul, tetapi ruang di antara simpul menunjukkan perbedaan yang berputar-putar dengan intensitas yang sangat redup.

Saya mengharapkan efek rumah kesenangan yang halus, tetapi bukan yang saya dapatkan saat ini (versi tanpa garis singgung):
image
Versi with tangents sebenarnya tidak lebih baik, yang membuat saya bertanya-tanya apakah ini benar-benar glTF yang valid:
image
@emackey Apakah Anda merasa memenuhi syarat untuk memberi tahu kami apakah salah satu atau kedua model yang disediakan @donmccurdy ini sebenarnya glTF valid? Jika ya, saya pikir kita punya masalah besar.

Kubus khusus ini adalah contoh ekstrem yang saya tidak tahu harus berkata apa, atau apakah refleksi yang realistis secara fisik adalah harapan yang adil. Peta normal dimaksudkan untuk menambahkan detail seperti tonjolan dan penyok, bukan untuk mendeformasi seluruh permukaan jaring. Itu kebetulan merupakan cara yang sangat efektif untuk menguji bahwa garis singgung dibaca atau dibuat dengan benar. Saya tahu bahwa perubahan normalScale.y *= -1 tidak pernah cukup untuk memperbaikinya; ini adalah salah satu contoh yang mendorong kami untuk mendukung tangen yang tersimpan di tempat pertama.

Pantulannya terlihat liar di BabylonJS juga:
Screen Shot 2019-10-23 at 4 00 02 PM

Jika satu-satunya masalah yang teridentifikasi adalah dengan NormalTangentTest, dan tidak ada pengguna yang menampilkan model yang dirender secara tidak benar dalam praktiknya, mungkin kita harus menunda untuk membuat perubahan di sini?

Saya masih baik-baik saja dengan memulihkan pengganda normalScale.y *= -1 , tetapi kurangnya contoh masalah tampaknya merupakan indikasi bahwa masalahnya kecil, daripada indikasi bahwa kita perlu membuat contoh ekstrem seperti itu.

Jika satu-satunya masalah yang teridentifikasi adalah dengan NormalTangentTest, dan tidak ada pengguna yang menampilkan model yang dirender secara tidak benar dalam praktiknya, mungkin kita harus menunda untuk membuat perubahan di sini?

Koreksi: https://github.com/mrdoob/three.js/issues/17804 menunjukkan bahwa sesuatu mungkin memang mengalami kemunduran dengan materi dua sisi. Sepertinya perlu untuk diselidiki lebih lanjut, meskipun untuk kesederhanaan dan kewarasan mungkin kita harus membiarkan Cursed Cube sendirian untuk saat ini. 😇

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

zsitro picture zsitro  ·  3Komentar

filharvey picture filharvey  ·  3Komentar

jlaquinte picture jlaquinte  ·  3Komentar

jack-jun picture jack-jun  ·  3Komentar

Horray picture Horray  ·  3Komentar