Ce diaporama a bien été signalé.

HTML5 game dev with three.js - HexGL

17

Partager

Chargement dans…3
×
1 sur 64
1 sur 64

HTML5 game dev with three.js - HexGL

17

Partager

Télécharger pour lire hors ligne

These are the slides of my talk about HexGL at the Adobe User Group meetup in the Netherlands.

More info: http://bkcore.com/blog/general/adobe-user-group-nl-talk-video-hexgl.html

These are the slides of my talk about HexGL at the Adobe User Group meetup in the Netherlands.

More info: http://bkcore.com/blog/general/adobe-user-group-nl-talk-video-hexgl.html

Plus De Contenu Connexe

Livres audio associés

Gratuit avec un essai de 14 jours de Scribd

Tout voir

HTML5 game dev with three.js - HexGL

  1. 1. The making of HexGL
  2. 2. • Thibaut Despoulain (@bkcore – bkcore.com) • 22 year-old student in Computer Engineering • University of Technology of Belfort-Montbéliard (France) • Web dev and 3D enthousiast • The guy behind the HexGL project
  3. 3. • Fast-paced, futuristic racing game • Inspired by the F-Zero and Wipeout series • HTML5, JavaScript, WebGL (via Three.js) • Less than 2 months • Just me.
  4. 4. • JavaScript API • OpenGL ES 2.0 • Chrome, FireFox, (Opera, Safari) • <Canvas> (HTML5)
  5. 5. • Rendering engine • Maintained by Ricardo Cabello (MrDoob) and Altered Qualia • R50/stable • + : Active community, stable, updated frequently • - : Documentation
  6. 6. • First « real » game • 2 months to learn and code • Little to no modeling and texturing skills • Physics? Controls? Gameplay?
  7. 7. • Last time I could have 2 months free • Visibility to get an internship • Huge learning opportunity • Explore Three.js for good
  8. 8. • Third-party physics engine (rejected) – Slow learning curve – Not really meant for racing games
  9. 9. • Ray casting (rejected) – Heavy perfomance-wise – Needs Octree-like structure – > too much time to learn and implement
  10. 10. • Home-made 2D approximation – Little to no learning curve – Easy to implement with 2D maps – Pretty fast – > But with some limitations
  11. 11. • Home-made 2D approximation – No track overlap – Limited track twist and gradient – Accuracy depends on map resolution – > Enough for what I had in mind
  12. 12. • No pixel getter on JS Image object/tag • Canvas2D to the rescue
  13. 13. Load data Draw it on a Get canvas Drawing Getting Loading texture with JS Canvas using pixels using Image object 2D context getImageData()
  14. 14. • ImageData (BKcore package) – Github.com/Bkcore/bkcore-js var a = new bkcore.ImageData(path, callback); //… a.getPixel(x, y); a.getPixelBilinear(xf, yf); // -> {r, g, b, a};
  15. 15. Game loop: Convert world position to pixel indexes Get current pixel intensity (red) If pixel is not white: Collision Test pixels relatively (front, left, right) :end
  16. 16. Front Left Right Track Void
  17. 17. Front Front Current Gradient Left Right Left Right Height map Tilt
  18. 18. Model .OBJ Python Three.js Materials converter JSON model .MTL $ python convert_obj_three.py -i mesh.obj -o mesh.js
  19. 19. var scene = new THREE.Scene(); var loader = new THREE.JSONLoader(); var createMesh = function(geometry) { var mesh = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial()); mesh.position.set(0, 0, 0); mesh.scale.set(3, 3, 3); scene.add(mesh); }; loader.load("mesh.js", createMesh);
  20. 20. var renderer = new THREE.WebGLRenderer({ antialias: false, clearColor: 0x000000 }); renderer.autoClear = false; renderer.sortObjects = false; renderer.setSize(width, height); document.body.appendChild(renderer.domElement);
  21. 21. renderer.gammaInput = true; renderer.gammaOutput = true; renderer.shadowMapEnabled = true; renderer.shadowMapSoft = true;
  22. 22. • Blinn-phong – Diffuse + Specular + Normal + Environment maps • THREE.ShaderLib.normal – > Per vertex point lights • Custom shader with per-pixel point lights for the road – > Booster light
  23. 23. var boosterSprite = new THREE.Sprite( { map: spriteTexture, blending: THREE.AdditiveBlending, useScreenCoordinates: false, color: 0xffffff }); boosterSprite.mergeWith3D = false; boosterMesh.add(boosterSprite);
  24. 24. var material = new THREE.ParticleBasicMaterial({ color: 0xffffff, map: THREE.ImageUtils.loadTexture(“tex.png”), size: 4, blending: THREE.AdditiveBlending, depthTest: false, transparent: true, vertexColors: true, sizeAttenuation: true });
  25. 25. var pool = []; var geometry = new THREE.Geometry(); geometry.dynamic = true; for(var i = 0; i < 1000; ++i) { var p = new bkcore.Particle(); pool.push(p); geometry.vertices.push(p.position); geometry.colors.push(p.color); }
  26. 26. bkcore.Particle = function() { this.position = new THREE.Vector3(); this.velocity = new THREE.Vector3(); this.force = new THREE.Vector3(); this.color = new THREE.Color(0x000000); this.basecolor = new THREE.Color(0x000000); this.life = 0.0; this.available = true; }
  27. 27. var system = new THREE.ParticleSystem( geometry, material ); system.sort = false; system.position.set(x, y, z); system.rotation.set(a, b, c); scene.add(system);
  28. 28. // Particle physics var p = pool[i]; p.position.addSelf(p.velocity); //… geometry.verticesNeedUpdate = true; geometry.colorsNeedUpdate = true;
  29. 29. • Particles (BKcore package) – Github.com/BKcore/Three-extensions
  30. 30. var clouds = new bkcore.Particles({ opacity: 0.8, tint: 0xffffff, color: 0x666666, color2: 0xa4f1ff, texture: THREE.ImageUtils.loadTexture(“cloud.png”), blending: THREE.NormalBlending, size: 6, life: 60, max: 500, spawn: new THREE.Vector3(3, 3, 0), spawnRadius: new THREE.Vector3(1, 1, 2), velocity: new THREE.Vector3(0, 0, 4), randomness: new THREE.Vector3(5, 5, 1) });
  31. 31. scene.add(clouds); // Game loop clouds.emit(10); clouds.update(dt);
  32. 32. • Built-in support for off-screen passes • Already has some pre-made post effects – Bloom – FXAA • Easy to use and Extend • Custom shaders
  33. 33. var renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; var renderTarget = new THREE.WebGLRenderTarget( width, height, renderTargetParameters );
  34. 34. var composer = new THREE.EffectComposer( renderer, renderTarget ); composer.addPass( … ); composer.render();
  35. 35. • Generic passes – RenderPass – ShaderPass – SavePass – MaskPass • Pre-made passes – BloomPass – FilmPass – Etc.
  36. 36. var renderModel = new THREE.RenderPass( scene, camera ); renderModel.clear = false; composer.addPass(renderModel);
  37. 37. var effectBloom = new THREE.BloomPass( 0.8, // Strengh 25, // Kernel size 4, // Sigma 256 // Resolution ); composer.addPass(effectBloom);
  38. 38. var hexvignette: { uniforms: { tDiffuse: { type: "t", value: 0, texture: null }, tHex: { type: "t", value: 1, texture: null}, size: { type: "f", value: 512.0}, color: { type: "c", value: new THREE.Color(0x458ab1) } }, fragmentShader: [ "uniform float size;", "uniform vec3 color;", "uniform sampler2D tDiffuse;", "uniform sampler2D tHex;", "varying vec2 vUv;", "void main() { ... }" ].join("n") };
  39. 39. var effectHex = new THREE.ShaderPass(hexvignette); effectHex.uniforms['size'].value = 512.0; effectHex.uniforms['tHex'].texture = hexTexture; composer.addPass(effectHex); //… effectHex.renderToScreen = true;

×