HTML5 game dev with three.js - HexGL

The making of HexGL
• 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
HTML5 game dev with three.js - HexGL
• 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.
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
• JavaScript API

• OpenGL ES 2.0

• Chrome, FireFox, (Opera, Safari)

• <Canvas> (HTML5)
HTML5 game dev with three.js - HexGL
• Rendering engine
• Maintained by Ricardo Cabello (MrDoob) and Altered Qualia
• R50/stable

• + : Active community, stable, updated frequently

• - : Documentation
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
• 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 good
HTML5 game dev with three.js - HexGL
• 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 implement
• Home-made 2D approximation
  – Little to no learning curve

  – Easy to implement with 2D maps

  – Pretty fast

  – > But with some limitations
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
• Home-made 2D approximation
  – No track overlap

  – Limited track twist and gradient

  – Accuracy depends on map resolution

  – > Enough for what I had in mind
HTML5 game dev with three.js - HexGL
• No pixel getter on JS Image object/tag

• Canvas2D to the rescue
Load data                   Draw it on a             Get canvas


                            Drawing




                                                     Getting
Loading




          texture with JS             Canvas using             pixels using
          Image object                2D context               getImageData()
• 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};
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
Front


Left            Right




Track             Void
Front


         Front
                                               Current
                                    Gradient
Left                Right    Left



                                                Right
       Height map                     Tilt
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
Model
  .OBJ               Python               Three.js
Materials           converter           JSON model
 .MTL

 $ python convert_obj_three.py -i mesh.obj -o mesh.js
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);
HTML5 game dev with three.js - HexGL
var renderer = new THREE.WebGLRenderer({
  antialias: false,
  clearColor: 0x000000
});


renderer.autoClear = false;
renderer.sortObjects = false;
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
renderer.gammaInput = true;

renderer.gammaOutput = true;



renderer.shadowMapEnabled = true;

renderer.shadowMapSoft = true;
HTML5 game dev with three.js - HexGL
• 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
HTML5 game dev with three.js - HexGL
var boosterSprite = new THREE.Sprite(
{
  map: spriteTexture,
  blending: THREE.AdditiveBlending,
  useScreenCoordinates: false,
  color: 0xffffff
});

boosterSprite.mergeWith3D = false;
boosterMesh.add(boosterSprite);
HTML5 game dev with three.js - HexGL
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
});
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);
}
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;
}
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);
// Particle physics
var p = pool[i];
p.position.addSelf(p.velocity);
//…
geometry.verticesNeedUpdate = true;
geometry.colorsNeedUpdate = true;
• Particles (BKcore package)
   – Github.com/BKcore/Three-extensions
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)
});
scene.add(clouds);

// Game loop
clouds.emit(10);
clouds.update(dt);
HTML5 game dev with three.js - HexGL
• Built-in support for off-screen passes

• Already has some pre-made post effects
   – Bloom

   – FXAA

• Easy to use and Extend

• Custom shaders
var renderTargetParameters = {
   minFilter: THREE.LinearFilter,
   magFilter: THREE.LinearFilter,
   format: THREE.RGBFormat,
   stencilBuffer: false
};
var renderTarget = new THREE.WebGLRenderTarget(
   width, height,
   renderTargetParameters
);
var composer = new THREE.EffectComposer(
   renderer,
   renderTarget
);

composer.addPass( … );

composer.render();
• Generic passes
   –   RenderPass
   –   ShaderPass
   –   SavePass
   –   MaskPass

• Pre-made passes
   – BloomPass
   – FilmPass
   – Etc.
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.addPass(effectBloom);
HTML5 game dev with three.js - HexGL
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")
};
var effectHex = new THREE.ShaderPass(hexvignette);

effectHex.uniforms['size'].value = 512.0;
effectHex.uniforms['tHex'].texture = hexTexture;

composer.addPass(effectHex);

//…
effectHex.renderToScreen = true;
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
1 sur 64

Recommandé

