Three.js: MeshStandardMaterial baru di r112 memiliki artefak pita pada beberapa GPU

Dibuat pada 30 Des 2019  ·  18Komentar  ·  Sumber: mrdoob/three.js

Mulai r112, MeshStandardMaterial default (dalam hal ini secara khusus digunakan saat memuat file glTF, tetapi mungkin juga dalam skenario lain) menunjukkan artefak pita pada beberapa GPU. Secara khusus, saya telah melihat masalah ini di Pixelbook dan setiap generasi ponsel Pixel. Masalah tidak terjadi pada GPU desktop Nvidia yang telah saya coba, atau pada Oculus Go atau Oculus Quest.

Perlu juga dicatat bahwa saya telah mengamati shader baru material tersebut mengalami kinerja yang signifikan relatif terhadap r111 untuk aplikasi khusus saya di berbagai perangkat seluler, termasuk yang tidak menunjukkan artefak rendering.

Artefaknya terlihat seperti ini (Dirender dengan Three.js r112 di Pixelbook)

Screenshot 2019-12-29 at 9 15 19 PM

Output yang diharapkan terlihat seperti ini (Diberikan dengan Three.js r111 di Pixelbook yang sama)

Screenshot 2019-12-29 at 9 24 31 PM

Tautan langsung, saat ini menggunakan r112: https://xrdinosaurs.com

Semua dinosaurus di halaman itu menunjukkan masalah tersebut, tetapi dinosaurus dengan area luas dengan warna datar atau halus (seperti perut TRex) cenderung lebih menonjol.

Materi dalam tangkapan layar (ditempel lengkap di bawah) menggunakan ekstensi glTF "KHR_materials_pbrSpecularGlossiness", dan memiliki tekstur menyebar, normal, dan spekular / kilap.

    {
      "doubleSided": true,
      "emissiveFactor": [
        0,
        0,
        0
      ],
      "extensions": {
        "KHR_materials_pbrSpecularGlossiness": {
          "diffuseFactor": [
            0.46512957319999998,
            0.46512957319999998,
            0.46512957319999998,
            1
          ],
          "diffuseTexture": {
            "index": 4,
            "texCoord": 0
          },
          "glossinessFactor": 0.27610518290000002,
          "specularFactor": [
            0.92244664629999995,
            0.92244664629999995,
            0.92244664629999995
          ],
          "specularGlossinessTexture": {
            "index": 6,
            "texCoord": 0
          }
        }
      },
      "name": "TRex",
      "normalTexture": {
        "index": 5,
        "scale": 1,
        "texCoord": 0
      }
    }
Bug Device Issue

Komentar yang paling membantu

@elalish setelah menjalankan beberapa tes pada beberapa contoh, saya dapat menentukan penyebab sebenarnya dari artefak ini. Bertentangan dengan apa yang saya katakan di posting saya sebelumnya, akar penyebab masalahnya tidak terkait dengan pengambilan sampel koordinat yang salah, tetapi dengan cara PMREMGenerator menangani devicePixelRatio .

Pada perangkat dengan floating point nominal pixelRatio kita mendapatkan koordinat mipmap yang "buruk" pada tekstur yang dihasilkan. Jadi ada celah kecil dan wilayah yang tumpang tindih. Saya juga menemukan bahwa mesin saya memiliki devicePixelRatios tergantung apakah saya melihat contoh secara lokal (0,899 ..) atau online (1) dan itulah mengapa saya hanya mengalami artefak ini secara lokal.

Saya telah menyiapkan tes sederhana dengan menonaktifkan setPixelRatio dan tampaknya menyelesaikan masalah, jika itu kasusnya untuk orang lain, maka akan lebih baik untuk merefaktor cara PMREMGenerator menanganinya.

Pikiran @toji @ plut0nist memeriksa contoh berikut pada perangkat yang menyajikan artefak ini?

DEV Example
Contoh UJI

Semua 18 komentar

Saya dapat mengonfirmasi glich di Pixel saya (1). Namun, artefak tampaknya hanya muncul ketika KHR_materials_pbrSpecularGlossiness digunakan.

18042 memperkenalkan anti-aliasing geometris. Namun, GLTFLoader menggantikan kode potongan lights_physical_fragment shader dengan yang berikut:

https://github.com/mrdoob/three.js/blob/3ba0553208cfc9113152f5f39b4036a448cf3f25/examples/js/loaders/GLTFLoader.js#L683 -L688

@toji Bisakah Anda memodifikasi salinan GLTFLoader aplikasi Anda dengan mengganti kode di atas dengan:

