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

Threedee Tales From Urban Bohemia

Threedee Tales From Urban Bohemia

An introduction to 3D graphics on the web using WebGL.

6804f1775cb4babfcc3851298566fbce?s=128

Vicent Martí

July 07, 2013
Tweet

Transcript

  1. None
  2. 3D is hard

  3. We’re building a videogame

  4. We’re building a videogame

  5. None
  6. None
  7. None
  8. (You are being a smartass)

  9. None
  10. WHAT?

  11. WebGL is A JavaScript API to render graphics accessing directly

    the GPU
  12. WebGL is not An API for 3D graphics

  13. WebGL is not An OpenGL Wrapper

  14. angle angle OpenGL ES 2.0 to DirectX 9 translation

  15. angle angle OpenGL ES 2.0 to DirectX 9 translation

  16. WHERE?

  17. None
  18. DIV

  19. CANVAS DIV

  20. WebGL context CANVAS “webgl” .getContext(“webgl”) WebGL context the

  21. WebGL context WebGL context(s) a b a.getContext(“webg b.getContext(“webg

  22. WHEN?

  23. DRAW DRAW DRAW DRAW DRAW DRAW DRAW DRAW Not when

    you want to
  24. When the browser tells you to.

  25. When the browser tells you to. requestAnimationFrame

  26. BRO WHAT ABOUT DOUBLE BUFFERING

  27. None
  28. Tearing

  29. Buffer A Buffer B

  30. Buffer A Buffer B

  31. Buffer A Buffer B

  32. JavaScript doesn’t execute while the DOM is being rendered!

  33. JavaScript doesn’t execute while the DOM is being rendered!

  34. HOW?

  35. Introducing... Jimmy the Vertex

  36. I’m not looking forward to this...

  37. (x, y, z)

  38. +x +y +z RIGHT HAND REPRESENT

  39. None
  40. None
  41. None
  42. Local Space

  43. World Space

  44. Camera Space

  45. Camera Space

  46. Screen Space

  47. xx xy xz Yx Yy Yz Zx Zy Zz {

    } World Space Local Space Model Matrix
  48. xx xy xz Yx Yy Yz Zx Zy Zz {

    } Camera Space World Space View Matrix
  49. xx xy xz Yx Yy Yz Zx Zy Zz {

    } Screen Space Camera Space Projection Matrix
  50. We could do the matrix operations in JavaScript

  51. We could do the matrix operations in JavaScript BUT WE

    DON’T
  52. SHADER is a program that runs on the GPU. SHADER

    a
  53. (THAT WAS EASY)

  54. N N It begins with an...

  55. OT JAVASCRIPT N N It begins with an...

  56. GLSL GLSL OpenGL Shader Language

  57. precision highp float; varying vec2 t; varying vec2 pos; uniform

    float time; uniform vec2 mouse; uniform int mouseLeft; uniform sampler2D tex0; void main() { float v1 = (sin(t.s+time) + 1.0) / 2.0; float v2 = (cos(t.t+time) + 1.0) / 2.0; float d = distance(mouse, pos); vec2 tt = vec2(t.s+sin(time/10.0), t.t+cos(time/10.0)); vec4 c1 = texture2D(tex0, tt) * 1.1; float avg = (c1.r+c1.g+c1.b)/3.0; float r = c1.r+v1*pow(avg,4.0) - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); float g = c1.g+v2*pow(avg,4.0) - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); float b = c1.g - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); gl_FragColor = vec4(r, g, b, 1.0); }
  58. precision highp float; varying vec2 t; varying vec2 pos; uniform

    float time; uniform vec2 mouse; uniform int mouseLeft; uniform sampler2D tex0; void main() { float v1 = (sin(t.s+time) + 1.0) / 2.0; float v2 = (cos(t.t+time) + 1.0) / 2.0; float d = distance(mouse, pos); vec2 tt = vec2(t.s+sin(time/10.0), t.t+cos(time/10.0)); vec4 c1 = texture2D(tex0, tt) * 1.1; float avg = (c1.r+c1.g+c1.b)/3.0; float r = c1.r+v1*pow(avg,4.0) - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); float g = c1.g+v2*pow(avg,4.0) - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); float b = c1.g - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); gl_FragColor = vec4(r, g, b, 1.0); } WELL THIS KINDA LOOKS LIKE JAVASCRIPT WELL THIS KINDA LOOKS LIKE JAVASCRIPT
  59. precision highp float; varying vec2 t; varying vec2 pos; uniform

    float time; uniform vec2 mouse; uniform int mouseLeft; uniform sampler2D tex0; void main() { float v1 = (sin(t.s+time) + 1.0) / 2.0; float v2 = (cos(t.t+time) + 1.0) / 2.0; float d = distance(mouse, pos); vec2 tt = vec2(t.s+sin(time/10.0), t.t+cos(time/10.0)); vec4 c1 = texture2D(tex0, tt) * 1.1; float avg = (c1.r+c1.g+c1.b)/3.0; float r = c1.r+v1*pow(avg,4.0) - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); float g = c1.g+v2*pow(avg,4.0) - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); float b = c1.g - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); gl_FragColor = vec4(r, g, b, 1.0); }
  60. precision highp float; varying vec2 t; varying vec2 pos; uniform

    float time; uniform vec2 mouse; uniform int mouseLeft; uniform sampler2D tex0; void main() { float v1 = (sin(t.s+time) + 1.0) / 2.0; float v2 = (cos(t.t+time) + 1.0) / 2.0; float d = distance(mouse, pos); vec2 tt = vec2(t.s+sin(time/10.0), t.t+cos(time/10.0)); vec4 c1 = texture2D(tex0, tt) * 1.1; float avg = (c1.r+c1.g+c1.b)/3.0; float r = c1.r+v1*pow(avg,4.0) - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); float g = c1.g+v2*pow(avg,4.0) - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); float b = c1.g - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); gl_FragColor = vec4(r, g, b, 1.0); } “
  61. precision highp float; varying vec2 t; varying vec2 pos; uniform

    float time; uniform vec2 mouse; uniform int mouseLeft; uniform sampler2D tex0; void main() { float v1 = (sin(t.s+time) + 1.0) / 2.0; float v2 = (cos(t.t+time) + 1.0) / 2.0; float d = distance(mouse, pos); vec2 tt = vec2(t.s+sin(time/10.0), t.t+cos(time/10.0)); vec4 c1 = texture2D(tex0, tt) * 1.1; float avg = (c1.r+c1.g+c1.b)/3.0; float r = c1.r+v1*pow(avg,4.0) - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); float g = c1.g+v2*pow(avg,4.0) - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); float b = c1.g - pow(d,pow(avg,2.0) +float(mouseLeft)*avg); gl_FragColor = vec4(r, g, b, 1.0); } <script id="fragment-shader" type="x-shader/x-fragment"> </script>
  62. document.getElementById document.getElementById

  63. GLSL GLSL GLSL compile compile compile link

  64. xx xy xz Yx Yy Yz Zx Zy Zz {

    } xx xy xz Yx Yy Yz Zx Zy Zz { } Perspective Matrix Model View Matrix
  65. attribute vec3 aVertexPosition; uniform mat4 uMVMatrix; uniform mat4 uPMatrix; void

    main(void) { gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); }
  66. attribute vec3 aVertexPosition; uniform mat4 uMVMatrix; uniform mat4 uPMatrix; void

    main(void) { gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); } Output
  67. attribute vec3 aVertexPosition; uniform mat4 uMVMatrix; uniform mat4 uPMatrix; void

    main(void) { gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); } Output Uniforms
  68. attribute vec3 aVertexPosition; uniform mat4 uMVMatrix; uniform mat4 uPMatrix; void

    main(void) { gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); } Output Uniforms Attribute
  69. None
  70. None
  71. xx xy xz Yx Yy Yz Zx Zy Zz {

    } xx xy xz Yx Yy Yz Zx Zy Zz { } Passing Uniforms var ptr = gl.getUniformLocation(shaderProgram, "uPMatrix") gl.uniformMatrix4fv( ptr, false, new Float32Array(vertexes));
  72. None
  73. -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0,

    1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, Here come the vertices
  74. -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0,

    1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, Here come the vertices
  75. -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0,

    1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, Here come the vertices
  76. -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0,

    1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, Here come the vertices
  77. -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0,

    1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, Here come the vertices
  78. cubeVertices = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertices); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER,

    cubeVertices); gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); 0,1,0 1,0,0 0,1,1 1,0,1 1,1,1 Passing Vertices
  79. cubeVertices = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertices); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER,

    cubeVertices); gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); 0,1,0 1,0,0 0,1,1 1,0,1 1,1,1 Passing Vertices
  80. xx xy xz Yx Yy Yz Zx Zy Zz {

    } xx xy xz Yx Yy Yz Zx Zy Zz { } Uniforms gl_Position 0,1,0 1,0,0 0,1,1 1,0,1 1,1,1 [aVertexPosition] drawArrays*
  81. xx xy xz Yx Yy Yz Zx Zy Zz {

    } xx xy xz Yx Yy Yz Zx Zy Zz { } Uniforms gl_Position 0,1,0 1,0,0 0,1,1 1,0,1 1,1,1 [aVertexPosition] drawArrays*
  82. xx xy xz Yx Yy Yz Zx Zy Zz {

    } xx xy xz Yx Yy Yz Zx Zy Zz { } Uniforms gl_Position 0,1,0 1,0,0 0,1,1 1,0,1 1,1,1 [aVertexPosition] drawArrays*
  83. xx xy xz Yx Yy Yz Zx Zy Zz {

    } xx xy xz Yx Yy Yz Zx Zy Zz { } Uniforms gl_Position 0,1,0 1,0,0 0,1,1 1,0,1 1,1,1 [aVertexPosition] drawArrays*
  84. xx xy xz Yx Yy Yz Zx Zy Zz {

    } xx xy xz Yx Yy Yz Zx Zy Zz { } Uniforms gl_Position 0,1,0 1,0,0 0,1,1 1,0,1 1,1,1 [aVertexPosition] drawArrays*
  85. Rasterization

  86. None
  87. None
  88. Fragments

  89. Fragment Shader varying lowp vec4 vColor; void main(void) { gl_FragColor

    = vColor; }
  90. Fragment Shader varying lowp vec4 vColor; void main(void) { gl_FragColor

    = vColor; } Output
  91. Fragment Shader varying lowp vec4 vColor; void main(void) { gl_FragColor

    = vColor; } Output Variant
  92. Variants Vertex Shader Fragment Shader

  93. None
  94. None
  95. Color

  96. Color Texture

  97. Color Texture Lighting

  98. Color Texture Lighting Specularity

  99. Color Texture Lighting Specularity Normal Mapping

  100. Color Texture Lighting Specularity Normal Mapping ...

  101. Clear Canvas Load Perspective M atrixes Load O bject M

    atrixes Render O bject
  102. None
  103. Three.js https://github.com/mrdoob/three.js A.K.A. use

  104. 3D is hard

  105. 3D is hard hard to understand

  106. 3D is hard hard to understand hard to learn

  107. Hard to get right

  108. But we need to try

  109. None
  110. twitter.com/vmg github.com/vmg

  111. With demos from: http://wagerfield.github.io/flat-surface-shader/ http://lab.aerotwist.com/webgl/surface/ http://www.mrdoob.com/lab/javascript/beachballs/ http://plumegraph.org/