WebGL / WebVR
for FrontEnd Engineer

3c557c6103a4addc52f7b76ffd0a0f27?s=47 yomotsu
February 25, 2017

WebGL / WebVR
for FrontEnd Engineer

3c557c6103a4addc52f7b76ffd0a0f27?s=128

yomotsu

February 25, 2017
Tweet

Transcript

  1. 4.
  2. 7.
  3. 9.
  4. 10.

    Pros • Strong and large community • Docs and examples

    • JS friendly easy APIs • Low level WebGL access Cons • Doesn't follow semver,
 Breaking changes sometime • Tricky garbage collection
  5. 11.
  6. 12.
  7. 13.
  8. 14.

    var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(

    60, width / height, 1, 1000 ); camera.position.set( 0, 0, 5 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize( width, height ); document.body.appendChild( renderer.domElement ); var light = new THREE.HemisphereLight( 0x443333, 0x332222, 2 ); scene.add( light ); var geometry = new THREE.SphereGeometry( 2, 2, 2 ); var material = new THREE.MeshPhongMaterial( { color: 0xff0000 } ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); renderer.render( scene, camera );
  9. 16.

    • Avoid unnecessary rendering • Reduce drawcalls • Avoid frequent

    texture uploading • Consider to use GPU • Compress 3D assets
  10. 20.
  11. 21.

    window.addEventListener( 'resize', function () { const width = window.innerWidth; const

    height = window.innerHeight; camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize( width, height );
 renderer.render( scene, camera ); // <- don't do this! } ); Re-rendering may unnecessary
  12. 22.

    ( function anim () { requestAnimationFrame( anim ); if (

    !myApp.needsUpdate ) { return; } renderer.render( scene, camera ); } )(); Pass re-rendering if unnecessary
  13. 23.

    var prevPosition = new THREE.Vector3(); var checkCameraPosition = function ()

    { if ( !approximatelyEqual( camera.position, prevPosition ) ) { myApp.needsUpdate = true; } prevPosition.copy( camera.position ); }; Checking “needsUpdate”
  14. 24.

    window.addEventListener( 'resize', function () { const width = window.innerWidth; const

    height = window.innerHeight; camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize( width, height );
 myApp.needsUpdate = true; // for next rAF } ); Checking “needsUpdate”
  15. 31.

    var houseGeometry = ...; var houseGeometry2 = ...;
 houseGeometry2.applyMatrix( new

    THREE.Matrix4().makeTranslation( -10, 0, 0 ) ); houseGeometry.merge( houseGeometry2 ); Merge geometries
  16. 33.
  17. 35.
  18. 36.
  19. 38.

    ( function anim () { var elapsed = clock.getElapsedTime(); requestAnimationFrame(

    anim ); texture.image = images[ frame ]; texture.needsUpdate = true; renderer.render( scene, camera ); frame = ( elapsed * 20 % images.length ) | 0; } )(); Bad: Replacing image
  20. 39.

    ( function anim () { var elapsed = clock.getElapsedTime(); requestAnimationFrame(

    anim ); texture.offset.set( frame % frameCol / frameCol, ( frameRow - 1 ) / frameRow - ( ( frame / frameCol ) | 0 ) / frameRow ); renderer.render( scene, camera ); frame = ( elapsed * 20 % frameLength ) | 0; } )(); Better: Use UV offset
  21. 40.
  22. 41.

    var rtt = new THREE.WebGLRenderTarget( 512, 512,
 { minFilter: THREE.LinearFilter,

    magFilter: THREE.NearestFilter, format: THREE.RGBFormat } ); renderer.render( sceneRTT, cameraRTT, rtt, true ); RTT
  23. 43.
  24. 45.

    requestAnimationFrame( anim ); for ( var i = 0, l

    = particleLength; i < l; i ++ ) { if ( geometry.attributes.position.array[ i * 3 + 1 ] > - boxHeight * 0.5 ) { geometry.attributes.position.array[ i * 3 + 1 ] -= delta; } else { geometry.attributes.position.array[ i * 3 + 1 ] = boxHeight * 0.5; } }; geometry.attributes.position.needsUpdate = true; Calc in CPU
  25. 46.

    uniform float time; uniform float height; uniform float scale; void

    main () { vec3 pos = vec3( position.x, position.y - time * 1.0, position.z ); pos.y = mod( pos.y, height ) - ( height * 0.5 ); vec4 mvPosition = modelViewMatrix * vec4( pos, 1.0 ); gl_Position = projectionMatrix * mvPosition; gl_PointSize = 1.0; } Calc in GPU (Shader)
  26. 51.
  27. 53.
  28. 56.

    • Contains multi files • Compressed One file • Arrows

    you to make
 a progressive bar • UnZip JS libs are
 available on GitHub
  29. 57.
  30. 58.
  31. 60.

    • Compressing lib for 3D assets • Developed by Google

    • Decompressor is available in JS
 (but 800kb emscripten) Might be still early…?
  32. 62.

    WebGL is… • Click, then it will open • No

    installing, but loading • Devices/Browsers are unspecified
  33. 63.

    • Write your code efficiently • CPU and GPU are

    separated • Compress 3D assets Conclusion
  34. 64.
  35. 68.

    Navigator.getVRDisplays() params and states •d[ i ].VREyeParameters •FOV •offset (eye

    transition) •d[ i ].getPose() •position •orientation (quaternion) and etc…
  36. 70.
  37. 71.
  38. 73.
  39. 74.

    ... mounted () { const scene = this.getScene(); scene.add( this.mesh

    ); }, beforeDestroy () { const scene = this.getScene(); // optional // this.mesh.material.map.dispose(); // this.mesh.geometry.dispose(); // this.mesh.material.dispose(); scene.remove( this.mesh ); },