var lightPhysicalFragmentChunk = [
    'PhysicalMaterial material;',
    'material.diffuseColor = diffuseColor.rgb;',
    'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );',
    'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );',

    'material.specularRoughness = max( 1.0 - glossinessFactor, 0.0525 );// 0.0525 corresponds to the base mip of a 256 cubemap.',
    'material.specularRoughness += geometryRoughness;',
    'material.specularRoughness = min( material.specularRoughness, 1.0 );',
    'material.specularColor = specularFactor.rgb;',
].join( '\n' );

@elalish Meskipun tambalan ini tidak menyelesaikan masalah, kita harus menambahkan ini ke GLTFLoader dalam hal apapun, bukan?

@ Mugen87 Ya, pasti. Saya akan melihat apakah saya dapat melakukan repro pada Pixel 3 saya juga.

@toji Saya tidak melakukan repro pada Pixel 3 saya dengan Android 10, jadi setidaknya tidak semua Pixel ...

Bug pengemudi? Saya tidak yakin baris mana yang memicunya. Ada / tidak adanya anti-aliasing geometris tidak akan membuat artefak semacam itu, saya cukup yakin.

@toji Saya juga baru saja mencoba ponsel penguji jelek khusus saya (Alcatel yang

Ugh, langit hitam sebenarnya berarti pembuatan PMREM gagal sepenuhnya, dan itu karena bug aneh dan solusi yang kami temukan: https://github.com/GoogleWebComponents/model-viewer/pull/920. Saya bermaksud memasukkan ini ke r112, tetapi saya gagal. Mungkin tidak terkait dengan bug OP.

Saya mereproduksi kesalahan OP pada OnePlus 5T saya di Chrome dan Firefox.

Terima kasih! Menerapkan tambalan ke GLTFLoader dan mengamati bahwa artefak pita berkurang, tetapi tidak dihilangkan.

Sebelum tambalan:

Screenshot 2019-12-30 at 12 11 36 PM

Setelah tambalan:

Screenshot 2019-12-30 at 12 10 35 PM

Pada dasarnya, sepertinya itu memperbaiki salah satu band. :) (Tangkapan layar diambil pada Pixelbook, tetapi juga diamati pada Pixel 4 XL. Saat ini saya tidak memiliki perangkat uji lain.)

Senang untuk menambal perubahan lain yang ingin Anda uji, atau Anda dapat memeriksa https://github.com/toji/xr-dinosaurus jika Anda ingin mengujinya secara lokal. (Tidak memerlukan komponen server apa pun.)

Adapun perf: ini tidak persis mentega, tapi tidak buruk.

Terima kasih. 😁 Bekerja keras untuk kinerja. Dalam hal ini selama pembaruan ke r112 saya melihat kinerja regresi dan bertanya kepada @mrdoob tentang hal itu. Dia menyarankan itu mungkin shader standar baru yang lebih akurat dan menyarankan menukar beberapa bahan dengan MeshLambertMaterial untuk memverifikasi. Karena model lingkungan tidak memiliki bahan PBR yang dikonfigurasi dengan benar, saya memaksanya ke Lambert dan meninggalkannya di sana, yang memperoleh kembali regresi kinerja apa pun dan kemudian beberapa (karena itu membutuhkan sebagian besar area pandang.) Meninggalkan dinosaurus dengan bahan standar karena mereka adalah aset "pahlawan".

Catatan kaki: Scene.environment saat ini tidak berfungsi ketika GLTFLoader memuat mesh menggunakan bahan-bahan specular / glossiness karena penyaji memeriksa MeshStandardMaterial eg

https://github.com/mrdoob/three.js/blob/dd81aad5513d66e35e51f3a3b42555bc8aef5cbc/src/renderers/WebGLRenderer.js#L1633

Namun, GLTFLoader membuat ShaderMaterial untuk setiap bahan specular / glossiness. Hal ini disadari hari ini saat menguji dengan model T-Rex ^^. Nah, satu lagi alasan untuk akhirnya menyelesaikan # 14099.

Saya tidak dapat mereproduksi artefak pita saat tidak ada peta lingkungan yang digunakan. Semuanya terlihat bagus pada Pixel (1) dengan pengaturan pencahayaan sederhana seperti ambient dan point light.

Um, sepertinya ada lebih banyak masalah dengan material fisik menggunakan peta lingkungan. Lihat bagaimana contoh berikut terlihat pada Pixel 1, Android 10.

https://threejs.org/examples/webgl_materials_envmaps_exr

Screenshot_20200106-111923

https://threejs.org/examples/webgl_materials_physical_clearcoat

