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

Web3Dライブラリを作ってVue Custom Rendererの仕組みを理解しよう / l...

Web3Dライブラリを作ってVue Custom Rendererの仕組みを理解しよう / lets learn vue custom renderer by making 3d library

Vue Fes Japan 2026でLT登壇した資料です
https://vuefes.jp/2026/speaker/drumath2237

Avatar for にー兄さん

にー兄さん

October 24, 2026

More Decks by にー兄さん

Other Decks in Programming

Transcript

  1. にー兄さん ソフトウェアエンジニア@HoloLab inc. Babylon.js勉強会運営 Iwaken Lab. Microsoft MVP for Developer

    Technologies (2024~) 好きな技術 Babylon.js / WebXR Device API / Android XR / 3D Gaussian Splatting @ninisan_drumath @drumath2237 @drumath2237.bsky.social
  2. 3Dのシーンもヒエラルキ構造を成す 3Dのシーンにはカメラやライト、 メッシュやエフェクトなどが存在 オブジェクト同士は親子関係を構築できる (Web)3Dライブラリは 手続き的な処理によってこれを実現 Custom Rendererでラップすれば 宣言的に記述可能になりそう Babylon

    Liteによるシーン実装例 const engine = await createEngine(renderCanvas) const scene = createSceneContext(engine) const camera = createDefaultCamera(scene) attachControl(camera, renderCanvas, scene) const light = createDirectionalLight([1, -1, 1]) addToScene(scene, light) const box = createBox(engine, 1) const material = createStandardMaterial() box.material = material addToScene(scene, box) const sphere = createSphere(engine) sphere.parent = box await registerScene(scene) await startEngine(engine)
  3. createRenderer()でRendererの作成 createRenderer 関数の型定義 createRenderer<HostNode, HostElement>(options: RendererOptions<HostNode, HostElement>): Renderer<HostElement>; Rendererを作成してレンダー処理を開始 const

    renderer = createRenderer(nodeOps) アプリ全体で を使う場合 // Custom Renderer const app = renderer.createApp(rootComponent) createApp(app).mount('#app') 特定コンポーネントの を として扱う場合 // or slots Custom Renderer renderer.render(rootComponent, rootContainer)
  4. RendererOptionsの実装 createRenderer() が引数に 取るオプション 独自定義のElement/Nodeの動作を定 義するメインの部分 慣習的に nodeOps という名前で定義 される事が多い

    RendererOptionsの定義必須の関数たち const nodeOps: RendererOptions = { createElement(type, namespace, isCustomizedBuiltin, props) {...}, createComment(text) {...}, createText(text) {...}, insert(element, parentNode) {...}, nextSibling(node) {...}, parentNode(node) {...}, patchProp(element, key, prevValue, nextValue) {...}, remove(node) {...}, setElementText(node, text) {...}, setText(node, text) {...}, }
  5. 要素の作成フローと親子関係の構築(1/3) <SceneVue> <Box> <Material /> <Sphere> <Material /> </Sphere> <Box>

    <Material /> </Box> </Box> </SceneVue> 右のようなElementの構造になる
  6. 要素の作成フローと親子関係の構築(2/3) <SceneVue> <Box> <Material /> <Sphere> <Material /> </Sphere> <Box>

    <Material /> </Box> </Box> </SceneVue> createElement が呼ばれて Elementを作成しておく この時に親子関係などはいったん置いておき、オブ ジェクト単体を作成 ツリーが走査される過程で行きがけ順に呼ばれる
  7. 要素の作成フローと親子関係の構築(3/3) <SceneVue> <Box> <Material /> <Sphere> <Material /> </Sphere> <Box>

    <Material /> </Box> </Box> </SceneVue> Elementが作成されたら insert が呼ばれる parentのElementがわかるので、ここで親子関係を 構築すると良さそう ツリーが走査される過程で帰りがけ順に呼ばれる
  8. 実際のレンダリング結果 <SceneVue> <DirectionalLight :direction="vec3(-0.5, -1, 1)" /> <Box :position="vec3(0, 0.5,

    0)" :size="0.5"> <Material :color="{ r: 1, g: 0, b: 0 }" /> <Sphere :diameter="0.3" :position="vec3(0.5, 0, 0)"> <Material :color="{ r: 1, g: 1, b: 1 }" /> </Sphere> <Box :position="vec3(0, -0.5, 0)" :size="0.5"> <Material :color="{ r: 0, g: 0, b: 1 }" /> </Box> </Box> </SceneVue>
  9. 参考文献 Custom Renderer API https://vuejs.org/api/custom-renderer.html @vue/runtime-dom(github) https://github.com/vuejs/core/tree/main/packages/runtime-dom Building a Vue

    3 Custom Renderer(youtube) https://www.youtube.com/playlist?list=PLC2LZCNWKL9b876nPMVULEyBzkVoH8B7n vue-pdf-renderer-demo https://github.com/lmiller1990/vue-pdf-renderer-demo/tree/article-final