100 000 et un object WebGL / three.js
sli.do/1618
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6137211/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6146477/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6146468/pasted-from-clipboard.png)
Prince of Persia - 1989
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6146254/pasted-from-clipboard.png)
La cité idéale - 1465
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6146226/pasted-from-clipboard.png)
Starfox - 1993
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6147623/pasted-from-clipboard.png)
Metal Gear Solid - 1998
Uncharted 4 - 2016
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6147697/pasted-from-clipboard.png)
@AnasAmeziane
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6136948/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6136955/pasted-from-clipboard.png)
anas@ozzo.io
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6136961/pasted-from-clipboard.png)
Fondateur de ozzo.io
Anas AMEZIANE
Trading automatique et évolutif sur les marchés de cryptomonnaie
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6137131/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6151274/ozzo-product.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6140691/ozzo-screen.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6125757/boite-de-petr.jpg)
Architecture
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6151370/ozzo-archi-general.png)
WebGL
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6130577/pasted-from-clipboard.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6155473/pasted-from-clipboard.png)
Primitive processing
Puis organisés et assemblés en primitives
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6155484/pasted-from-clipboard.png)
Primitive processing
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6155437/pasted-from-clipboard.png)
les primitives sont pixelisées en fragments
Fragment processing
les fragment sont transformés à des pixels colorés
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6155558/pasted-from-clipboard.png)
Fragment processing
Les fragments sont mélangés dans le buffer d'image à leur emplacements de pixels
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6155596/pasted-from-clipboard.png)
pipeline
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6155622/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6130597/pasted-from-clipboard.png)
Shader
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6125952/gutenpress.jpg)
Les shaders sont un ensemble d'instructions exécutées en une seule fois pour chaque pixel de l'écran.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6126086/typepress.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6155690/pasted-from-clipboard.png)
CPU
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6155692/pasted-from-clipboard.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6151485/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6151490/pasted-from-clipboard.png)
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();
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6141407/pasted-from-clipboard.png)
Scene
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6140845/pasted-from-clipboard.png)
Camera
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6141491/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6140742/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6140828/camera-threejs.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6135942/perspective-ecran.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6141015/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6140909/pasted-from-clipboard.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6142301/pasted-from-clipboard.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6155817/pasted-from-clipboard.png)
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),
});
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6145063/pasted-from-clipboard.png)
Texture
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6145116/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6145118/pasted-from-clipboard.png)
+
=
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
})
);
![](https://s3.amazonaws.com/media-p.slid.es/uploads/530786/images/6145184/Bump_map_vs_isosurface2.png)
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
- 1,851