Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Frontend Engineer at PixelGrid, Inc. Akihiro Oyamada @yomotsu

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

https://ff-wear.com/?template=2_59832150-1541043364

Slide 5

Slide 5 text

https://twitter.com/aniplex_plus/status/779261285783392256 http://yomotsu.net/blog/assets/2016-12-25-xmas/ Made with +

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Excuse: This topic is considered as
 Experimental

Slide 8

Slide 8 text

͝஫ҙɿ 
 ࢼͯ͠Έͨྫͷ঺հͰ͢ ʢϕετϓϥΫςΟεͰ͸͋Γ·ͤΜʣ

Slide 9

Slide 9 text

• High optimized rendering performances • Advanced effects with GLSL Filters beyond CSS • Yet Vue can handle UI, data and APIs Why with WebGL?

Slide 10

Slide 10 text

w ߴ଎ͳϨϯμϦϯάύϑΥʔϚϯε w $44Ͱ͸Ͱ͖ͳ͍ɺ
 (-4-ʹΑΔΞυόϯευͳඳըޮՌ w ͨͩ͠ɺ7VFͰ6*΍σʔλͷྲྀΕ͸࡞Δ ͳͥ8FC(-Ͱʁ

Slide 11

Slide 11 text

How?

Slide 12

Slide 12 text

Ͳ͏΍ͬͯʁ

Slide 13

Slide 13 text

Failure story…

Slide 14

Slide 14 text

ࣦഊஊʜ

Slide 15

Slide 15 text

• WebGL is async. 
 WebGL Rendering is not synced with DOM Rendering. • Made a pure class,
 independent of Vue. Separate WebGL and Vue…

Slide 16

Slide 16 text

w 8FC(-͸ඇಉظ
 8FC(-ͷϨϯμϦϯά͸
 %0.ϨϯμϦϯάͱ͸ผλΠϛϯά w 7VFʹґଘ͠ͳ͍ɺ
 ϐϡΞͳDMBTTΛ࡞ͬͨ 8FC(-ͱ7VFΛ੾Γ཭͢

Slide 17

Slide 17 text

Okay, I will separate them!

Slide 18

Slide 18 text

Α͠ɺ෼͚Α͏ʂ

Slide 19

Slide 19 text

• Same data in 2 places.
 (Vuex and the pure class) • Infinite loop in two-way binding.
 (Due to number precision in JS) • Unreadable code… Separate WebGL and Vue…

Slide 20

Slide 20 text

w ಉ͡σʔλ͕̎Օॴʹ
 ʢ7VFYͱ8FC(-༻ϐϡΞΫϥεʣ w ૒ํ޲όΠϯυͰແݶϧʔϓ
 ʢ+4ͷ਺஋ޡࠩͷృΓ߹͍ͳͲʣ w ಡΈͮΒ͍ίʔυ΁ʜ ෼͚ͨ݁Ռʜ

Slide 21

Slide 21 text

Solutions and Technics

Slide 22

Slide 22 text

ղܾྫ

Slide 23

Slide 23 text

less Component

Slide 24

Slide 24 text

͕ͳ͍ 
 ίϯϙʔωϯτ

Slide 25

Slide 25 text

Demo WebGL Canvas
 https://github.com/yomotsu/vue-webgl-non-dom-component-example 25

Slide 26

Slide 26 text

Slide 27

Slide 27 text

mounted() { this.glRender = this.glRender.bind( this ); this.renderer = new THREE.WebGLRenderer( { canvas: this.$el, stencil: false, alpha: true, } ); ……

Slide 28

Slide 28 text

• for • Init the WebGL Renderer at mounted • Destroy the Renderer at destroyed WebGL Canvas component

Slide 29

Slide 29 text

w DBOWBTͷΈͷUFNQMBUF w 8FC(-3FOEFSFSΛNPVOUFEͰॳظԽ w %FTUSPZ࣌ʹ8FC(-3FOEFSFSΛഇغ 8FC(-$BOWBTίϯϙʔωϯτ

Slide 30

Slide 30 text

Demo DisplayObjects 30

Slide 31

Slide 31 text

export default { name: ‘DisplayObject3D’, …… render() { // template がないので、 // 空の render を明示して // `Failed to mount component: template or render function not defined.` // のエラーを防ぐ } }

Slide 32

Slide 32 text

created() { var loader = new THREE.GLTFLoader(); loader.load( './vue.glb', ( gltf ) => { this.mesh = gltf.scene; this.mesh.userData.vuexId = this.id; this.mesh.traverse( ( obj ) => obj.userData.vuexId = this.id ); this.scene.add( this.mesh ); this.scene.add( this.transformControl ); this.transformControl.attach( this.mesh ); this.$emit( 'changed' ); } ...

Slide 33

Slide 33 text

• WebGL objects are not DOM. • is not needed. • But Vue props. Display Object components

Slide 34

Slide 34 text

w 8FC(-಺ΦϒδΣΫτ͸%0.Ͱ͸ͳ ͍ w UFNQMBUF͸ෆཁ w Ͱ΋1SPQT͸΄͍͠ දࣔΦϒδΣΫτίϯϙʔωϯτ

Slide 35

Slide 35 text

• omit • Void render • Init the component at created. • Dispose at destroyed. Display object components

Slide 36

Slide 36 text

w UFNQMBUF͸φγ w SFOEFS͸Կ΋ͤ͞ͳ͍ w DSFBUFEͰίϯϙʔωϯτΛॳظԽ w EFTUSPZFEͰഇغ දࣔΦϒδΣΫτίϯϙʔωϯτ

Slide 37

Slide 37 text

• WebGL root component listen events. • Then, WebGL render. • Doesn't rely on Virtual-DOM. Render them

Slide 38

Slide 38 text

w 8FC(-$BOWBTDPNQPOFOU͕
 ΠϕϯτΛ؂ࢹ w ΠϕϯτʹԠͯ͡8FC(-ͷϨϯμϦϯά w όʔνϟϧ%0.ʹ͸པΒͳ͍ Ϩϯμʔ͢Δ

Slide 39

Slide 39 text

{{ /* 必ず一意のkeyを入れる */ }}

Slide 40

Slide 40 text

methods: { glRender() { if ( this.willRender ) return; this.willRender = true; requestAnimationFrame( () => { if ( ! this.renderer ) return; this.renderer.render( this.scene, this.camera ); delete this.willRender; } ); }, …(snip)

Slide 41

Slide 41 text

Other points

Slide 42

Slide 42 text

ͦͷଞ
 ΍ͬͯΈͨ͜ͱ

Slide 43

Slide 43 text

• Avoid multiple update at the sometime. • Combine multiple props into one object. • “Watch” will be also merged into one. Use computed for combined-props

Slide 44

Slide 44 text

w ಉ࣌ෳ਺ճͷߋ৽Λճආ w QSPQTͷ૊Έ߹Θͤ͸DPNQVUFEͰҰͭʹ w ͜ΕʹΑΓɺ8BUDI΋Ϛʔδ͞ΕΔ ࠞ߹QSPQT͸DPNQVUFEͰ

Slide 45

Slide 45 text

watch: { positionX() { ... }, positionY() { ... },

Slide 46

Slide 46 text

watch: { transform() { ... },

Slide 47

Slide 47 text

computed: { transform() { return { positionX: this.positionX, positionY: this.positionY, positionZ: this.positionZ, } }

Slide 48

Slide 48 text

• Texture upload (from CPU to GPU) • Mesh upload • Rendering WebGL is async

Slide 49

Slide 49 text

• ςΫενϟͷΞοϓϩʔυ(CPU͔ΒGPU) • ϝογϡ৘ใͷΞοϓσʔτ • ϨϯμϦϯά WebGL͸ඇಉظલఏ

Slide 50

Slide 50 text

• DOM is easier to build UI • Since WebGL doesn’t make DOM,
 You cannot use DOM inspector. • (May makes more difficult to inspect.) Consider using DOM

Slide 51

Slide 51 text

w %0.ʹΑΔ6*ߏங͸؆୯ w 8FC(-͸%0.Λ࡞Βͳ͍ͷͰ
 %0.ΠϯεϖΫλʔ͕࢖͑ͳ͍ w ։ൃ͕େมʹͳΔ %0.͕࢖͑ͳ͍͔Λ࠶ݕ౼

Slide 52

Slide 52 text

• Mount can be done without • Init and $mount the component manually.
 (But it usually for testing.) Manual Mounting

Slide 53

Slide 53 text

• Mount can be done without • Init and $mount the component manually.
 (But it usually for testing.) खಈϚ΢ϯτ

Slide 54

Slide 54 text

Demo https://github.com/yomotsu/vue-webgl-non-dom-component-example 54

Slide 55

Slide 55 text

// CanvasComponent(親)内で、手動でマウントする const displayObject3D = new DisplayObject3d( { propsData: { id: object.id, positionX: object.positionX, positionY: object.positionY, …(snip) } } ); displayObject3D.$on( 'changed', () => { this.glRender(); } );

Slide 56

Slide 56 text

The new hope:
 Custom render
 comes with Vue 3

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

Conclusion

Slide 59

Slide 59 text

WebGL is just a tool
 not the purpose.

Slide 60

Slide 60 text

• less component
 could be a solution
 for None-DOM instances • Then, your data flow would be clearer

Slide 61

Slide 61 text

• DOMΛ࣋ͨͳ͍Πϯελϯεͷ
 ղܾࡦͱͯ͠ͷ
 Ϩείϯϙʔωϯτ • σʔλͷྲྀΕ͸ΑΓ໌֬ʹ

Slide 62

Slide 62 text

gl.finish(); @yomotsu All demos can be found:
 https://github.com/yomotsu/vue-webgl-non-dom-component-example