100 000 et un object WebGL / three.js
sli.do/1618



Prince of Persia - 1989

La cité idéale - 1465

Starfox - 1993

Metal Gear Solid - 1998
Uncharted 4 - 2016

@AnasAmeziane


anas@ozzo.io

Fondateur de ozzo.io
Anas AMEZIANE
Trading automatique et évolutif sur les marchés de cryptomonnaie




Architecture

WebGL

Browsers
WebGL est une API de pixellisation, pas une API 3D
The graphics pipeline
Vertex processing
Les "vertex" sont transformés à des positions sur l’écran

Primitive processing
Puis organisés et assemblés en primitives

Primitive processing

les primitives sont pixelisées en fragments
Fragment processing
les fragment sont transformés à des pixels colorés

Fragment processing
Les fragments sont mélangés dans le buffer d'image à leur emplacements de pixels

pipeline


Shader

Les shaders sont un ensemble d'instructions exécutées en une seule fois pour chaque pixel de l'écran.


CPU

GPU
<script id="vertex-shader" type="notjs">
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}
</script>
<script id="fragment-shader" type="notjs">
precision mediump float;
void main() {
gl_FragColor = vec4(1, 0, 0.5, 1);
}
</script>
GLSL
( openGL Shading Language)
webglfundamentals.org
thebookofshaders.com
WebGL libraries


Threejs
<!DOCTYPE html>
<html lang="en">
<head>
<title>Basic Three.js App</title>
<style>
html, body { margin: 0; padding: 0; overflow: hidden; }
</style>
</head>
<body>
<script src="js/three.min.js"></script>
<script>
// Javascript will go here.
</script>
</body>
</html>
var scene = new THREE.Scene();
var aspect = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera( 75, aspect, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.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.1;
cube.rotation.y += 0.1;
renderer.render( scene, camera );
};
render();

Scene

Camera




var camera = new THREE.PerspectiveCamera(
40, //fov
canvasWidth / canvasHeight, //aspect
0.1, //near
1000 //far
);
Perspective Camera
var viewSize = 900;
var aspectRatio = canvasWidth/canvasHeight;
var camera = new THREE.OrthographicCamera(
-aspectRatio * viewSize / 2, //left
aspectRatio * viewSize / 2, //right
viewSize / 2, //top
-viewSize / 2, //bottom
-1000, //near
1000 //far
);
Orthographic Camera


Diablo, Civilization and SimCity
Orthographic Camera
<script src="path/to/OrbitControls.js"></script>
controls = new THREE.OrbitControls( camera );
function render() {
requestAnimationFrame( render );
controls.update();
renderer.render( scene, camera );
}
Camera controls
https://threejs.org/examples/js/controls/OrbitControls.js
Mesh
Geometry + Material
Geometry

BoxBufferGeometry, BoxGeometry, ,CircleBufferGeometry, CircleGeometry, ConeBufferGeometry, ConeGeometry, CylinderBufferGeometry, CylinderGeometry, DodecahedronBufferGeometry, DodecahedronGeometry, EdgesGeometry, ExtrudeBufferGeometry, ExtrudeGeometry, IcosahedronBufferGeometry, IcosahedronGeometry, LatheBufferGeometry, LatheGeometry, OctahedronBufferGeometry, OctahedronGeometry, ParametricBufferGeometry, ParametricGeometry, PlaneBufferGeometry, PlaneGeometry, PolyhedronBufferGeometry, PolyhedronGeometry, RingBufferGeometry, RingGeometry, ShapeBufferGeometry, ShapeGeometry, SphereBufferGeometry, SphereGeometry, TetrahedronBufferGeometry, TetrahedronGeometry, TextBufferGeometry, TextGeometry, TorusBufferGeometry, TorusGeometry, TorusKnotBufferGeometry, TorusKnotGeometry, TubeBufferGeometry, TubeGeometry, WireframeGeometry
Cube
var geometry = new THREE.BoxGeometry(
1, //width
1, //height
1 //depth
);
var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
Sphere
var geometry = new THREE.SphereGeometry(
5, //radius
32, //widthSegments
32 //heightSegments
);
var material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
var sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );
BufferGeometry
var geometry = new THREE.BufferGeometry();
var vertices = new Float32Array( [
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0
]);
geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
var material = new THREE.PointsMaterial( { color: 0xff0000 } );
var mesh = new THREE.Points( geometry, material );
Material

MeshNormalMaterial
MeshNormalMaterial( parameters : Object )
MeshStandardMaterial
MeshStandardMaterial( parameters : Object )
MeshPhongMaterial
MeshPhongMaterial( parameters : Object )
PointsMaterial
let ozzoBotPointsMaterial = new THREE.PointsMaterial({
size: 8,
vertexColors: THREE.VertexColors,
map: new THREE.TextureLoader().load(CircleSprite),
});

Texture


+
=
http://planetpixelemporium.com/mars.html
Texture map
var PLANET_RADIUS = 1;
let planetMesh = new THREE.Mesh(
new THREE.SphereBufferGeometry(PLANET_RADIUS, 32, 32),
new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load('images/mars_4k_color.jpg')
})
);
Texture bump
var PLANET_RADIUS = 1;
var planetMesh = new THREE.Mesh(
new THREE.SphereBufferGeometry(PLANET_RADIUS, 32, 32),
new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load('images/mars_4k_color.jpg'),
bumpMap: new THREE.TextureLoader().load('images/mars_4k_bump.jpg'),
bumpScale: 0.05
})
);

Light & shadows
var light = new THREE.DirectionalLight( 0xdddddd, 0.8 );
light.position.set(5, 0, 5);
scene.add(light);
DirectionalLight
scene.add(new THREE.AmbientLight( 0x444444, 0.8));
AmbientLight
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
light.castShadow = true;
planetMesh.receiveShadow = true;
planetMesh.castShadow = true;
moonMesh.castShadow = true;
moonMesh.receiveShadow = true;
Shadow
var D_THETA = 0.005;
var theta = 0;
function animate() {
requestAnimationFrame( animate );
//rotate animation
planetMesh.rotation.y += (0.5*(Math.PI / 180)) % 360;
moonMesh.rotation.y += (0.5*(Math.PI / 180)) % 360;
//orbit animation
theta += D_THETA;
moonMesh.position.x = (PLANET_RADIUS + MOON_RADIUS + MOON_DISTANCE) * Math.cos(theta);
moonMesh.position.z = (PLANET_RADIUS + MOON_RADIUS + MOON_DISTANCE) * Math.sin(theta);
controls.update();
renderer.render( scene, camera );
}
Animation
threejs
By anas ameziane
threejs
- 2,117