Three.js: Das neue MeshStandardMaterial in r112 weist auf einigen GPUs Streifenartefakte auf

Erstellt am 30. Dez. 2019  ·  18Kommentare  ·  Quelle: mrdoob/three.js

Ab r112 weist das Standard-MeshStandardMaterial (in diesem Fall speziell beim Laden von glTF-Dateien, wahrscheinlich aber auch in anderen Szenarien) auf einigen GPUs Streifenartefakte auf. Insbesondere habe ich dieses Problem auf einem Pixelbook und jeder Generation von Pixel-Handys gesehen. Das Problem tritt weder bei den von mir getesteten Nvidia-Desktop-GPUs noch bei Oculus Go oder Oculus Quest auf.

Es sollte auch beachtet werden, dass ich beobachtet habe, dass der neue Shader des Materials für meine spezielle Anwendung auf verschiedenen Mobilgeräten, einschließlich solcher, die keine Rendering-Artefakte aufweisen, einen merklichen Leistungseinbruch im Vergleich zu r111 verzeichnete.

Die Artefakte sehen folgendermaßen aus (gerendert mit Three.js r112 auf einem Pixelbook)

Screenshot 2019-12-29 at 9 15 19 PM

Die erwartete Ausgabe sieht folgendermaßen aus (gerendert mit Three.js r111 auf demselben Pixelbook)

Screenshot 2019-12-29 at 9 24 31 PM

Live-Link, der derzeit r112 verwendet: https://xrdinosaurs.com

Alle Dinosaurier auf dieser Seite weisen das Problem auf, aber diejenigen mit großen Flächen mit flachen oder glatten Farben (wie der Bauch des TRex) fallen eher auf.

Das Material im Screenshot (unten vollständig eingefügt) verwendet die glTF-Erweiterung "KHR_materials_pbrSpecularGlossiness" und weist diffuse, normale und spiegelnde / glänzende Texturen auf.

    {
      "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

Hilfreichster Kommentar

@elalish Nachdem ich einige Tests an mehreren Beispielen durchgeführt hatte, konnte ich die tatsächliche Ursache dieser Artefakte ermitteln. Im Gegensatz zu dem, was ich in meinem vorherigen Beitrag gesagt habe, liegt die Hauptursache des Problems nicht in der falschen Koordinatenabtastung, sondern in der Art und Weise, wie PMREMGenerator mit devicePixelRatio .

Auf Geräten mit nominalem Gleitkomma pixelRatio wir "schlechte" Mipmap-Koordinaten für die generierte Textur. Es gibt also kleine Lücken und überlappende Regionen. Ich habe auch festgestellt, dass mein Computer unterschiedliche devicePixelRatios je nachdem, ob ich das Beispiel lokal (0.899 ..) oder online (1) betrachte. Deshalb habe ich diese Artefakte nur lokal erlebt.

Ich habe einen einfachen Test eingerichtet, indem ich setPixelRatio deaktiviert habe, und es scheint das Problem zu lösen. Wenn dies bei anderen der Fall ist, ist es am besten, die Art und Weise, wie PMREMGenerator damit umgeht, umzugestalten.

@toji @ plut0nist Möchten Sie die folgenden Beispiele auf den Geräten überprüfen, auf denen diese Artefakte dargestellt wurden?

DEV Beispiel
TEST Beispiel

Alle 18 Kommentare

Ich kann das Glich auf meinem Pixel (1) bestätigen. Die Artefakte scheinen jedoch nur aufzutreten, wenn KHR_materials_pbrSpecularGlossiness verwendet wird.

18042 wurde geometrisches Anti-Aliasing eingeführt. GLTFLoader ersetzt jedoch den Code des lights_physical_fragment Shader-Chunks durch Folgendes:

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

@toji Können Sie bitte die GLTFLoader Kopie Ihrer App ändern, indem Sie den obigen Code durch Folgendes ersetzen:

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 Auch wenn dieser Patch das Problem nicht löst, sollten wir dies auf jeden Fall zu GLTFLoader hinzufügen, oder?

@ Mugen87 Ja sicher. Ich werde sehen, ob ich auch auf meinem Pixel 3 Repro kann.

@toji Ich alle Pixel ...

Treiberfehler? Ich bin mir nicht sicher, welche Leitung es auslöst. Das Vorhandensein / Fehlen von geometrischem Anti-Aliasing würde diese Art von Artefakt sowieso nicht machen, da bin ich mir ziemlich sicher.

@toji Ich habe auch gerade mein spezielles beschissenes

Ugh, der schwarze Himmel bedeutet tatsächlich, dass die PMREM-Generierung vollständig fehlgeschlagen ist, und dies liegt an diesem seltsamen Fehler und der Problemumgehung, die wir gefunden haben: https://github.com/GoogleWebComponents/model-viewer/pull/920. Ich wollte das in r112 bringen, aber es ist mir entgangen. Wahrscheinlich nichts mit dem Fehler des OP zu tun.

Ich habe den OP-Fehler auf meinem OnePlus 5T sowohl in Chrome als auch in Firefox reproduziert.

Vielen Dank! Wendete den Patch auf GLTFLoader und stellte fest, dass das Streifenartefakt reduziert, aber nicht beseitigt wurde.

Vor dem Patch:

Screenshot 2019-12-30 at 12 11 36 PM

Nach dem Patch:

Screenshot 2019-12-30 at 12 10 35 PM

Grundsätzlich sieht es so aus, als hätte es eine der Bands repariert. :) (Screenshots von einem Pixelbook, aber auch von einem Pixel 4 XL. Ich habe momentan keine anderen Testgeräte bei mir.)

