Laden von externen 3D-Objekten, einfache Maus-Interaktion und Beleuchtung

Wissen: 3D im Web Teil 2

Nachdem im ersten Teil ein einfaches Setup und das Rendern eines generischen Objekts gezeigt wurden, wird es im zweiten Teil um das Laden von externen 3D-Objekten, einfache Maus-Interaktion und Beleuchtung gehen.

Dafür laden wir uns ein 3D-Modell von sketchfab im glTF-Format (GL Transmission Format) herunter.

Bei diesem Format handelt es sich um ein lizenzfreies, komprimiertes Format zur effizienten Übertragung von 3D-Daten zwischen Anwendungen. Das Format wird in der Version 2 von fast allen gängigen 3D-Anwendungen unterstützt. Das heruntergeladene Modell beinhaltet einen Ordner mit Texturen textures der in das Projekt integriert werden muss.

Der obere Bereich des Setup-Codes ist bereits aus dem ersten Teil 1 bekannt und wird hier wiederverwendet:

 

/* main.js */

import * as THREE from 'https://cdn.skypack.dev/three';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75, // FOV (field of view) in Grad
window.innerWidth / window.innerHeight, // Verhältnis des render context
0.1, // near - Objekte mit einer kleineren Distanz als dieser Wert werden nicht angezeigt
1000 // far - Objekte mit einer größeren Distanz als dieser Wert werden nicht angezeigt
);

const renderer = new THREE.WebGLRenderer(); // ein von THREE.js erzeugtes  Element

renderer.setSize(window.innerWidth, window.innerHeight); // Größe des Canvas
document.body.appendChild(renderer.domElement);

scene.background = new THREE.Color( 0x1d1e20 ); //Setting the canvas background-color

 

 

Loader Setup

Um das 3D-Modell zu laden, wird ein Loader für das gewählte Dateiformat benötigt. Three.js bietet für unsere glTF-Datei den GLTFLoader, der am Beginn der Datei main.js importiert werden muss. Der Code zum Laden des 3D-Modells kann direkt aus der Three.js Dokumentation kopiert (die an dieser Stelle gelobt wird :ok_hand:) werden.

 

import { OBJLoader } from "https://cdn.skypack.dev/three@0.122.0/examples/jsm/loaders/OBJLoader.js";

/* ... Code von oben ... */

/*
Loader setup
----------------------*/
const loader = new GLTFLoader();

//Laden des glTF Modells
loader.load(
"src/model/scene.gltf", function (gltf) {
scene.add(gltf.scene);
},

// called while loading is progressing
function (xhr) {
    console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
},

// called when loading has errors
function (error) {
    console.log("An error happened");
}
);

 

 

Light Setup

Nach dem Neuladen sollte nun das 3D-Modell im Canvas gerendert werden. Da noch keine Lichter eingefügt wurden, sieht die ganze Szene noch sehr dunkel aus. Um das zu ändern, fügen wir der Szene ein PointLight hinzu. Das PointLight erhält 3 Argumente:

  • Color - Farbe des Lichts
  • Intensity - Helligkeit (default ist 1)
  • Decay - Abnahme der Licht-Intensität über die Distanz
/*
Light setup
----------------------*/
const pointLight = new THREE.PointLight(0xffffcc, 2, 10); // (color, intensity, decay)

pointLight.position.set(0, 10, 0);
pointLight.castShadow = true;
pointLight.shadow.camera.near = 1;
pointLight.shadow.camera.far = 60;
pointLight.shadow.bias = -0.005;

scene.add(pointLight);

 

Das sieht schon besser aus!

Um nun das Wasser besser in Szene zu setzen, fügen wir noch ein AmbientLight hinzu. Ähnlich wie bei dem PointLight kann auch das AmbientLight über Argumente konfiguriert werden:

  • Color - Farbe des Lichts
  • Intensity - Helligkeit des Lichts (default ist 1)
const ambientLight = new THREE.AmbientLight(0xcccccc, 0.6);

scene.add(ambientLight);

 

Beim Hinzufügen von Lichtern ist es oftmals notwendig die Position zu korrigieren. Three.js bietet eine Helfer-Funktion für alle vorhanden Lichtklassen, die diese Aufgabe erleichtert:

 

const sphereSize = 1;
const pointLightHelper = new THREE.PointLightHelper(pointLight, sphereSize);

scene.add(pointLightHelper);

 

Hinweis: Die sphereSize bestimmt die Größe des Helfer-Objekts.

Jetzt ist die Szene gut ausgeleuchtet!

 

Control Setup

Um mit dem 3D-Modell zu interagieren, z.B. drehen und zoomen, werden die sogenannten OrbitControls importiert. Das Verhalten dieser Steuerungselemente kann einfach konfiguriert werden. So kann z.B. die Zoom-Distanz eingeschränkt werden, der damping-Wert lässt die Bewegung langsam zu Ende laufen. Das ganze muss dann noch im render-Loop in jedem Frame abgefragt werden via <code>controls.update()</code>

 

import { OrbitControls } from "https://cdn.skypack.dev/three@0.122.0/examples/jsm/controls/OrbitControls.js";
/*
Control Setup
----------------------*/
const controls = new OrbitControls(camera, renderer.domElement);

controls.minDistance = 50;
controls.maxDistance = 150;
controls.enableDamping = true;

/*
Render Loop
----------------------*/
function draw() {
    requestAnimationFrame(draw);
    renderer.render(scene, camera);
    controls.update();
}

draw();

 

Et voilà! Wir haben ein externes 3D-Modell mit Hilfe eines Loaders in den Canvas geladen und die Szene ausgeleuchtet. Dann haben wir dem Benutzer noch eine Interaktions-Möglichkeit via OrbitControls gegeben.

 

Im dritten Teil werden wir die Interaktivität erweitern und direkt mit dem Modell interagieren. Der finale Code dieses Artikels ist wieder auf codepen:

 

 

Daniel Tofaute

Webentwickler bei eyeworkers
kontakt@eyeworkers.de
+ 49 721 183960