WebGL and three.js - Web 3D Graphics par
WebGL and three.js - Web 3D Graphics WebGL and three.js - Web 3D Graphics
WebGL and three.js - Web 3D Graphics PSTechSerbia
3K vues26 diapositives
WebGL and three.js par
WebGL and three.jsWebGL and three.js
WebGL and three.jsAnton Narusberg
3.8K vues21 diapositives
From Hello World to the Interactive Web with Three.js: Workshop at FutureJS 2014 par
From Hello World to the Interactive Web with Three.js: Workshop at FutureJS 2014From Hello World to the Interactive Web with Three.js: Workshop at FutureJS 2014
From Hello World to the Interactive Web with Three.js: Workshop at FutureJS 2014Verold
2.7K vues64 diapositives
Introduction to three.js par
Introduction to three.jsIntroduction to three.js
Introduction to three.jsyuxiang21
424 vues17 diapositives
Intro to Three.js par
Intro to Three.jsIntro to Three.js
Intro to Three.jsKentucky JavaScript Users Group
2.6K vues9 diapositives
Creating Applications with WebGL and Three.js par
Creating Applications with WebGL and Three.jsCreating Applications with WebGL and Three.js
Creating Applications with WebGL and Three.jsFuture Insights
2.3K vues38 diapositives

Contenu connexe

Tendances

Introduction to three.js & Leap Motion par
Introduction to three.js & Leap MotionIntroduction to three.js & Leap Motion
Introduction to three.js & Leap MotionLee Trout
1.1K vues28 diapositives
ENEI16 - WebGL with Three.js par
ENEI16 - WebGL with Three.jsENEI16 - WebGL with Three.js
ENEI16 - WebGL with Three.jsJosé Ferrão
1.7K vues110 diapositives
Three.js basics par
Three.js basicsThree.js basics
Three.js basicsVasilika Klimova
2.9K vues69 diapositives
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ... par
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...Ontico
411 vues99 diapositives
3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ] par
3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]
3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]JavaScript Meetup HCMC
1.7K vues24 diapositives
Bs webgl소모임004 par
Bs webgl소모임004Bs webgl소모임004
Bs webgl소모임004Seonki Paik
1.2K vues32 diapositives

Tendances(20)

Introduction to three.js & Leap Motion par Lee Trout
Introduction to three.js & Leap MotionIntroduction to three.js & Leap Motion
Introduction to three.js & Leap Motion
Lee Trout1.1K vues
ENEI16 - WebGL with Three.js par José Ferrão
ENEI16 - WebGL with Three.jsENEI16 - WebGL with Three.js
ENEI16 - WebGL with Three.js
José Ferrão1.7K vues
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ... par Ontico
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...
Ontico411 vues
Bs webgl소모임004 par Seonki Paik
Bs webgl소모임004Bs webgl소모임004
Bs webgl소모임004
Seonki Paik1.2K vues
CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트 par YEONG-CHEON YOU
CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트
CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트
YEONG-CHEON YOU693 vues
HTML5 Canvas - Let's Draw! par Phil Reither
HTML5 Canvas - Let's Draw!HTML5 Canvas - Let's Draw!
HTML5 Canvas - Let's Draw!
Phil Reither3.3K vues
Cocos2dを使ったゲーム作成の事例 par Yuichi Higuchi
Cocos2dを使ったゲーム作成の事例Cocos2dを使ったゲーム作成の事例
Cocos2dを使ったゲーム作成の事例
Yuichi Higuchi3.7K vues
How to Hack a Road Trip with a Webcam, a GSP and Some Fun with Node par pdeschen
How to Hack a Road Trip  with a Webcam, a GSP and Some Fun with NodeHow to Hack a Road Trip  with a Webcam, a GSP and Some Fun with Node
How to Hack a Road Trip with a Webcam, a GSP and Some Fun with Node
pdeschen1.3K vues
Html5 canvas par Gary Yeh
Html5 canvasHtml5 canvas
Html5 canvas
Gary Yeh586 vues
Having fun with graphs, a short introduction to D3.js par Michael Hackstein
Having fun with graphs, a short introduction to D3.jsHaving fun with graphs, a short introduction to D3.js
Having fun with graphs, a short introduction to D3.js
Michael Hackstein2.2K vues
Begin three.js.key par Yi-Fan Liao
Begin three.js.keyBegin three.js.key
Begin three.js.key
Yi-Fan Liao9.5K vues

Similaire à HTML5 game dev with three.js - HexGL