Gerne können Sie weitere Änderungen korrigieren, die Sie testen möchten, oder Sie können https://github.com/toji/xr-dinosaurs überprüfen, wenn Sie sie lokal testen möchten. (Benötigt keine Serverkomponente.)

Was Perf betrifft: Es ist nicht gerade butterartig, aber es ist nicht schlecht.

Vielen Dank. 😁 Ich habe hart an der Leistung gearbeitet. In diesem Fall bemerkte ich während des Updates auf r112 die Perf-Regression und fragte @mrdoob danach . Er schlug vor, dass es sich möglicherweise um den neuen, genaueren Standard-Shader handelt, und schlug vor, einige Materialien gegen MeshLambertMaterial auszutauschen, um dies zu überprüfen. Da das Umgebungsmodell PBR-Materialien ohnehin nicht richtig konfiguriert hatte, habe ich es Lambert aufgezwungen und dort belassen, wodurch alle Perf-Regressionen zurückgewonnen wurden, und dann einige (da es einen großen Teil des Ansichtsfensters einnimmt). Lassen Sie die Dinosaurier mit dem Standardmaterial, da sie der "Held" sind.

Nebenbemerkung: Scene.environment funktioniert derzeit nicht, wenn GLTFLoader Netze mit spiegelnden / glänzenden Materialien lädt, da der Renderer nach MeshStandardMaterial sucht, z

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

GLTFLoader erzeugt jedoch ein ShaderMaterial für jedes Spiegel- / Glanzmaterial. Dies wurde heute beim Testen mit dem T-Rex-Modell ^^ realisiert. Nun, ein Grund mehr, # 14099 endlich abzuschließen.

Ich kann die Streifenartefakte nicht reproduzieren, wenn keine Umgebungskarte verwendet wird. Auf einem Pixel (1) sieht alles gut aus, mit einem einfachen Beleuchtungssetup wie einem Umgebungslicht und einem Punktlicht.

Ähm, es scheint mehr Probleme mit physischen Materialien zu geben, die eine Umgebungskarte verwenden. Sehen Sie sich an, wie die folgenden Beispiele auf einem Pixel 1, Android 10, aussehen.

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

Ich kann diese Artefakte auf meinem iMac nicht reproduzieren.

Auf meinem Computer passiert etwas ziemlich Seltsames. Ich kann diese Artefakte auf allen Beispielen reproduzieren, die das neue PMREMGenerator . Aber nur, wenn sie lokal ausgeführt werden. Wenn Sie sie online anzeigen (von der Seite threejs.org), erscheinen sie alle korrekt.

Ich habe noch nie ein solches Problem erlebt und bin völlig verloren, was es verursacht.

