WebGL 3D mit HTML Canvas

Canvas mit 3D Animationen

3D-Modelle bestehen aus einer Szene, einer Kamera, aus dem dreidimensionalen Objekt und aus Licht. WebGL ist das Javascript API (Application Programming Interface) für 2d und 3D-Grafik in einem HTML-Canvas-Element.

WebGL wird von allen modernen Browsern unterstützt (Microsoft IE ab Version 11 – Internet Explorer muss man ja immer extra aufzählen).

three.js Javascript-Library für 3D-Anwendungen

three.js von threejs.org rendert WebGL, Canvas, SVG, CSS3D und DOM und bringt Szenen, Kameras, Geometrie, 3D-Modell-Importer, Licht, Materialien, Shader, Partikel, Animationen und eine Portion Mathe.

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js">
</script>
var scene = new THREE.Scene();
var aspect = document.querySelector(".dice").offsetWidth / document.querySelector(".dice").offsetHeight;
var camera = new THREE.PerspectiveCamera( 35, aspect, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( document.querySelector(".dice").offsetWidth, document.querySelector(".dice").offsetHeight );
renderer.setClearColor(0xffffff);
document.querySelector(".dice").appendChild( renderer.domElement );

Objekte einer 3D-Szene

Kamera

THREE.js hat verschiedene Kameras in Petto. Die perspektivische Kamera agiert ähnlich wie eine Kamera und agiert mit vier Argumenten.

cam = new THREE.PerspectiveCamera( fov, aspect, near, far )
  • Field of View (FOV) Sichtwinkel, ähnlich wie die Brennweite des Kameraobjektivs
  • Aspect Ratio beschreibt das Seitenverhältnis des erfassten Bildes
  • Near Clipping Plane – gedachte Ebene in Sichtrichtung der Kamera, hinter der Elemente gerendert werden
  • Far Clipping Plane – gedachte Ebene in Sichtrichtung der Kamera, bis zu der Elemente gerendert werden

Field of View (FOV) Brennweite der 3d-Kamera

Brennweite Objektv

Der Bildwinkel FOV der 3d-Kamera hat zwar dieselbe Wirkung wie die Brennweite des Kameraobjektivs, allerdings sind kleine Werte für FOV große Bildwinkel und große Werte stehen für einen großen Bildwinkel

Near Clipping Plane und Far Clipping Plane

Near Clipping Plane und Far Clipping Plance

Den Bereich zwischen Near und Far Clipping Plane könnte man mit der Schärfentiefe vergleichen, außer dass nur Elemente zwischen den Ebenen gerendert werden.

3D-Objekte und Mesh

3D-Objekte bestehen aus einer Geometrie – dem Polygon-Netz – und einem Oberflächen-Material.

THREE.BoxGeometry ( 1, 1, 1 ) ist ein fertiger Würfel mit den Längen der drei Kanten. THREE.js bringt einfache geometrische Objekte schon mit: Würfel, Zylinder, Kugeln, Ringe, Kegel.

var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshNormalMaterial();
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;

var render = function () {
  requestAnimationFrame( render );
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  renderer.render( scene, camera );
};

render();
material = new THREE.MeshLambertMaterial({ color: 0x9B9B9B, emissive: 0x050505, emissiveIntensity: 0.1 }); -->

Wenn es über die einfachen Geometrie-Körper hinaus geht, wäre das Erstellen von 3D-Modellen mit Javascript zu aufwändig. THREE.js importiert 3D-Modelle über Loader.

Für das 3D-Programm Blender gibt es z.B. einen Blender Export-Plugin, aber Blender 2.79 exportiert von Haus aus schon .obj, das sehr kompakt ist und direkt in Threejs geladen werden kann.

three.js/utils/converters/obj2three.js

Schöne Übersicht über Loader – die Module zum Laden von 3D-Modellen in THREEjs.

Licht

Studiofotografen und Kameramänner beim Film brauchen Lichtquellen: Ambientes Licht ist Umgebungslicht ohne Schattenbildung, daneben gerichtetes Licht für Schatten, Punkt-Lichtquellen und Strahler (Spot Light).

light = new THREE.DirectionalLight( 0xdddddd, 0.8 );
light.position.set( -80, 80, 80 );
light.target.position = 160;

Material

Ein breites Spektrum von Materialien liegt ebenfalls fertig zum Abholen: von einfachen stumpfen farbigen Oberflächen über fertig animierte Wasseroberflächen bis hin zum Handtuch im Wind.

var material = new THREE.MeshLambertMaterial({ ... });

oder 

var material = new THREE.MeshPhongMaterial({ ... });

Transformationen

mesh.position.x = -100;
mesh.scale.set(2,2,2);
mesh.rotation.y = Math.PI / 4; // Rotation um 45°
mesh.rotation.y = THREE.Math.degToRad(45);

Wie beim Canvas 2D wird der Kreis in Radiant beschrieben.

Kreis mit Einteilung in PI und Grad.

Das komplette Script für den Würfel

<div class="dice"></div>

<script src="/javascript/js/three.min.js"></script>
<script>
var scene = new THREE.Scene();
var aspect = document.querySelector(".dice").offsetWidth / document.querySelector(".dice").offsetHeight;
var camera = new THREE.PerspectiveCamera( 50, aspect, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( document.querySelector(".dice").offsetWidth, document.querySelector(".dice").offsetHeight );
renderer.setClearColor(0xffffff);
document.querySelector(".dice").appendChild( renderer.domElement );

var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshNormalMaterial();
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;

var render = function () {
  requestAnimationFrame( render );
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  renderer.render( scene, camera );
};

render();
</script>
WEBGL CANVAS 3D 15 30 90 150 RendererSzeneKameraMeshLichtGeometrieMaterialVertexFaceTexturBildObjekteder Szene yx(0,1)(1,0)(0,-1)(-1,0)Π2Π4444490°45°315°270°225°180°135°Π0 Vertex Vertex Vertex Vertex Edge / Kante Edge / Kante Edge / Kante Edge / Kante Face / Fläche Face Edge Vertex Vertex