Maps par
MapsMaps
Mapsboybuon205
554 vues37 diapositives
Gems of GameplayKit. UA Mobile 2017. par
Gems of GameplayKit. UA Mobile 2017.Gems of GameplayKit. UA Mobile 2017.
Gems of GameplayKit. UA Mobile 2017.UA Mobile
239 vues84 diapositives
Learning Predictive Modeling with TSA and Kaggle par
Learning Predictive Modeling with TSA and KaggleLearning Predictive Modeling with TSA and Kaggle
Learning Predictive Modeling with TSA and KaggleYvonne K. Matos
107 vues28 diapositives
Real life XNA par
Real life XNAReal life XNA
Real life XNAJohan Lindfors
597 vues48 diapositives
Exploring Canvas par
Exploring CanvasExploring Canvas
Exploring CanvasKevin Hoyt
1.7K vues55 diapositives
Intro to HTML5 Canvas par
Intro to HTML5 CanvasIntro to HTML5 Canvas
Intro to HTML5 CanvasJuho Vepsäläinen
2K vues32 diapositives

Similaire à HTML5 game dev with three.js - HexGL(20)

Gems of GameplayKit. UA Mobile 2017. par UA Mobile
Gems of GameplayKit. UA Mobile 2017.Gems of GameplayKit. UA Mobile 2017.
Gems of GameplayKit. UA Mobile 2017.
UA Mobile239 vues
Learning Predictive Modeling with TSA and Kaggle par Yvonne K. Matos
Learning Predictive Modeling with TSA and KaggleLearning Predictive Modeling with TSA and Kaggle
Learning Predictive Modeling with TSA and Kaggle
Yvonne K. Matos107 vues
Exploring Canvas par Kevin Hoyt
Exploring CanvasExploring Canvas
Exploring Canvas
Kevin Hoyt1.7K vues
The Ring programming language version 1.5.3 book - Part 48 of 184 par Mahmoud Samir Fayed
The Ring programming language version 1.5.3 book - Part 48 of 184The Ring programming language version 1.5.3 book - Part 48 of 184
The Ring programming language version 1.5.3 book - Part 48 of 184
The Ring programming language version 1.5.3 book - Part 58 of 184 par Mahmoud Samir Fayed
The Ring programming language version 1.5.3 book - Part 58 of 184The Ring programming language version 1.5.3 book - Part 58 of 184
The Ring programming language version 1.5.3 book - Part 58 of 184
Pointer Events in Canvas par deanhudson
Pointer Events in CanvasPointer Events in Canvas
Pointer Events in Canvas
deanhudson1.1K vues
Need an detailed analysis of what this code-model is doing- Thanks #St.pdf par actexerode
Need an detailed analysis of what this code-model is doing- Thanks #St.pdfNeed an detailed analysis of what this code-model is doing- Thanks #St.pdf
Need an detailed analysis of what this code-model is doing- Thanks #St.pdf
actexerode4 vues
Deep dive into deeplearn.js par Kai Sasaki
Deep dive into deeplearn.jsDeep dive into deeplearn.js
Deep dive into deeplearn.js
Kai Sasaki2.9K vues
Stupid Canvas Tricks par deanhudson
Stupid Canvas TricksStupid Canvas Tricks
Stupid Canvas Tricks
deanhudson9.5K vues
Html5 game programming overview par 민태 김
Html5 game programming overviewHtml5 game programming overview
Html5 game programming overview
민태 김1.9K vues
The Ring programming language version 1.3 book - Part 38 of 88 par Mahmoud Samir Fayed
The Ring programming language version 1.3 book - Part 38 of 88The Ring programming language version 1.3 book - Part 38 of 88
The Ring programming language version 1.3 book - Part 38 of 88
Bindings: the zen of montage par Kris Kowal
Bindings: the zen of montageBindings: the zen of montage
Bindings: the zen of montage
Kris Kowal808 vues
Can someone please explain what the code below is doing and comment on.pdf par kuldeepkumarapgsi
Can someone please explain what the code below is doing and comment on.pdfCan someone please explain what the code below is doing and comment on.pdf
Can someone please explain what the code below is doing and comment on.pdf
How to make a video game par dandylion13
How to make a video gameHow to make a video game
How to make a video game
dandylion13825 vues

Dernier

The Forbidden VPN Secrets.pdf par
The Forbidden VPN Secrets.pdfThe Forbidden VPN Secrets.pdf
The Forbidden VPN Secrets.pdfMariam Shaba
20 vues72 diapositives
Mini-Track: Challenges to Network Automation Adoption par
Mini-Track: Challenges to Network Automation AdoptionMini-Track: Challenges to Network Automation Adoption
Mini-Track: Challenges to Network Automation AdoptionNetwork Automation Forum
17 vues27 diapositives
SUPPLIER SOURCING.pptx par
SUPPLIER SOURCING.pptxSUPPLIER SOURCING.pptx
SUPPLIER SOURCING.pptxangelicacueva6
20 vues1 diapositive
STKI Israeli Market Study 2023 corrected forecast 2023_24 v3.pdf par
STKI Israeli Market Study 2023   corrected forecast 2023_24 v3.pdfSTKI Israeli Market Study 2023   corrected forecast 2023_24 v3.pdf
STKI Israeli Market Study 2023 corrected forecast 2023_24 v3.pdfDr. Jimmy Schwarzkopf
24 vues29 diapositives
Business Analyst Series 2023 - Week 3 Session 5 par
Business Analyst Series 2023 -  Week 3 Session 5Business Analyst Series 2023 -  Week 3 Session 5
Business Analyst Series 2023 - Week 3 Session 5DianaGray10
345 vues20 diapositives
Melek BEN MAHMOUD.pdf par
Melek BEN MAHMOUD.pdfMelek BEN MAHMOUD.pdf
Melek BEN MAHMOUD.pdfMelekBenMahmoud
17 vues1 diapositive

Dernier(20)

The Forbidden VPN Secrets.pdf par Mariam Shaba
The Forbidden VPN Secrets.pdfThe Forbidden VPN Secrets.pdf
The Forbidden VPN Secrets.pdf
Mariam Shaba20 vues
STKI Israeli Market Study 2023 corrected forecast 2023_24 v3.pdf par Dr. Jimmy Schwarzkopf
STKI Israeli Market Study 2023   corrected forecast 2023_24 v3.pdfSTKI Israeli Market Study 2023   corrected forecast 2023_24 v3.pdf
STKI Israeli Market Study 2023 corrected forecast 2023_24 v3.pdf
Business Analyst Series 2023 - Week 3 Session 5 par DianaGray10
Business Analyst Series 2023 -  Week 3 Session 5Business Analyst Series 2023 -  Week 3 Session 5
Business Analyst Series 2023 - Week 3 Session 5
DianaGray10345 vues
Webinar : Desperately Seeking Transformation - Part 2: Insights from leading... par The Digital Insurer
Webinar : Desperately Seeking Transformation - Part 2:  Insights from leading...Webinar : Desperately Seeking Transformation - Part 2:  Insights from leading...
Webinar : Desperately Seeking Transformation - Part 2: Insights from leading...
ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ... par Jasper Oosterveld
ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ...ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ...
ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ...
Unit 1_Lecture 2_Physical Design of IoT.pdf par StephenTec
Unit 1_Lecture 2_Physical Design of IoT.pdfUnit 1_Lecture 2_Physical Design of IoT.pdf
Unit 1_Lecture 2_Physical Design of IoT.pdf
StephenTec15 vues
2024: A Travel Odyssey The Role of Generative AI in the Tourism Universe par Simone Puorto
2024: A Travel Odyssey The Role of Generative AI in the Tourism Universe2024: A Travel Odyssey The Role of Generative AI in the Tourism Universe
2024: A Travel Odyssey The Role of Generative AI in the Tourism Universe
Simone Puorto13 vues
Igniting Next Level Productivity with AI-Infused Data Integration Workflows par Safe Software
Igniting Next Level Productivity with AI-Infused Data Integration Workflows Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Safe Software317 vues
PharoJS - Zürich Smalltalk Group Meetup November 2023 par Noury Bouraqadi
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023
Noury Bouraqadi139 vues
HTTP headers that make your website go faster - devs.gent November 2023 par Thijs Feryn
HTTP headers that make your website go faster - devs.gent November 2023HTTP headers that make your website go faster - devs.gent November 2023
HTTP headers that make your website go faster - devs.gent November 2023
Thijs Feryn26 vues
TouchLog: Finger Micro Gesture Recognition Using Photo-Reflective Sensors par sugiuralab
TouchLog: Finger Micro Gesture Recognition  Using Photo-Reflective SensorsTouchLog: Finger Micro Gesture Recognition  Using Photo-Reflective Sensors
TouchLog: Finger Micro Gesture Recognition Using Photo-Reflective Sensors
sugiuralab23 vues
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院 par IttrainingIttraining
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院