Ich verwende Windows 10 mit einer GeForce GTX 750 TI, daher denke ich nicht, dass dies ein gerätespezifisches Problem ist.

Aber nur, wenn sie lokal ausgeführt werden. Wenn Sie sie online anzeigen (von der Seite threejs.org), erscheinen sie alle korrekt.

Beachten Sie, dass die dev -Version Änderungen enthält, die in prod noch nicht vorhanden sind. Können Sie bitte den aktuellen Zweig master überprüfen und dann einen lokalen Test durchführen?

Können Sie bitte den aktuellen Hauptzweig auschecken und dann einen lokalen Test durchführen?

Das erste, was ich versucht habe, nachdem ich dieses Verhalten bemerkt habe, sind die gleichen Ergebnisse. Wirklich neugierig.

Können Sie bitte mit Inkognito-Fenstern testen? Manchmal werden Dinge zwischengespeichert oder Browsererweiterungen stören, was sehr verwirrend sein kann

Versucht mit Inkognito, gleiche Ergebnisse :(

Ich glaube, ich weiß, warum diese Streifenbildung auftritt.
Während der Mip-Generierung erstellt meine lokale (falsche) Version ein schwarzes Band, das in der Live-Version nicht vorhanden ist.

local
online

Dies wird auch auf niedrigere Mip-Levels repliziert.

Dies geschieht wahrscheinlich aufgrund einer falschen Koordinatenabtastung. Ich habe versucht, die anisotrope Filterung manuell zu deaktivieren, aber das Problem bleibt bestehen. Es ist schwierig, genau zu bestimmen, was gerade passiert, vor allem, weil ich mir nicht vorstellen kann, warum es zwei verschiedene Verhaltensweisen auf derselben Maschine zeigt.

@elalish Nachdem ich einige Tests an mehreren Beispielen durchgeführt hatte, konnte ich die tatsächliche Ursache dieser Artefakte ermitteln. Im Gegensatz zu dem, was ich in meinem vorherigen Beitrag gesagt habe, liegt die Hauptursache des Problems nicht in der falschen Koordinatenabtastung, sondern in der Art und Weise, wie PMREMGenerator mit devicePixelRatio .

Auf Geräten mit nominalem Gleitkomma pixelRatio wir "schlechte" Mipmap-Koordinaten für die generierte Textur. Es gibt also kleine Lücken und überlappende Regionen. Ich habe auch festgestellt, dass mein Computer unterschiedliche devicePixelRatios je nachdem, ob ich das Beispiel lokal (0.899 ..) oder online (1) betrachte. Deshalb habe ich diese Artefakte nur lokal erlebt.

Ich habe einen einfachen Test eingerichtet, indem ich setPixelRatio deaktiviert habe, und es scheint das Problem zu lösen. Wenn dies bei anderen der Fall ist, ist es am besten, die Art und Weise, wie PMREMGenerator damit umgeht, umzugestalten.

@toji @ plut0nist Möchten Sie die folgenden Beispiele auf den Geräten überprüfen, auf denen diese Artefakte dargestellt wurden?

DEV Beispiel
TEST Beispiel

@sciecode Vielen Dank, dass Sie die Grundursache herausgefunden haben! Ich werde sehen, ob ich eine Lösung finden kann.

@sciecode : Auf meinen Geräten

Ich war sehr neugierig, warum PMREMGenerator devicePixelRatio ausmachen musste, also ging ich graben. Es stellt sich heraus, dass renderer.setViewport() den DPR automatisch in alle von Ihnen gesendeten Werte einbezieht. Dies scheint eindeutig das falsche Verhalten für andere Renderziele als den Standard-Framebuffer zu sein, denen exakte Pixelwerte zugewiesen sind, die dies nicht tun berücksichtigen überhaupt das Pixelverhältnis. Ich würde vorschlagen, dass das "richtige" Verhalten hier darin besteht, dass intern rendere.setViewport() getTargetPixelRatio() , was 1 zurückgibt, wenn das aktive Renderziel etwas anderes als das Standardziel ist. Ich kann jedoch definitiv sehen, wie dies zu Problemen mit der Abwärtskompatibilität führen kann.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen