Three.js-Kameraparameter und Lösungen für Z-Fighting-Probleme

In diesem Thema geht es um Perspektivkameras und darum, wie man einen geeigneten Betrachtungsstumpf für entfernte Umgebungen einrichtet.

Fügen Sie hier eine Bildbeschreibung ein

Empfehlung: Verwenden Sie den NSDT-Editor , um schnell programmierbare 3D-Szenen zu erstellen

Perspective Camera ist ein Projektionsmodus, der die Art und Weise nachahmt, wie Menschen Dinge in der realen Welt sehen. Dies ist der gebräuchlichste Projektionsmodus zum Rendern von 3D-Szenen. - three.js

Wenn Sie sich den perspektivischen Kamerakonstruktor in den Three.js-Dokumenten ansehen, sieht er folgendermaßen aus:

new THREE.PerspectiveCamera( fov, aspect, near, far )

In:

  • fov: Sichtfeld der Kamera
  • Aspekt: ​​Seitenverhältnis der Kamera;
  • nah: Kamera in der Nähe des Flugzeugs
  • fern: Kameraferne Ebene.

Zusammen definieren diese Parameter den Betrachtungskegel der Kamera – den Bereich der 3D-Szene, der gerendert und auf dem Bildschirm angezeigt wird.

Zum Beispiel:

const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );

Grundsätzlich können Sie Fov, Nah und Fern auf jeden gewünschten Bereich einstellen. Stellen Sie das Sichtfeld beispielsweise auf etwa 10 oder 20 ein, und Sie können problemlos die Vorderseite des Objekts bzw. alles, was in den Bildschirm hineingezoomt ist, sehen. Wenn Sie das Sichtfeld dagegen auf etwa 90 von 100 einstellen, wird sich alles in der Szene bewegen weit weg.

Wie sieht es mit nah und fern aus?

Natürlich können Sie auch beliebige Werte für die Nah- und Fernebene festlegen, aber wenn die Nah- und Fernbereiche groß sind, kommt es im Nahbereich zu mehr Z-Kämpfen, und wenn die Bereiche zu klein sind, wird es mehr Z-Kämpfe geben Brechen Sie die Szene.

Wenn Sie nah = 0,01 einstellen, sollte fern idealerweise 1000 sein, oder nah = 1, dann können Sie weiter fern = 10000 einstellen.

Wenn Sie jedoch wirklich so etwas wie große Entfernungen benötigen, verwenden Sie nah = 0,0000000001 und fern = 10000000000000. In diesem Fall benötigen Sie jedoch möglicherweise eine andere Option zum Konfigurieren von WebGLRenderer.

Warum?

Der Grund dafür ist, dass die GPU nur über eine begrenzte Präzision verfügt und nicht bestimmen kann, ob sich ein Objekt vor oder hinter anderen Objekten befindet. Diese Präzision ist sowohl nah als auch fern verteilt. Erschwerend kommt hinzu, dass die Präzision in der Nähe der Kamera standardmäßig detailliert ist, während die Präzision in der Ferne grob ist. Diese Einheiten beginnen in der Nähe und dehnen sich langsam aus, je näher sie kommen. - Threejsfundamentals.org

Um die Situation zu veranschaulichen, haben wir eine einfache Szene mit einem 3D-Modell, einer Kamera und einem Renderer, die wie folgt eingerichtet sind:

// camera
this.camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight,
  0.00000001,
  10000
);
this.camera.position.set(10, 6, 10);

// renderer
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.physicallyCorrectLights = true;
this.renderer.outputEncoding = THREE.sRGBEncoding;

was denkst du wird passieren

Mit dem 3D-Modell stimmt etwas nicht. Sie können sehen, dass alle Texturen fehlerhaft sind. Dies ist ein Beispiel für Z-Fighting, bei dem die GPU eines Computers nicht präzise genug ist, um zu bestimmen, welche Pixel vorne und welche hinten liegen.
Fügen Sie hier eine Bildbeschreibung ein

Eine Lösung besteht darin, dass Sie Three.js anweisen müssen, eine andere Methode zur Berechnung zu verwenden, welche Pixel vorne und welche dahinter liegen. Wir können dies tun, indem wir logarithmicDepthBuffer im WebGLRenderer-Konstruktor aktivieren.

Unser Renderer sieht nun also so aus:

// renderer
this.renderer = new THREE.WebGLRenderer({ 
  antialias: true,
  logarithmicDepthBuffer: true
});
// ...

Überprüfen Sie das Ergebnis, es sollte funktionieren ...
Fügen Sie hier eine Bildbeschreibung ein

logarithmicDepthBuffer kann dieses Problem natürlich lösen, seine Verwendung wird jedoch nicht immer empfohlen, da es langsamer als die Standardlösung sein kann, insbesondere auf den meisten mobilen Geräten.

Das bedeutet, dass Sie Ihre Nah- und Ferndistanzen stets Ihren Bedürfnissen anpassen sollten. Beachten Sie nun, dass es eine alternative Option gibt, die Sie ausprobieren können, wenn Sie eine große, weit entfernte Szene zeichnen möchten, ohne irgendwelche Objekte in der Szene zu zerstören.

Hoffe das hilft!


Ursprünglicher Link: Kameraparameter und Z-Fighting-Lösung – BimAnt

おすすめ

転載: blog.csdn.net/shebao3333/article/details/132586971