Reviving the Dream of the 90s with WebGL

Bfb8a1489a81ab3faf55860402abb58e?s=47 Billy Roh
October 04, 2019

Reviving the Dream of the 90s with WebGL

See demos on billyroh.com/screensavers.

The 90s were an exuberant time for technology. This is an attempt to bring back some of that energy by recreating 90s screensavers with WebGL and other modern web technologies.

Bfb8a1489a81ab3faf55860402abb58e?s=128

Billy Roh

October 04, 2019
Tweet

Transcript

  1. None
  2. Washington University Computer Science 2012 Facebook Product designer 2013 –

    2014 Opendoor Senior product designer 2014 – 2019
  3. $40,000 raised for non-profits through WaffleJS I helped start a

    creative coding monthly meetup called WaffleJS. We just had our 4-year anniversary!
  4. Grew up in the 90s in Vancouver, Canada

  5. None
  6. (Irrational?)

  7. None
  8. None
  9. None
  10. We have given up in exchange for .

  11. The transition between this and the thesis is a bit

    rough Beginning of modern computing (Windows)… 90s -> Windows => screensavers Pipes and maze Windows 95 screensavers
  12. None
  13. Recreated using WebGL, matrix math, asynchronous functions, HSL, SVG paths

    In-browser recreations
  14. None
  15. Windows 95 original

  16. Avoid intersections Matrix math Sequential rendering Asynchronous functions Generative palette

    HSL, material Dissolve and reset SVG paths
  17. Avoid intersections Matrix math Sequential rendering Asynchronous functions Generative palette

    HSL, material Dissolve and reset SVG paths
  18. 1. Generate matrix 2. Seed starting position and mark 3.

    Choose unoccupied position and mark 4. Repeat visitedMatrix pipePath 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  19. 1. Generate matrix 2. Seed starting position and mark 3.

    Choose unoccupied position and mark 4. Repeat pipeMatrix pipePath 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
  20. 1. Generate matrix 2. Seed starting position and mark 3.

    Choose unoccupied position and mark 4. Repeat pipeMatrix pipePath 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
  21. 1. Generate matrix 2. Seed starting position and mark 3.

    Choose unoccupied position and mark 4. Repeat pipeMatrix pipePath 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0
  22. 1. Generate matrix 2. Seed starting position and mark 3.

    Choose unoccupied position and mark 4. Repeat pipeMatrix pipePath 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 1 1
  23. 1. Generate matrix 2. Seed starting position and mark 3.

    Choose unoccupied position and mark 4. Repeat pipeMatrix pipePath 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 1 1 1
  24. 1. Generate matrix 2. Seed starting position and mark 3.

    Choose unoccupied position and mark 4. Repeat pipeMatrix pipePath 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 1 1 1
  25. 1. Generate matrix 2. Seed starting position and mark 3.

    Choose unoccupied position and mark 4. Repeat pipeMatrix pipePath 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 1 1 1 1
  26. 1. Generate matrix 2. Seed starting position and mark 3.

    Choose unoccupied position and mark 4. Repeat pipeMatrix pipePath 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
  27. Avoid intersections Matrix math Sequential rendering Asynchronous functions Generative palette

    HSL, material Dissolve and reset SVG paths
  28. None
  29. Iterate through pipePathArray to render each pipe

  30. …which immediately renders all the pipes at once

  31. Synchronous Everything gets rendered at once

  32. Promise chaining Endless chaining oh no

  33. Await/async Simpler, easier to understand

  34. None
  35. Wait between each drawPipe() Iterate through pipePath and wait until

    drawPath is complete in between each iteration
  36. Wait between each drawSegment() Iterate through pipePath and wait until

    drawPath is complete in between each iteration
  37. Draw and delay Draw a segment of the pipe and

    add a time delay
  38. Asynchronous Pipes get rendered sequentially

  39. Avoid intersections Matrix math Sequential rendering Asynchronous functions Generative palette

    HSL, material Dissolve and reset SVG paths
  40. Dynamically generate palette and use semi-shiny material Windows 95 original

  41. Teapot!

  42. Shiny material Material params Generative palette HSL Teapot External asset

  43. None
  44. Generate random colour Cap it to reasonable saturation and lightness

    values
  45. None
  46. Color Fog Metalness Opacity Texture Wireframe Emissive Roughness Material can

    affect dozens of things, such as…
  47. Default Metalness 0.3 Metalness 1.0

  48. Audio A-frame can load and cache external assets. Images 3D

    models
  49. None
  50. Load asset Set unique ID

  51. None
  52. Ensure only one teapot is rendered

  53. Reference unique ID from <a-asset-item>

  54. None
  55. Teapot!

  56. Avoid intersections Matrix math Sequential rendering Asynchronous functions Generative palette

    HSL, material Dissolve and reset SVG paths
  57. Fade out with small black squares then reset Windows 95

    original
  58. 1. Create grid from viewport 2. Randomly divide up grid

    into groups 3. Render each group as an SVG
  59. 1. Create grid from viewport 2. Randomly divide up grid

    into groups 3. Render each group as an SVG 2 1 3 4 1 1 2 1 3 3 4 2 1 2 1 2 1 4 4 1 3 1 2 3
  60. 1. Create grid from viewport 2. Randomly divide up grid

    into groups 3. Render each group as an SVG 2 1 3 4 1 1 2 1 3 3 4 2 1 2 1 2 1 4 4 1 3 1 2 3
  61. Render 1,000s of squares individually Cumbersome, slow to render <svg>

    <rect/> <rect/> <rect/> <!— and so on --> </svg>
  62. Render 100s of squares at once with <path> Easier to

    manage, faster to render <svg> <path/> </svg>
  63. Move Horizontal Vertical Z (Cloze?)

  64. Instantiate a string

  65. Use `M` to set the starting point

  66. Use `H` to draw a horizontal line

  67. Use `V` to draw a vertical line

  68. Use `H` to draw a horizontal line

  69. Use `Z` to close the shape

  70. Repeat for all squares in the array

  71. In-browser recreation

  72. Q: How might we make this more fun? A: More

    colours, interaction and
  73. None
  74. None
  75. None
  76. Windows 95 original

  77. Generate the maze Depth-first search Traverse the maze Depth-first search

    Dynamic entities A-frame look-at Dissolve and reset Animation params
  78. Generate the maze Depth-first search Traverse the maze Depth-first search

    Dynamic entities A-frame look-at Dissolve and reset Animation params
  79. Source: wolfesoftware.com/maze-generator/

  80. None
  81. Generate the maze Depth-first search Traverse the maze Depth-first search

    Dynamic entities A-frame look-at Dissolve and reset Animation params
  82. 1. Pick random starting position 2. Pick an accessible, unvisited

    position 3. Else, step backward
  83. 1. Pick random starting position 2. Pick an accessible, unvisited

    position 3. Else, step backward
  84. 1. Pick random starting position 2. Pick an accessible, unvisited

    position 3. Else, step backward
  85. 1. Pick random starting position 2. Pick an accessible, unvisited

    position 3. Else, step backward
  86. 1. Pick random starting position 2. Pick an accessible, unvisited

    position 3. Else, step backward
  87. 1. Pick random starting position 2. Pick an accessible, unvisited

    position 3. Else, step backward
  88. 1. Pick random starting position 2. Pick an accessible, unvisited

    position 3. Else, step backward
  89. In-browser recreation

  90. Generate the maze Depth-first search Traverse the maze Depth-first search

    Dynamic entities A-frame look-at Dissolve and reset Animation params
  91. Smiley face Stationary Resets maze Rat Traverses maze Has no

    effect Start button Spawns near camera Has no effect
  92. None
  93. Enumerate all positions in maze Shuffle array to randomize positions

  94. Pop a position off the array for each entity to

    prevent collisions
  95. In-browser recreation

  96. Notice how the start button faces you, no matter which

    way you face Windows 95 original
  97. aframe-look-at-component

  98. None
  99. In-browser recreation

  100. Generate the maze Depth-first search Traverse the maze Depth-first search

    Dynamic entities A-frame look-at Dissolve and reset Animation params
  101. Scale walls, start button, and smiley face up/down at the

    start/end Windows 95 original
  102. <a-entity animation=‘’ />

  103. Source: aframe.io/examples/showcase/animation/

  104. Property to animate e.g. position, scale, rotation Value to animate

    to Easing e.g. easeInOutQuad, easeInOutElastic Animation attribute Can add arbitrary characters after “animation”
  105. None
  106. Wrapper for entire maze

  107. Wrapper for thing that need to scale up/down Walls, smiley

    face, start button
  108. None
  109. Scale up wallWrapper along the y-axis

  110. None
  111. Scale down wallWrapper along the y-axis

  112. In-browser recreation

  113. Q: How might we make this more fun? A:

  114. None
  115. The Metropolitan Transportation Authority ran a six- month, $1 million

    trial of the “fertility management bait” in subways in 2013, and said in 2017 that it would expand to additional stations following “promising results.”
  116. None
  117. Q: How might we make this more fun? A:

  118. None
  119. None
  120. None
  121. None
  122. None
  123. (Irrational?)

  124. Reject the notion that must be bound to .

  125. None
  126. None