Screenshot_20200106-111856

https://threejs.org/examples/webgl_materials_envmaps_hdr

Screenshot_20200106-111809

Saya tidak dapat mereproduksi artefak ini di iMac saya.

Sesuatu yang cukup aneh terjadi di mesin saya, saya dapat mereproduksi artefak ini pada semua contoh yang menggunakan PMREMGenerator . Tetapi hanya saat menjalankannya secara lokal; ketika melihatnya online (dari halaman threejs.org) semuanya tampak benar.

Saya tidak pernah mengalami masalah seperti itu dan saya benar-benar bingung dengan penyebabnya.

Saya menjalankan Windows 10 dengan GeForce GTX 750 TI, jadi menurut saya ini bukan masalah khusus perangkat.

Tetapi hanya saat menjalankannya secara lokal; ketika melihatnya online (dari halaman threejs.org) semuanya tampak benar.

Ketahuilah bahwa versi dev memiliki perubahan yang belum ada di prod . Bisakah Anda memeriksa cabang master saat ini dan kemudian melakukan tes lokal?

Bisakah Anda memeriksa cabang master saat ini dan kemudian melakukan tes lokal?

Hal pertama yang saya coba setelah memperhatikan perilaku ini, hasilnya sama. Penasaran banget.

Bisakah Anda menguji dengan jendela penyamaran? Terkadang hal-hal mungkin di-cache atau ekstensi browser mengganggu yang bisa sangat membingungkan

Mencoba dengan penyamaran, hasil yang sama :(

Saya yakin saya tahu mengapa ikatan ini terjadi.
Selama pembuatan mip, versi lokal saya (salah) membuat pita hitam yang tidak ada di versi langsung.

local
online

Ini juga direplikasi ke level mip yang lebih rendah.

Ini mungkin terjadi karena beberapa pengambilan sampel koordinat yang salah, saya telah bereksperimen dengan secara manual menonaktifkan pemfilteran anisotropik, tetapi masalahnya tetap ada. Sulit untuk menentukan dengan tepat apa yang terjadi, terutama karena saya tidak dapat memahami mengapa hal itu menghadirkan dua perilaku berbeda pada mesin yang sama.

@elalish setelah menjalankan beberapa tes pada beberapa contoh, saya dapat menentukan penyebab sebenarnya dari artefak ini. Bertentangan dengan apa yang saya katakan di posting saya sebelumnya, akar penyebab masalahnya tidak terkait dengan pengambilan sampel koordinat yang salah, tetapi dengan cara PMREMGenerator menangani devicePixelRatio .

Pada perangkat dengan floating point nominal pixelRatio kita mendapatkan koordinat mipmap yang "buruk" pada tekstur yang dihasilkan. Jadi ada celah kecil dan wilayah yang tumpang tindih. Saya juga menemukan bahwa mesin saya memiliki devicePixelRatios tergantung apakah saya melihat contoh secara lokal (0,899 ..) atau online (1) dan itulah mengapa saya hanya mengalami artefak ini secara lokal.

Saya telah menyiapkan tes sederhana dengan menonaktifkan setPixelRatio dan tampaknya menyelesaikan masalah, jika itu kasusnya untuk orang lain, maka akan lebih baik untuk merefaktor cara PMREMGenerator menanganinya.

Pikiran @toji @ plut0nist memeriksa contoh berikut pada perangkat yang menyajikan artefak ini?

DEV Example
Contoh UJI

@sciecode Terima kasih banyak telah mencari tahu penyebab

@scieciec : Diverifikasi di perangkat saya. Uji Contoh DEV menunjukkan garis hitam yang sangat jelas di peta lingkungan sedangkan Contoh TEST tidak. Debugging yang luar biasa, terima kasih!

Saya sangat penasaran mengapa PMREMGenerator perlu memperhitungkan devicePixelRatio , jadi saya pergi menggali. Ternyata itu karena renderer.setViewport() secara otomatis memfaktorkan DPR ke dalam nilai apa pun yang Anda kirimkan, yang terasa seperti perilaku yang salah untuk target render selain framebuffer default, yang dialokasikan dengan nilai piksel yang tepat yang tidak. memperhitungkan rasio piksel sama sekali. Saya menyarankan perilaku yang "benar" di sini adalah bahwa secara internal rendere.setViewport() harus menggunakan getTargetPixelRatio() , yang mengembalikan 1 ketika target render yang aktif adalah apa pun selain default. Saya pasti bisa melihat bagaimana hal itu bisa memperkenalkan masalah compat ke belakang.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat