Upgrade to Pro — share decks privately, control downloads, hide ads and more …

WebGL:
The graphics API
for web developers

3c557c6103a4addc52f7b76ffd0a0f27?s=47 yomotsu
June 18, 2015

WebGL:
The graphics API
for web developers

my slide at GREE Tech Talk #08 : WebGL http://techtalk.labs.gree.jp/08/

3c557c6103a4addc52f7b76ffd0a0f27?s=128

yomotsu

June 18, 2015
Tweet

Transcript

  1. WebGL:
 The graphics API
 for web developers Presented by Akihiro

    Oyamada (@yomotsu) Jun 18, 2015
  2. Frontend Engineer at PixelGrid, Inc. Akihiro Oyamada @yomotsu

  3. Limitations of the Web 3D

  4. 4 www.nike.com/gb/en_gb/c/nikeid

  5. 5 http://www2.asics.co.jp/baseball/3dorder

  6. 6 http://www2.asics.co.jp/io/help/help.html They also provide
 an installation guide…

  7. There were
 no graphics APIs
 for the Web

  8. The history
 of the web 3d

  9. None
  10. • A Web Standerd • A JavaScript feature • Great

    performance • Programable Shaders in GLSL
  11. Click a link,
 Just it will open!

  12. Maintained by Khronos Group, not W3C

  13. 13 http://caniuse.com/#feat=webgl

  14. Most of browsers support WebGL

  15. Hardware-
 accelerated

  16. None
  17. None
  18. vec3(-1, -1, 0) vec3( 1, -1, 0) vec3(-1, 1, 0)

    vec3(-1, 1, 0) vec3( 1, -1, 0) vec3( 1, 1, 0) ... 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 ✕ position matrix
  19. for ( var i = 0, l = position.length; i

    < l; i ++ ) { ! matrix.multiplyVector( position[ i ] ); ! }
  20. Scalar Operation SIMD Operation

  21. Scalar Operation SIMD Operation

  22. Scalar Operation SIMD Operation

  23. CPU GPU

  24. CPU GPU

  25. Super fast! because of the parallel processing

  26. • Tech definitions • Verbose initialization of WebGL • Shaders

    in GLSL • Math: Linear algebra, physics, etc… :PVTUJMMIBWFUPMFBSO
  27. three.js PIXI.js TWGL

  28. three.js

  29. 29 http://threejs.org/

  30. 30 http://threejs.org/docs/

  31. 31 http://www.apple.com/macbook/design/

  32. 32 https://www.ana-flightconnections.com/

  33. 33 https://www.ana-flightconnections.com/

  34. 34 http://fr.special-t.com/media/ogreen/en/

  35. 35 https://yomotsu.github.io/walkthrough

  36. make a scene

  37. make a camera

  38. add a light

  39. add an object

  40. http://localhost:8000/threejs/threejs_0_basic.html

  41. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>=^.^=</title> </head> <body> <script

    src="./lib/three.min.js"></script> <script> var width = window.innerWidth, height = window.innerHeight; ! var scene = new THREE.Scene(); ! var camera = new THREE.PerspectiveCamera( 40, width / height, 1, 1000 ); camera.position.set( 0, 0, 3 ); ! var renderer = new THREE.WebGLRenderer(); renderer.setSize( width, height ); document.body.appendChild( renderer.domElement ); !
  42. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>=^.^=</title> </head> <body> <script

    src="./lib/three.min.js"></script> <script> var width = window.innerWidth, height = window.innerHeight; ! var scene = new THREE.Scene(); ! var camera = new THREE.PerspectiveCamera( 40, width / height, 1, 1000 ); camera.position.set( 0, 0, 3 ); ! var renderer = new THREE.WebGLRenderer(); renderer.setSize( width, height ); document.body.appendChild( renderer.domElement ); ! load pixi.js
  43. <script> var width = window.innerWidth, height = window.innerHeight; ! var

    scene = new THREE.Scene(); ! var camera = new THREE.PerspectiveCamera( 40, width / height, 1, 1000 ); camera.position.set( 0, 0, 3 ); ! var renderer = new THREE.WebGLRenderer(); renderer.setSize( width, height ); document.body.appendChild( renderer.domElement ); ! var directionalLight = new THREE.DirectionalLight( 0xffffff ); directionalLight.position.set( 0, 1, 1 ).normalize(); scene.add( directionalLight ); ! var box = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ), new THREE.MeshPhongMaterial( { color: 0xff0000 } ) ); make a scene
  44. <script> var width = window.innerWidth, height = window.innerHeight; ! var

    scene = new THREE.Scene(); ! var camera = new THREE.PerspectiveCamera( 40, width / height, 1, 1000 ); camera.position.set( 0, 0, 3 ); ! var renderer = new THREE.WebGLRenderer(); renderer.setSize( width, height ); document.body.appendChild( renderer.domElement ); ! var directionalLight = new THREE.DirectionalLight( 0xffffff ); directionalLight.position.set( 0, 1, 1 ).normalize(); scene.add( directionalLight ); ! var box = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ), new THREE.MeshPhongMaterial( { color: 0xff0000 } ) ); make a camera
  45. var scene = new THREE.Scene(); ! var camera = new

    THREE.PerspectiveCamera( 40, width / height, 1, 1000 ); camera.position.set( 0, 0, 3 ); ! var renderer = new THREE.WebGLRenderer(); renderer.setSize( width, height ); document.body.appendChild( renderer.domElement ); ! var directionalLight = new THREE.DirectionalLight( 0xffffff ); directionalLight.position.set( 0, 1, 1 ).normalize(); scene.add( directionalLight ); ! var box = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ), new THREE.MeshPhongMaterial( { color: 0xff0000 } ) ); scene.add( box ); ! ( function renderLoop () { ! make a renderer
  46. ! var renderer = new THREE.WebGLRenderer(); renderer.setSize( width, height );

    document.body.appendChild( renderer.domElement ); ! var directionalLight = new THREE.DirectionalLight( 0xffffff ); directionalLight.position.set( 0, 1, 1 ).normalize(); scene.add( directionalLight ); ! var box = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ), new THREE.MeshPhongMaterial( { color: 0xff0000 } ) ); scene.add( box ); ! ( function renderLoop () { ! requestAnimationFrame( renderLoop ); box.rotation.y += 0.01; renderer.render( scene, camera ); ! make a light
  47. var directionalLight = new THREE.DirectionalLight( 0xffffff ); directionalLight.position.set( 0, 1,

    1 ).normalize(); scene.add( directionalLight ); ! var box = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ), new THREE.MeshPhongMaterial( { color: 0xff0000 } ) ); scene.add( box ); ! ( function renderLoop () { ! requestAnimationFrame( renderLoop ); box.rotation.y += 0.01; renderer.render( scene, camera ); ! } )(); </script> ! </body> </html> make an 3d object
  48. scene.add( directionalLight ); ! var box = new THREE.Mesh( new

    THREE.BoxGeometry( 1, 1, 1 ), new THREE.MeshPhongMaterial( { color: 0xff0000 } ) ); scene.add( box ); ! ( function renderLoop () { ! requestAnimationFrame( renderLoop ); box.rotation.y += 0.01; renderer.render( scene, camera ); ! } )(); </script> ! </body> </html> render it
  49. http://localhost:8000/threejs/threejs_0_basic.html

  50. 3D Models http://localhost:8000/threejs/threejs_1_3dmodel.html

  51. skeletal animation http://localhost:8000/threejs/threejs_2_animation.html

  52. events http://localhost:8000/threejs/threejs_3_event.html

  53. custom shader http://yomotsu.github.io/VolumetricFire/examples/example2.html

  54. • 3D model import • Animations • Math functions (

    such as vector and matrix ) • Build-in Shaders • Post processing effects and more!
  55. None
  56. 56 http://www.pixijs.com/

  57. 57 http://pixijs.github.io/docs/

  58. 58 http://www.html5gamedevs.com/forum/15-pixijs/

  59. 59 http://www.goodboydigital.com/runpixierun/

  60. 60 http://kaatje.ketnet.be/html/

  61. 61 http://www.wolverineunleashed.com/

  62. 62 http://archive.revolutionsinsound.com/#/explore/clubnights/bugged-out

  63. http://localhost:8000/pixijs/pixi_0_basic.html

  64. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>=^.^=</title> <style> body{margin: 0;}

    canvas{display: block;} </style> </head> <body> ! <script src="pixi.min.js"></script> ! <script> ! var renderer = new PIXI.autoDetectRenderer( 600, 400, { backgroundColor : 0xCCCCCC } ); document.body.appendChild( renderer.view ); !
  65. <style> body{margin: 0;} canvas{display: block;} </style> </head> <body> ! <script

    src="pixi.min.js"></script> ! <script> ! var renderer = new PIXI.autoDetectRenderer( 600, 400, { backgroundColor : 0xCCCCCC } ); document.body.appendChild( renderer.view ); ! var stage = new PIXI.Container(); ! var monster = new PIXI.Sprite.fromImage( 'monster.png' ); monster.position.set( 100, 50 ); stage.addChild( monster ); load pixi.js
  66. <script src="pixi.min.js"></script> ! <script> ! var renderer = new PIXI.autoDetectRenderer(

    600, 400, { backgroundColor : 0xCCCCCC } ); document.body.appendChild( renderer.view ); ! var stage = new PIXI.Container(); ! var monster = new PIXI.Sprite.fromImage( 'monster.png' ); monster.position.set( 100, 50 ); stage.addChild( monster ); ! var animate = ( function animate() { ! requestAnimationFrame( animate ); renderer.render( stage ); ! } )(); make a renderer
  67. backgroundColor : 0xCCCCCC } ); document.body.appendChild( renderer.view ); ! var

    stage = new PIXI.Container(); ! var monster = new PIXI.Sprite.fromImage( 'monster.png' ); monster.position.set( 100, 50 ); stage.addChild( monster ); ! var animate = ( function animate() { ! requestAnimationFrame( animate ); renderer.render( stage ); ! } )(); ! </script> ! </body> </html> make a container as a stage
  68. backgroundColor : 0xCCCCCC } ); document.body.appendChild( renderer.view ); ! var

    stage = new PIXI.Container(); ! var monster = new PIXI.Sprite.fromImage( 'monster.png' ); monster.position.set( 100, 50 ); stage.addChild( monster ); ! var animate = ( function animate() { ! requestAnimationFrame( animate ); renderer.render( stage ); ! } )(); ! </script> ! </body> </html> make a display object
  69. var stage = new PIXI.Container(); ! var monster = new

    PIXI.Sprite.fromImage( 'monster.png' ); monster.position.set( 100, 50 ); stage.addChild( monster ); ! var animate = ( function animate() { ! requestAnimationFrame( animate ); renderer.render( stage ); ! } )(); ! </script> ! </body> </html> render it
  70. http://localhost:8000/pixijs/pixi_0_basic.html

  71. filters http://localhost:8000/pixijs/pixi_1_blend.html

  72. sprite animations http://localhost:8000/pixijs/pixi_2_sprite.html

  73. events http://localhost:8000/pixijs/pixi_3_event.html

  74. shaders http://localhost:8000/pixijs/pixi_4_shader.html

  75. custom shaders http://localhost:8000/pixijs/pixi_5_shader2.html

  76. • Sprite and spine animations • Mouse and touch events

    • Pixel manipulation with WebGL • Custom shaders and more
  77. • Stage has been deprecated, now container • Name spaces

    has been changed • EventListener has been supported • Color matrix has been changed to 5x4 from 4x4 and many changes %JGGFSFODFTCFUXFFO7BOE7
  78. TWGL.js by the author of WebGL Fundamentals

  79. 79 http://twgljs.org/

  80. http://localhost:8000/twgljs/twgl_1.html

  81. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>=^.^=</title> <style> body{margin: 0;}

    canvas{display: block;} </style> </head> <body> ! <canvas id="canvas" width="512" height="512"></canvas> ! ! <script src="twgl-full.js"></script> <script> ! var canvas = document.getElementById( 'canvas' ); canvas.width = window.innerWidth; canvas.height = window.innerHeight;
  82. </head> <body> ! <canvas id="canvas" width="512" height="512"></canvas> ! ! <script

    src="twgl-full.js"></script> <script> ! var canvas = document.getElementById( 'canvas' ); canvas.width = window.innerWidth; canvas.height = window.innerHeight; ! var gl = twgl.getWebGLContext( canvas ); ! var vs = [ 'attribute vec3 position;', 'attribute vec2 texcoord;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', prepare a canvas
  83. </head> <body> ! <canvas id="canvas" width="512" height="512"></canvas> ! ! <script

    src="twgl-full.js"></script> <script> ! var canvas = document.getElementById( 'canvas' ); canvas.width = window.innerWidth; canvas.height = window.innerHeight; ! var gl = twgl.getWebGLContext( canvas ); ! var vs = [ 'attribute vec3 position;', 'attribute vec2 texcoord;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', load twgl.js
  84. ! <script src="twgl-full.js"></script> <script> ! var canvas = document.getElementById( 'canvas'

    ); canvas.width = window.innerWidth; canvas.height = window.innerHeight; ! var gl = twgl.getWebGLContext( canvas ); ! var vs = [ 'attribute vec3 position;', 'attribute vec2 texcoord;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', 'uniform mat4 modelMatrix;', 'varying vec2 vUv;', 'void main () {', get gl context
  85. ! var vs = [ 'attribute vec3 position;', 'attribute vec2

    texcoord;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', 'uniform mat4 modelMatrix;', 'varying vec2 vUv;', 'void main () {', 'gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0 );', 'vUv = texcoord;', ! '}' ].join( '\n' ); ! var fs = [ prepare VS source
  86. ].join( '\n' ); ! var fs = [ 'precision mediump

    float;', ! 'uniform sampler2D diffuse;', ! 'varying vec2 vUv;', ! 'void main () {', ! 'vec4 diffuseColor = texture2D( diffuse, vUv );', 'gl_FragColor = diffuseColor;', // 'gl_FragColor = vec4( 0, 0, 0, 1 );', ! '}' ].join( '\n' ); ! var programInfo = twgl.createProgramInfo( gl, [ vs, fs ] ); ! var arrays = { position: { prepare FS source
  87. ! '}' ].join( '\n' ); ! var programInfo = twgl.createProgramInfo(

    gl, [ vs, fs ] ); ! var arrays = { position: { numComponents: 3, data: [ -1, -1, 0, 1, -1, 0, -1, 1, 0, ! -1, 1, 0, 1, -1, 0, 1, 1, 0 ] }, indices: { numComponents: 3, data: [ compile those and
 create a program
  88. ! var arrays = { position: { numComponents: 3, data:

    [ -1, -1, 0, 1, -1, 0, -1, 1, 0, ! -1, 1, 0, 1, -1, 0, 1, 1, 0 ] }, indices: { numComponents: 3, data: [ 0, 1, 2, 3, 4, 5 ] }, prepare attributes
  89. }, indices: { numComponents: 3, data: [ 0, 1, 2,

    3, 4, 5 ] }, texcoord: { numComponents: 2, data: [ 0, 1, 1, 1, 0, 0, ! 0, 0, 1, 1, 1, 0 ] } }; !
  90. }; ! var bufferInfo = twgl.createBufferInfoFromArrays( gl, arrays ); !

    ! var projectionMatrix = twgl.m4.perspective( 30 * Math.PI / 180, gl.canvas.clientWidth / gl.canvas.clientHeight, 1, 1000 ); var viewMatrix = twgl.m4.translate( twgl.m4.identity(), [ 0, 0 ,-5 ] ); var modelMatrix = twgl.m4.rotationY( 1 ); ! ! var tex = twgl.createTexture( gl, { min: gl.NEAREST, mag: gl.NEAREST, src: './uv.png' }, function () {} ); ! make a buffer
  91. ! var projectionMatrix = twgl.m4.perspective( 30 * Math.PI / 180,

    gl.canvas.clientWidth / gl.canvas.clientHeight, 1, 1000 ); var viewMatrix = twgl.m4.translate( twgl.m4.identity(), [ 0, 0 ,-5 ] ); var modelMatrix = twgl.m4.rotationY( 1 ); ! ! var tex = twgl.createTexture( gl, { min: gl.NEAREST, mag: gl.NEAREST, src: './uv.png' }, function () {} ); ! var uniforms = { projectionMatrix: projectionMatrix, viewMatrix : viewMatrix, modelMatrix : modelMatrix, prepare unifroms
  92. }, function () {} ); ! var uniforms = {

    projectionMatrix: projectionMatrix, viewMatrix : viewMatrix, modelMatrix : modelMatrix, diffuse : tex }; ! var render = function ( time ) { ! twgl.resizeCanvasToDisplaySize( gl.canvas ); gl.viewport( 0, 0, gl.canvas.width, gl.canvas.height ); uniforms.modelMatrix = twgl.m4.rotationY( time * 0.001 ); ! gl.useProgram( programInfo.program ); twgl.setBuffersAndAttributes( gl, programInfo, bufferInfo ); twgl.setUniforms( programInfo, uniforms ); gl.drawElements( gl.TRIANGLES, bufferInfo.numElements, gl.UNSIGNED_SHORT, 0 ); !
  93. ! var render = function ( time ) { !

    twgl.resizeCanvasToDisplaySize( gl.canvas ); gl.viewport( 0, 0, gl.canvas.width, gl.canvas.height ); uniforms.modelMatrix = twgl.m4.rotationY( time * 0.001 ); ! gl.useProgram( programInfo.program ); twgl.setBuffersAndAttributes( gl, programInfo, bufferInfo ); twgl.setUniforms( programInfo, uniforms ); gl.drawElements( gl.TRIANGLES, bufferInfo.numElements, gl.UNSIGNED_SHORT, 0 ); ! requestAnimationFrame( render ); ! }; ! render( 0 ); ! </script> ! render it!
  94. http://localhost:8000/twgljs/twgl_1.html

  95. http://localhost:8000/twgljs/twgl_2.html

  96. • Less verbose initialization • Math functions That’s it!

  97. WebGL is not PS4

  98. • WebUI for 3D contents
 Still not exist a lot

    • Multiple devices
 High-End Gaming PC, Laptop, Mobile and others • Internet Connection 8IBUXFOFFEUPUIJOLBCPVU
  99. • Number of polygons
 esp. file size • Texture size

    • Resolution • Number of Draw-calls 8IBUXFOFFEUPDBSFBCPVU
  100. Like 3DS, PSP, PSVita FYI: Playable characters in FINAL FANTASY

    TYPE-0 consist of
 about 1000 tris and 76KB textures http://hexadrive.jp/lab/case/1573/
  101. Video games could be
 great knowledge

  102. None
  103. None
  104. WebVR

  105. d = navigator.
 getVRDevices()

  106. d = navigator.
 getVRDevices() •d[ i ].VRDevice (Type of the

    device) •d[ i ].VREyeParameters •FOV •eyeTranslation •d[ i ].VRPositionState •position •velocity •orientation •angularVelocity othres...
  107. vrHMD.getEyeTranslation( ‘left' ); vrHMD.getEyeTranslation( 'right' ); vrHMD.getRecommendedEyeFieldOfView( 'left' ); vrHMD.getRecommendedEyeFieldOfView(

    'right' );
  108. Chromium WebVR Builds Firefox Nightly Builds WebVR Oculus Rift Enabler

    as of Jun, 2015
  109. Virtuix Omni Locomotion HMD Cyberith Virtualizer OCULUS Rift SONY Morpheus

    HTC Vine • Leap Motion • PrioVR • Control VR • Sixense Stem • Razer Hydra Others
  110. 110 https://www.youtube.com/watch?v=aTtfAQEeAJI

  111. None
  112. Drop-in Phone
 Viewers

  113. Drop-in Phone
 Viewers • Different APIs
 (It will use DeviceOrientation

    API instead) • Limited performance
 (Stereo rendering on mobile device)
  114. Conclusion

  115. WebGL is
 a cross-platform,
 web standard, fast,
 powerful graphics API

  116. Several JS libraries
 are available
 for different purposes

  117. WebGL is still expanding WebGL2, WebVR and others

  118. gl.finish(); @yomotsu