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
- 1,965