HTML5 game dev with three.js - HexGL

  • 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
  • 4. • 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.
  • 9. • JavaScript API • OpenGL ES 2.0 • Chrome, FireFox, (Opera, Safari) • <Canvas> (HTML5)
  • 11. • Rendering engine • Maintained by Ricardo Cabello (MrDoob) and Altered Qualia • R50/stable • + : Active community, stable, updated frequently • - : Documentation
  • 15. • First « real » game • 2 months to learn and code • Little to no modeling and texturing skills • Physics? Controls? Gameplay?
  • 16. • Last time I could have 2 months free • Visibility to get an internship • Huge learning opportunity • Explore Three.js for good
  • 18. • Third-party physics engine (rejected) – Slow learning curve – Not really meant for racing games
  • 19. • Ray casting (rejected) – Heavy perfomance-wise – Needs Octree-like structure – > too much time to learn and implement
  • 20. • Home-made 2D approximation – Little to no learning curve – Easy to implement with 2D maps – Pretty fast – > But with some limitations
  • 23. • Home-made 2D approximation – No track overlap – Limited track twist and gradient – Accuracy depends on map resolution – > Enough for what I had in mind
  • 25. • No pixel getter on JS Image object/tag • Canvas2D to the rescue
  • 26. Load data Draw it on a Get canvas Drawing Getting Loading texture with JS Canvas using pixels using Image object 2D context getImageData()
  • 27. • 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};
  • 28. 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
  • 29. Front Left Right Track Void
  • 30. Front Front Current Gradient Left Right Left Right Height map Tilt
  • 34. Model .OBJ Python Three.js Materials converter JSON model .MTL $ python convert_obj_three.py -i mesh.obj -o mesh.js
  • 35. 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);
  • 37. var renderer = new THREE.WebGLRenderer({ antialias: false, clearColor: 0x000000 }); renderer.autoClear = false; renderer.sortObjects = false; renderer.setSize(width, height); document.body.appendChild(renderer.domElement);
  • 38. renderer.gammaInput = true; renderer.gammaOutput = true; renderer.shadowMapEnabled = true; renderer.shadowMapSoft = true;
  • 40. • 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
  • 42. var boosterSprite = new THREE.Sprite( { map: spriteTexture, blending: THREE.AdditiveBlending, useScreenCoordinates: false, color: 0xffffff }); boosterSprite.mergeWith3D = false; boosterMesh.add(boosterSprite);
  • 44. 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 });
  • 45. 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); }
  • 46. 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; }
  • 47. 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);
  • 48. // Particle physics var p = pool[i]; p.position.addSelf(p.velocity); //… geometry.verticesNeedUpdate = true; geometry.colorsNeedUpdate = true;
  • 49. • Particles (BKcore package) – Github.com/BKcore/Three-extensions
  • 50. 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) });
  • 53. • Built-in support for off-screen passes • Already has some pre-made post effects – Bloom – FXAA • Easy to use and Extend • Custom shaders
  • 54. var renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; var renderTarget = new THREE.WebGLRenderTarget( width, height, renderTargetParameters );
  • 55. var composer = new THREE.EffectComposer( renderer, renderTarget ); composer.addPass( … ); composer.render();
  • 56. • Generic passes – RenderPass – ShaderPass – SavePass – MaskPass • Pre-made passes – BloomPass – FilmPass – Etc.
  • 57. var renderModel = new THREE.RenderPass( scene, camera ); renderModel.clear = false; composer.addPass(renderModel);
  • 58. var effectBloom = new THREE.BloomPass( 0.8, // Strengh 25, // Kernel size 4, // Sigma 256 // Resolution ); composer.addPass(effectBloom);
  • 60. 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") };
  • 61. var effectHex = new THREE.ShaderPass(hexvignette); effectHex.uniforms['size'].value = 512.0; effectHex.uniforms['tHex'].texture = hexTexture; composer.addPass(effectHex); //… effectHex.renderToScreen = true;