Fülle die three.js-Szene mit einem Gitter

8

Was ich suche

Zeigt ein Raster in einer three.js-Szene an, das die gesamte Szene ausfüllt. In diesem Fall ist die Szene das ganze Fenster.

Dieses Gitter stellt eine Oberfläche in 3D dar und kann mit der Maus mit THREE.TrackballControls bewegt werden. Dieses Gitter zeigt auf die Kamera, so dass es zunächst wie eine flache (2D) Oberfläche aussieht, bis der Trackball mit der Maus gezogen wird / p>

Die Breite der Gitterlinien sollte der Breite des Renderers entsprechen.

Was ich gemacht habe

Ich habe ein funktionierendes jsFiddle für das eingerichtet, was ich bisher gemacht habe.

Zuerst finde ich die Grenzen der Szene (all das ist in der jsFiddle),

%Vor%

};

Setup three.js

%Vor%

Diese Funktionen bieten einen Vektor für jede Bildschirmecke,

%Vor%

Ich erstelle eine Geometrie, die eine Linie ganz oben auf dem Bildschirm darstellt, und versuche, Linien von oben nach unten bis zum unteren Bildschirmrand zu zeichnen.

%Vor%

Das Problem

Diese Methode funktioniert nicht, im jsFiddle startet die erste Zeile vom Bildschirm und die Breite der Zeilen füllt nicht die Bildschirmbreite.

    
cs_brandt 19.06.2012, 01:01
quelle

3 Antworten

9

Es gibt also zwei Fehler in Ihrem Code.

Zuerst beginnst du mit der Zeile bei MAX_Y und setzt dann jede Zeile eine feste Distanz unter die letzte. Der relativ kleine Fehler besteht darin, dass Sie in getNWScreenVector und getNEScreenVector die Scheitelpunkte der Linie auf eine Höhe von MAX_Y und dann auf

setzen %Vor%

Sie fügen der Zeile von MAX_Y - (c * this.gridBlockSize) eine Übersetzung hinzu, die eine endgültige y-Position von MAX_Y + MAX_Y - (c * this.gridBlockSize) ergibt, was ein MAX_Y zu viel ist. Wenn es für Ihr Programm sinnvoll ist, mit absteigenden Zeilen von getNWScreenVector und getNEScreenVector zu beginnen, sollten Sie die Zeile line.position.y auf nur

setzen %Vor%

Sie können sehen, dass die Zeilen nun auf jsFiddle zentriert sind, aber sie haben immer noch eine falsche Größe. Dies liegt daran, dass Sie nicht die Tatsache berücksichtigen, dass Ihre Szene in der Perspektive ist. Für Ihre Zeilen ist die z-Koordinate auf 0 gesetzt. Wenn Sie also this.camera.position.z = 1000 einstellen, sind sie 1000 Einheiten von der Kamera entfernt. Es gibt keinen Grund anzunehmen, dass etwas mit der gleichen Breite wie die Pixelbreite des Canvas die gleiche Breite hat, wenn es aus 1000 Einheiten entfernt perspektivisch gezeichnet wird.

Stattdessen können wir berechnen, wie groß sie sein müssen. Ich werde hier nicht auf eine vollständige Erklärung der Perspektive eingehen, aber wir können herausfinden, wie groß die Fläche sein muss, die die Linien abdecken müssen, um den Bildschirm abzudecken. Sie haben in Ihrem Kamerakonstruktor ein vertikales Sichtfeld von 45 Grad und einen Abstand von 1000 zwischen der Kamera und Ihren Linien festgelegt. Three.js zeigt im Grunde die Lösung, wenn Sie einen Blick darauf werfen, wie es die perspektivische Matrix erstellt: makePerspective

Zuerst benötigen wir den vertikalen Abstand der oberen Hälfte des Bildschirms, da 0 in der Mitte des Bildschirms ist. Math.tan(45 / 2 * (Math.PI / 180)) (Tangente der Hälfte des Winkels, in Radianten umgerechnet) gibt die vertikale Entfernung geteilt durch die Entfernung von der Kamera an, sodass Sie die Höhe mit

berechnen können %Vor%

oder verdoppeln Sie es zu

%Vor%

Das horizontale FOV ist nicht gleich, es sei denn, die Leinwand ist quadratisch, aber das Verhältnis von Breite und Höhe des Linienbereichs ist proportional zum Breiten- und Höhenverhältnis des Bildschirms. Wie three.js auch, kannst du einfach mit dem Seitenverhältnis multiplizieren, das du auch dem Kamerakonstruktor gegeben hast, um die Breite herauszufinden:

%Vor%

Dies sind die Werte, die Sie zum Platzieren Ihrer Linien verwenden sollten. Alles zusammen:

%Vor%

Schließlich möchten Sie die Linien über den gesamten Bereich verteilen, also sollten Sie

einstellen %Vor%

Sie können sehen, dass das hier funktioniert: Ссылка

Es gibt jedoch noch einen anderen Weg, um die Linien gleich zu halten, aber die Kamera näher an die Linien zu bringen, so dass die Breite der Linien gerade der Pixelbreite der Leinwand in dieser Entfernung entspricht . Die Formel ist nur eine Überarbeitung der oben genannten für DISPLAY_HEIGHT , aber anstatt für Höhe zu lösen, lösen wir für eine Entfernung, wenn die Höhe der Bildschirmhöhe entspricht:

%Vor%

Sie können das hier sehen: Ссылка

Es ist eine viel kleinere Änderung an Ihrem Code, aber es bedeutet, dass sich die Kameraposition ändert, je nachdem, wie groß die Leinwand ist, was andere Inhalte beeinflussen könnte, die Sie genau platzieren müssen, so dass Sie die Wahl haben.

>     
Brendan Kenny 21.06.2012, 00:13
quelle
17

Seit ThreeJS r57 gibt es einen Helfer namens GridHelper, mit dem Sie wie jedes andere geometrische Objekt ganz einfach ein nettes Gitter zeichnen können.

GridHelper benötigt 2 Parameter. Die erste ist die Größe des Gitters und die zweite ist die Größe der Stufe zwischen 2 Zeilen

Unten ist der Code zum Zeichnen des Rasters in der Szene mit der Größe = 100 und Schritt = 10

%Vor%

In Ihrem Fall können Sie vermeiden, eine Methode namens drawGrid zu haben und diese direkt durch den obigen Code mit zwei Zeilen zu ersetzen, oder Sie können diese über zwei Codezeilen in der drawgrid-Methode hinzufügen.

Ein Live-Beispiel finden Sie hier unter folgendem Link

Beispiel für das Grid-Hilfsprogramm

    
aravind.udayashankara 28.11.2014 12:58
quelle
11

Sie können ein Gitter so zeichnen.

%Vor%     
geedew 23.11.2012 06:14
quelle

Tags und Links