0
The making of HexGL
• Thibaut Despoulain (@bkcore – bkcore.com)• 22 year-old student in Computer Engineering• University of Technology of Belf...
• Fast-paced, futuristic racing game• Inspired by the F-Zero and Wipeout series• HTML5, JavaScript, WebGL (via Three.js)• ...
• JavaScript API• OpenGL ES 2.0• Chrome, FireFox, (Opera, Safari)• <Canvas> (HTML5)
• Rendering engine• Maintained by Ricardo Cabello (MrDoob) and Altered Qualia• R50/stable• + : Active community, stable, u...
• First « real » game• 2 months to learn and code• Little to no modeling and texturing skills• Physics? Controls? Gameplay?
• Last time I could have 2 months free• Visibility to get an internship• Huge learning opportunity• Explore Three.js for g...
• Third-party physics engine (rejected)   – Slow learning curve   – Not really meant for racing games
• Ray casting (rejected)   – Heavy perfomance-wise   – Needs Octree-like structure   – > too much time to learn and implem...
• Home-made 2D approximation  – Little to no learning curve  – Easy to implement with 2D maps  – Pretty fast  – > But with...
• Home-made 2D approximation  – No track overlap  – Limited track twist and gradient  – Accuracy depends on map resolution...
• No pixel getter on JS Image object/tag• Canvas2D to the rescue
Load data                   Draw it on a             Get canvas                            Drawing                        ...
• ImageData (BKcore package)  – Github.com/Bkcore/bkcore-jsvar a = new bkcore.ImageData(path, callback);//…a.getPixel(x, y...
Game loop:  Convert world position to pixel indexes  Get current pixel intensity (red)  If pixel is not white:      Collis...
FrontLeft            RightTrack             Void
Front         Front                                               Current                                    GradientLeft ...
Model  .OBJ               Python               Three.jsMaterials           converter           JSON model .MTL $ python co...
var scene = new THREE.Scene();var loader = new THREE.JSONLoader();var createMesh = function(geometry){   var mesh = new TH...
var renderer = new THREE.WebGLRenderer({  antialias: false,  clearColor: 0x000000});renderer.autoClear = false;renderer.so...
renderer.gammaInput = true;renderer.gammaOutput = true;renderer.shadowMapEnabled = true;renderer.shadowMapSoft = true;
• Blinn-phong   – Diffuse + Specular + Normal + Environment maps• THREE.ShaderLib.normal   – > Per vertex point lights• Cu...
var boosterSprite = new THREE.Sprite({  map: spriteTexture,  blending: THREE.AdditiveBlending,  useScreenCoordinates: fals...
var material = new THREE.ParticleBasicMaterial({  color: 0xffffff,  map: THREE.ImageUtils.loadTexture(“tex.png”),  size: 4...
var pool = [];var geometry = new THREE.Geometry();geometry.dynamic = true;for(var i = 0; i < 1000; ++i){   var p = new bkc...
bkcore.Particle = function(){  this.position = new THREE.Vector3();  this.velocity = new THREE.Vector3();  this.force = ne...
var system = new THREE.ParticleSystem(   geometry,   material);system.sort = false;system.position.set(x, y, z);system.rot...
// Particle physicsvar p = pool[i];p.position.addSelf(p.velocity);//…geometry.verticesNeedUpdate = true;geometry.colorsNee...
• Particles (BKcore package)   – Github.com/BKcore/Three-extensions
var clouds = new bkcore.Particles({  opacity: 0.8,  tint: 0xffffff, color: 0x666666, color2: 0xa4f1ff,  texture: THREE.Ima...
scene.add(clouds);// Game loopclouds.emit(10);clouds.update(dt);
• Built-in support for off-screen passes• Already has some pre-made post effects   – Bloom   – FXAA• Easy to use and Exten...
var renderTargetParameters = {   minFilter: THREE.LinearFilter,   magFilter: THREE.LinearFilter,   format: THREE.RGBFormat...
var composer = new THREE.EffectComposer(   renderer,   renderTarget);composer.addPass( … );composer.render();
• Generic passes   –   RenderPass   –   ShaderPass   –   SavePass   –   MaskPass• Pre-made passes   – BloomPass   – FilmPa...
var renderModel = new THREE.RenderPass(   scene,   camera);renderModel.clear = false;composer.addPass(renderModel);
var effectBloom = new THREE.BloomPass(   0.8, // Strengh   25, // Kernel size   4, // Sigma   256 // Resolution);composer....
var hexvignette: {    uniforms: {          tDiffuse: { type: "t", value: 0, texture: null },          tHex: { type: "t", v...
var effectHex = new THREE.ShaderPass(hexvignette);effectHex.uniforms[size].value = 512.0;effectHex.uniforms[tHex].texture ...
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
Upcoming SlideShare
Loading in...5
×

HTML5 game dev with three.js - HexGL

7,270

Published on

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

Published in: Technology, Art & Photos
0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,270
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
82
Comments
0
Likes
10
Embeds 0
No embeds

No notes for slide

Transcript of "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 GettingLoading texture with JS Canvas using pixels using Image object 2D context getImageData()
  14. 14. • ImageData (BKcore package) – Github.com/Bkcore/bkcore-jsvar 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. FrontLeft RightTrack Void
  17. 17. Front Front Current GradientLeft Right Left Right Height map Tilt
  18. 18. Model .OBJ Python Three.jsMaterials 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 physicsvar 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 loopclouds.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;
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×