2017-06-01 1 views
0

Ich baue einen Dateibrowser/3D-Modell-Viewer. Ich möchte Modelle verschiedener Formate (nur .OBJ) in die Szene laden und mit orbitControls.js eine vernünftige Framerate erzielen.Optimieren von Three.js für ein einzelnes großes Modell

Die meisten Optimierungsstrategien, die ich gesehen habe, konzentrieren sich auf den Umgang mit vielen Netzen, nicht einem einzigen großen Netz. Das allerzeit beste Ziel wäre es, riesige Dateien (Hunderttausende/Millionen Vertices) zu laden und nicht alles abstürzen zu lassen. Ich weiß, dass das weit hergeholt ist, aber ich weiß nicht einmal, wo ich mit der Optimierung für dieses Problem anfangen soll, damit ich meine Framerate zumindest ein wenig verbessern kann. Google hat mir bisher nicht geholfen

+0

Verwenden Sie 'OBJLoader'? Welche Version von 'THREE.js' benutzt du? – TheJim01

+0

Ja und die neueste Version – Jason

+0

Die größte mögliche Größe für einen Indexpuffer ist 65535 für webgl1. Es ist daher selten, ein einzelnes Netz zu verwenden, um ein Modell mit genügend Details zu präsentieren. Das erneute Zusammenstellen der Daten in Attributspeichern ist möglich. Aber wie er die Puffergrößengrenze verschiebt, hängt davon ab, mit welchem ​​Algorithmus die Modelle erstellt werden. –

Antwort

0

Eine Sache OBJLoader tut nicht - was könnte wirklich helfen, Ihre Leistung zu verbessern - ist Indexierung (Gesichter mit gemeinsamen Scheitelpunkt/normale Paare). Ich habe einen Würfel aus Blender exportiert und 36 Indizes erhalten (1 Dreieck = 3 Eckpunkte, 2 Dreiecke pro Würfelfläche = 6 Eckpunkte, 6 Flächen = 36 Eckpunkte). Derselbe Würfel mit Indexierung wäre 24 Ecken.

Indexierung does erhöhen Sie die Größe Ihres Objekts um die Anzahl der Indizes. Der Würfel ist ein schlechtes Beispiel dafür (24 Indizes), weil nur sehr wenige Flächen denselben Eckpunkt haben, aber bei komplexen Netzen können die Einsparungen ziemlich hoch sein.

Ich denke, erklären alle Details, wie die Indizierung funktioniert über den Rahmen einer Antwort, und ich bin sicher, dass andere Ressourcen haben einen besseren Job gemacht als ich es könnte, aber hier ist ein kleines Beispiel eines Flugzeug:

var planeGeo = new THREE.BufferGeometry(); 
planeGeo.addAttribute("position", new THREE.BufferAttribute(new Float32Array([ 
    -10, 10, 0, 
    -10, -10, 0, 
    10, -10, 0, 
    10, 10, 0 
]), 3)); 
planeGeo.addAttribute("normal", new THREE.BufferAttribute(new Float32Array([ 
    0, 0, 1, 
    0, 0, 1, 
    0, 0, 1, 
    0, 0, 1 
]), 3)); 
planeGeo.setIndex(new THREE.BufferAttribute(new Float32Array([ 
    // triangle 1 
    0, 1, 2, 
    // triangle 2 
    3, 2, 1 
]), 1)); 

Beachten Sie, dass zwei der Vertex-Indizes zweimal verwendet werden, so dass wir nur eine Kopie des Vertex im Puffer position haben können.

Eine Sache zu beachten ist jedoch, dass Indizes auf Vertex/normale Paare funktionieren sollten. Vertices und Normalen haben keine diskrete Indizierung. Wenn also ein Vertex zwei Normalen hat, benötigen Sie immer noch eine zweite Kopie der Vertex-Werte im Puffer position.

Aber wie hilft Ihnen das? Nun, es geht nicht direkt. Was ich vorschlage, ist, dass Sie entweder OBJLoader ändern, um indizierte BufferGeometry Objekte zu erstellen (die parse Methode muss intelligenter gemacht werden, um korrekte Indizierung zu erstellen), oder schreiben Sie Ihre eigene komplett neue parse Funktion. Letzteres ist für Sie nützlicher, da Sie möglicherweise neue Loader erstellen müssen, um die anderen Dateiformate zu unterstützen, die Sie unterstützen möchten.

Verwandte Themen