[{"data":1,"prerenderedAt":604},["ShallowReactive",2],{"navigation":3,"/essentials/core-architecture/custom-vue-renderer":239,"/essentials/core-architecture/custom-vue-renderer-surround":599},[4,29,78,173,205,215,219,223,227,231,235],{"title":5,"path":6,"stem":7,"children":8,"icon":27,"titleTemplate":28},"Getting Started","/getting-started","1.getting-started/1.index",[9,12,17,22],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Installation","/getting-started/installation","1.getting-started/2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Your First Scene","/getting-started/your-first-scene","1.getting-started/3.your-first-scene","i-lucide-donut",{"title":23,"path":24,"stem":25,"icon":26},"Upgrade Guide","/getting-started/upgrade-guide","1.getting-started/4.upgrade-guide","i-lucide-circle-arrow-up","i-lucide-rocket","%s · Get Started with TresJS",{"title":30,"path":31,"stem":32,"children":33},"Essentials","/essentials","2.essentials",[34,36,48],{"title":30,"path":31,"stem":35},"2.essentials/index",{"title":37,"icon":38,"open":39,"path":40,"stem":41,"children":42,"page":47},"Core Architecture","i-lucide-cpu",true,"/essentials/core-architecture","2.essentials/1.core-architecture",[43],{"title":44,"path":45,"stem":46},"Custom Vue Renderer","/essentials/core-architecture/custom-vue-renderer","2.essentials/1.core-architecture/2.custom-vue-renderer",false,{"title":49,"icon":50,"open":39,"path":51,"stem":52,"children":53,"page":47},"Key Concepts","i-lucide-medal","/essentials/concepts","2.essentials/2.concepts",[54,58,62,66,70,74],{"title":55,"path":56,"stem":57},"Declarative vs Imperative","/essentials/concepts/declarative-vs-imperative","2.essentials/2.concepts/1.declarative-vs-imperative",{"title":59,"path":60,"stem":61},"Reactivity","/essentials/concepts/reactivity","2.essentials/2.concepts/2.reactivity",{"title":63,"path":64,"stem":65},"Constructor Arguments","/essentials/concepts/constructor-arguments","2.essentials/2.concepts/3.constructor-arguments",{"title":67,"path":68,"stem":69},"Declarative Properties","/essentials/concepts/declarative-properties","2.essentials/2.concepts/4.declarative-properties",{"title":71,"path":72,"stem":73},"Extending the Catalogue","/essentials/concepts/extending-catalogue","2.essentials/2.concepts/5.extending-catalogue",{"title":75,"path":76,"stem":77},"Child Attachments","/essentials/concepts/child-attachments","2.essentials/2.concepts/6.child-attachments",{"title":79,"path":80,"stem":81,"children":82},"API","/api","3.api",[83,86,104,131,141,155],{"title":84,"path":80,"stem":85},"TresJS API Reference","3.api/1.index",{"title":87,"icon":88,"open":39,"path":89,"stem":90,"children":91,"page":47},"Components","i-lucide-box","/api/components","3.api/1.components",[92,96,100],{"title":93,"path":94,"stem":95},"\u003CTresCanvas />","/api/components/tres-canvas","3.api/1.components/tres-canvas",{"title":97,"path":98,"stem":99},"\u003CTresCanvasContext />","/api/components/tres-context","3.api/1.components/tres-context",{"title":101,"path":102,"stem":103},"Tres Components","/api/components/tres-objects","3.api/1.components/tres-objects",{"title":105,"titleTemplate":106,"icon":107,"path":108,"stem":109,"children":110,"page":47},"Composables","%s · TresJS Composables","i-lucide-arrow-right-left","/api/composables","3.api/2.composables",[111,115,119,123,127],{"title":112,"path":113,"stem":114},"useTres","/api/composables/use-tres","3.api/2.composables/1.use-tres",{"title":116,"path":117,"stem":118},"useTresContext","/api/composables/use-tres-context","3.api/2.composables/2.use-tres-context",{"title":120,"path":121,"stem":122},"useLoop","/api/composables/use-loop","3.api/2.composables/3.use-loop",{"title":124,"path":125,"stem":126},"useGraph","/api/composables/use-graph","3.api/2.composables/4.use-graph",{"title":128,"path":129,"stem":130},"useLoader","/api/composables/use-loader","3.api/2.composables/5.use-loader",{"title":132,"icon":133,"path":134,"stem":135,"children":136,"page":47},"Event handling","i-lucide-mouse-pointer-2","/api/events","3.api/3.events",[137],{"title":138,"path":139,"stem":140},"Pointer Events","/api/events/pointer-events","3.api/3.events/1.pointer-events",{"title":142,"icon":143,"path":144,"stem":145,"children":146,"page":47},"Utils","i-lucide-wrench","/api/utils","3.api/4.utils",[147,151],{"title":148,"path":149,"stem":150},"Type Guards","/api/utils/type-guards","3.api/4.utils/1.type-guards",{"title":152,"path":153,"stem":154},"Directives","/api/utils/directives","3.api/4.utils/2.directives",{"title":156,"icon":157,"path":158,"stem":159,"children":160,"page":47},"Advanced","i-lucide-brain-circuit","/api/advanced","3.api/5.advanced",[161,165,169],{"title":162,"path":163,"stem":164},"Scaling Performance 🚀","/api/advanced/performance","3.api/5.advanced/performance",{"title":166,"path":167,"stem":168},"Primitives","/api/advanced/primitives","3.api/5.advanced/primitives",{"title":170,"path":171,"stem":172},"WebGPU","/api/advanced/web-gpu","3.api/5.advanced/web-gpu",{"title":174,"path":175,"stem":176,"children":177},"Cookbook","/cookbook","4.cookbook",[178,181,185,189,193,197,201],{"title":179,"path":175,"stem":180},"Cookbook 🍳🧑‍🍳","4.cookbook/index",{"title":182,"path":183,"stem":184},"OrbitControls","/cookbook/orbit-controls","4.cookbook/1.orbit-controls",{"title":186,"path":187,"stem":188},"Basic Animations","/cookbook/basic-animations","4.cookbook/2.basic-animations",{"title":190,"path":191,"stem":192},"Model Animation","/cookbook/model-animation","4.cookbook/3.model-animation",{"title":194,"path":195,"stem":196},"Advanced GSAP Animations","/cookbook/advanced-gsap-animations","4.cookbook/4.advanced-gsap-animations",{"title":198,"path":199,"stem":200},"Tweakpane","/cookbook/tweakpane","4.cookbook/5.tweakpane",{"title":202,"path":203,"stem":204},"Dynamic components","/cookbook/transition-dynamic","4.cookbook/6.transition-dynamic",{"title":206,"path":207,"stem":208,"children":209},"Community","/community","5.community/1.index",[210,211],{"title":206,"path":207,"stem":208},{"title":212,"path":213,"stem":214},"Awesome Resources","/community/awesome-resources","5.community/awesome-resources",{"title":216,"path":217,"stem":218},"German Translation","/de","de",{"title":220,"path":221,"stem":222},"Spanish Translation","/es","es",{"title":224,"path":225,"stem":226},"French Translation","/fr","fr",{"title":228,"path":229,"stem":230},"Italian Translation","/it","it",{"title":232,"path":233,"stem":234},"Japanese Translation","/jp","jp",{"title":236,"path":237,"stem":238},"Chinese Translation","/zh","zh",{"id":240,"title":44,"body":241,"description":593,"extension":594,"links":595,"meta":596,"navigation":39,"path":45,"seo":597,"stem":46,"__hash__":598},"docs/2.essentials/1.core-architecture/2.custom-vue-renderer.md",{"type":242,"value":243,"toc":586},"minimark",[244,251,254,259,262,267,270,424,428,431,560,564,567,583],[245,246,247],"warning",{},[248,249,250],"p",{},"This page is a work in progress.",[248,252,253],{},"This page documents how TresJS leverages Vue 3's custom renderer API to transform Vue components into Three.js objects. The custom renderer is one of the core architectural elements of TresJS, allowing developers to use declarative Vue syntax to construct and manipulate 3D scenes.",[255,256,258],"h2",{"id":257},"what-is-a-custom-renderer","What is a custom renderer?",[248,260,261],{},"Vue 3 introduced the ability to create custom renderers that target platforms beyond the DOM. While Vue's standard renderer transforms Vue components into DOM elements, a custom renderer can transform them into anything—in TresJS's case, Three.js objects.",[263,264,266],"h3",{"id":265},"the-traditional-dom-renderer","The Traditional DOM Renderer",[248,268,269],{},"In a typical Vue application, the renderer creates and manipulates DOM elements:",[271,272,278],"pre",{"className":273,"code":274,"filename":275,"language":276,"meta":277,"style":277},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// Vue's DOM renderer operations\nconst div = document.createElement('div') // Create element\ndiv.textContent = 'Hello World' // Set properties\ndocument.body.appendChild(div) // Mount to parent\ndiv.style.color = 'red' // Update properties\ndocument.body.removeChild(div) // Unmount\n","dom-renderer-concept.js","javascript","",[279,280,281,290,333,356,378,405],"code",{"__ignoreMap":277},[282,283,286],"span",{"class":284,"line":285},"line",1,[282,287,289],{"class":288},"sHwdD","// Vue's DOM renderer operations\n",[282,291,293,297,301,305,308,311,315,318,321,325,327,330],{"class":284,"line":292},2,[282,294,296],{"class":295},"spNyl","const",[282,298,300],{"class":299},"sTEyZ"," div ",[282,302,304],{"class":303},"sMK4o","=",[282,306,307],{"class":299}," document",[282,309,310],{"class":303},".",[282,312,314],{"class":313},"s2Zo4","createElement",[282,316,317],{"class":299},"(",[282,319,320],{"class":303},"'",[282,322,324],{"class":323},"sfazB","div",[282,326,320],{"class":303},[282,328,329],{"class":299},") ",[282,331,332],{"class":288},"// Create element\n",[282,334,336,338,340,343,345,348,351,353],{"class":284,"line":335},3,[282,337,324],{"class":299},[282,339,310],{"class":303},[282,341,342],{"class":299},"textContent ",[282,344,304],{"class":303},[282,346,347],{"class":303}," '",[282,349,350],{"class":323},"Hello World",[282,352,320],{"class":303},[282,354,355],{"class":288}," // Set properties\n",[282,357,359,362,364,367,369,372,375],{"class":284,"line":358},4,[282,360,361],{"class":299},"document",[282,363,310],{"class":303},[282,365,366],{"class":299},"body",[282,368,310],{"class":303},[282,370,371],{"class":313},"appendChild",[282,373,374],{"class":299},"(div) ",[282,376,377],{"class":288},"// Mount to parent\n",[282,379,381,383,385,388,390,393,395,397,400,402],{"class":284,"line":380},5,[282,382,324],{"class":299},[282,384,310],{"class":303},[282,386,387],{"class":299},"style",[282,389,310],{"class":303},[282,391,392],{"class":299},"color ",[282,394,304],{"class":303},[282,396,347],{"class":303},[282,398,399],{"class":323},"red",[282,401,320],{"class":303},[282,403,404],{"class":288}," // Update properties\n",[282,406,408,410,412,414,416,419,421],{"class":284,"line":407},6,[282,409,361],{"class":299},[282,411,310],{"class":303},[282,413,366],{"class":299},[282,415,310],{"class":303},[282,417,418],{"class":313},"removeChild",[282,420,374],{"class":299},[282,422,423],{"class":288},"// Unmount\n",[263,425,427],{"id":426},"tresjs-threejs-renderer","TresJS Three.js Renderer",[248,429,430],{},"TresJS implements a custom renderer that performs analogous operations with Three.js objects:",[271,432,435],{"className":273,"code":433,"filename":434,"language":276,"meta":277,"style":277},"// TresJS renderer operations\nconst mesh = new THREE.Mesh() // Create Three.js object\nmesh.material = new THREE.MeshBasicMaterial() // Set properties\nscene.add(mesh) // Add to scene graph\nmesh.position.set(1, 2, 3) // Update properties\nscene.remove(mesh) // Remove from scene\n","tres-renderer-concept.js",[279,436,437,442,468,494,510,546],{"__ignoreMap":277},[282,438,439],{"class":284,"line":285},[282,440,441],{"class":288},"// TresJS renderer operations\n",[282,443,444,446,449,451,454,457,459,462,465],{"class":284,"line":292},[282,445,296],{"class":295},[282,447,448],{"class":299}," mesh ",[282,450,304],{"class":303},[282,452,453],{"class":303}," new",[282,455,456],{"class":299}," THREE",[282,458,310],{"class":303},[282,460,461],{"class":313},"Mesh",[282,463,464],{"class":299},"() ",[282,466,467],{"class":288},"// Create Three.js object\n",[282,469,470,473,475,478,480,482,484,486,489,491],{"class":284,"line":335},[282,471,472],{"class":299},"mesh",[282,474,310],{"class":303},[282,476,477],{"class":299},"material ",[282,479,304],{"class":303},[282,481,453],{"class":303},[282,483,456],{"class":299},[282,485,310],{"class":303},[282,487,488],{"class":313},"MeshBasicMaterial",[282,490,464],{"class":299},[282,492,493],{"class":288},"// Set properties\n",[282,495,496,499,501,504,507],{"class":284,"line":358},[282,497,498],{"class":299},"scene",[282,500,310],{"class":303},[282,502,503],{"class":313},"add",[282,505,506],{"class":299},"(mesh) ",[282,508,509],{"class":288},"// Add to scene graph\n",[282,511,512,514,516,519,521,524,526,530,533,536,538,541,543],{"class":284,"line":380},[282,513,472],{"class":299},[282,515,310],{"class":303},[282,517,518],{"class":299},"position",[282,520,310],{"class":303},[282,522,523],{"class":313},"set",[282,525,317],{"class":299},[282,527,529],{"class":528},"sbssI","1",[282,531,532],{"class":303},",",[282,534,535],{"class":528}," 2",[282,537,532],{"class":303},[282,539,540],{"class":528}," 3",[282,542,329],{"class":299},[282,544,545],{"class":288},"// Update properties\n",[282,547,548,550,552,555,557],{"class":284,"line":407},[282,549,498],{"class":299},[282,551,310],{"class":303},[282,553,554],{"class":313},"remove",[282,556,506],{"class":299},[282,558,559],{"class":288},"// Remove from scene\n",[255,561,563],{"id":562},"the-custom-renderer-api","The Custom Renderer API",[248,565,566],{},"The custom renderer in TresJS (nodeOps) implements a set of operations that Vue calls when it needs to:",[568,569,570,574,577,580],"ul",{},[571,572,573],"li",{},"Create a new Three.js object",[571,575,576],{},"Add an object to the scene or to another object",[571,578,579],{},"Update an object's properties",[571,581,582],{},"Remove an object from the scene.",[387,584,585],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":277,"searchDepth":285,"depth":292,"links":587},[588,592],{"id":257,"depth":292,"text":258,"children":589},[590,591],{"id":265,"depth":335,"text":266},{"id":426,"depth":335,"text":427},{"id":562,"depth":292,"text":563},"Discover how TresJS leverages Vue 3's custom renderer API to bridge Vue's reactive component system with Three.js 3D scene management.","md",null,{},{"title":44,"description":593},"z458A2Z6Akv6dz7694I5KSEAX1PpF-32rOLC_0S1rN0",[600,602],{"title":30,"path":31,"stem":35,"description":601,"children":-1},"Discover the core concepts of TresJS.",{"title":55,"path":56,"stem":57,"description":603,"children":-1},"Discover how TresJS transforms imperative Three.js code into declarative Vue components, making 3D development more intuitive and maintainable.",1774953661754]