Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
WebGL / WebVR for FrontEnd Engineer
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
yomotsu
February 25, 2017
Technology
4.8k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
WebGL / WebVR for FrontEnd Engineer
yomotsu
February 25, 2017
More Decks by yomotsu
See All by yomotsu
three.jsとRapierでレースゲームが3日でできた話
yomotsu
0
870
PBR in three.js
yomotsu
1
1.2k
dialog要素でつくるモーダルダイアログ
yomotsu
0
1.1k
IE to Edge
yomotsu
1
400
A Camera Control Library for three.js
yomotsu
1
1.5k
Let’s try AR on mobile Web with <model-viewer>
yomotsu
0
600
WebXR: Beyond WebGL
yomotsu
2
1.9k
Non-DOM components with WebGL in Vue.js
yomotsu
5
13k
WebGL Libs for WebApp Frameworks
yomotsu
4
7.9k
Other Decks in Technology
See All in Technology
2026TECHFRESH畢業分享會 - 葬送的通靈師:化系統與用戶雜訊成行動訊號
line_developers_tw
PRO
0
990
Kiroで書いた 設計書 が AI レビューの 採点基準 になる
ezaki
0
110
手塩にかけりゃいいってもんじゃない
ming_ayami
0
570
20260619 私の日常業務での生成 AI 活用
masaruogura
1
200
Agent Skills設計で柔軟性と硬さのバランスが難しい話
nassy20
0
130
2026 TECHFRESH 畢業分享會 - 開發日常大解密!從領域驅動到企業級上線
line_developers_tw
PRO
0
990
【NRUG vol.18】なぜ多くのオブザーバビリティ導入は失敗するのか
nrug_member
0
130
気づかぬうちにセキュリティ負債を生むAPIキー運用
sgwrmctk
0
120
Claude Code の Sandbox 機能を Anthropic Sandbox Runtime(srt) で試そう!/lets-play-anthropic-sandbox-runtime
tomoki10
1
590
ACE-Step-1.5で見る 音楽生成AIのしくみと“破綻だけ直す”Retake機能の開発【zennfes spring 2026 登壇資料】
personabb
1
450
小さくはじめるSLI/SLO ~育てながら組織に定着させる実践知~ / Starting Small with SLI/SLOs: Building Adoption Through Continuous Growth
nari_ex
7
1.9k
LayerXにおけるセキュリティ管理の現在地と次の一手
tosho
0
180
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.3k
How GitHub (no longer) Works
holman
316
150k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
730
How to Think Like a Performance Engineer
csswizardry
28
2.6k
Building Adaptive Systems
keathley
44
3.1k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
250
How to train your dragon (web standard)
notwaldorf
97
6.7k
Everyday Curiosity
cassininazir
0
230
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
330
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
390
Designing for Performance
lara
611
70k
Navigating Team Friction
lara
192
16k
Transcript
WebGL / WebVR for FrontEnd Engineer Presented by Akihiro Oyamada
(@yomotsu) Feb 25, 2017
Frontend Engineer at PixelGrid, Inc. Akihiro Oyamada @yomotsu
I don’t talk about WebVR much… Disclaimer...
None
http://yomotsu.net/blog/assets/2016-12-25-xmas/ http://www.welcometofillory.com/ https://plus360degrees.com/uxcars/ http://www.playkeepout.com/
Almost native app looks! Cuz it works on top of
native graphic APIs
None
Sounds difficult? There are libraries!
None
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
None
None
None
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 );
let’s move onto the main topics for today
• Avoid unnecessary rendering • Reduce drawcalls • Avoid frequent
texture uploading • Consider to use GPU • Compress 3D assets
Avoid unnecessary rendering
Continuously re-rendering Better
demo 19 http://localhost:8000/1_re-rendering/bad.html http://localhost:8000/1_re-rendering/better.html
( function anim () { requestAnimationFrame( anim ); renderer.render( scene,
camera ); } )(); Re-rendering may unnecessary
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
( function anim () { requestAnimationFrame( anim ); if (
!myApp.needsUpdate ) { return; } renderer.render( scene, camera ); } )(); Pass re-rendering if unnecessary
var prevPosition = new THREE.Vector3(); var checkCameraPosition = function ()
{ if ( !approximatelyEqual( camera.position, prevPosition ) ) { myApp.needsUpdate = true; } prevPosition.copy( camera.position ); }; Checking “needsUpdate”
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”
Reduce drawcalls
Continuously repainting Better 8 drawcalls 1 drawcall
demo 27 http://localhost:8000/2_texture-atlas/1_house1.html http://localhost:8000/2_texture-atlas/2_house2.html
.FSHFNBUFSJBMT
3 drawcalls for 3 objects 1 drawcall 3 objects
demo 30 http://localhost:8000/2_texture-atlas/3_house-multi1.html http://localhost:8000/2_texture-atlas/4_house-multi2.html http://localhost:8000/2_texture-atlas/5_house-multi3.html
var houseGeometry = ...; var houseGeometry2 = ...; houseGeometry2.applyMatrix( new
THREE.Matrix4().makeTranslation( -10, 0, 0 ) ); houseGeometry.merge( houseGeometry2 ); Merge geometries
Avoid frequent texture uploading
None
demo 34 http://localhost:8000/3_spriteAnim/bad.html http://localhost:8000/3_spriteAnim/better.html
None
None
$16BOE(16 BSFQIZTJDBMMZTFQBSBUFE
( 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
( 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
None
var rtt = new THREE.WebGLRenderTarget( 512, 512, { minFilter: THREE.LinearFilter,
magFilter: THREE.NearestFilter, format: THREE.RGBFormat } ); renderer.render( sceneRTT, cameraRTT, rtt, true ); RTT
GPU may be utilised
None
demo 44 http://localhost:8000/4_particle/bad.html http://localhost:8000/4_particle/better.html
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
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)
Compress 3D assets
3D Model file consists of mostly numbers
3D scanned(ish) Model file
http://localhost:8000/5_compress/bad.html
None
Save 70% of size!
None
zip is an archive format
Multiple files in one zip file
• Contains multi files • Compressed One file • Arrows
you to make a progressive bar • UnZip JS libs are available on GitHub
None
None
https://opensource.googleblog.com/2017/01/introducing-draco-compression-for-3d.html As of Jan 13, 2017
• Compressing lib for 3D assets • Developed by Google
• Decompressor is available in JS (but 800kb emscripten) Might be still early…?
Conclusion
WebGL is… • Click, then it will open • No
installing, but loading • Devices/Browsers are unspecified
• Write your code efficiently • CPU and GPU are
separated • Compress 3D assets Conclusion
WebVR?
https://www.youtube.com/watch?v=cBvCS78ZC1c
https://w3c.github.io/webvr/
Navigator.getVRDisplays() params and states
Navigator.getVRDisplays() params and states •d[ i ].VREyeParameters •FOV •offset (eye
transition) •d[ i ].getPose() •position •orientation (quaternion) and etc…
WebVR is a small API!
None
None
One more thing
None
... 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 ); },
WebGL can be used with WebApp frameworks!
for FrontEnd Engineer Presented by Akihiro Oyamada (@yomotsu) Feb
25, 2017 WebGL / WebVR
three.js for FrontEnd Engineer Presented by Akihiro Oyamada (@yomotsu) Feb
25, 2017
gl.finish(); @yomotsu
Ξϯέʔτʹ ͝ڠྗ͍ͩ͘͞ http://bit.ly/2meQNnL gl.finish(); @yomotsu