\r\n \u003CTresMeshNormalMaterial />\r\n \u003CHtml\r\n center\r\n transform\r\n :distance-factor=\"4\"\r\n :position=\"[0, 0, 0.65]\"\r\n :scale=\"[0.75, 0.75, 0.75]\"\r\n >\r\n \u003Cdiv>\r\n \u003Cp>This should not scroll\u003C/p>\r\n \u003C/div>\r\n \u003C/Html>\r\n \u003C/TresMesh>\r\n```\r\nI expect the first element to scroll, and the second to stay.\r\n\r\n### System Info\r\n\r\n```shell\r\nSystem:\r\n OS: Linux 5.15 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish)\r\n CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz\r\n Memory: 3.82 GB / 11.69 GB\r\n Container: Yes\r\n Shell: 3.6.1 - /usr/bin/fish\r\n Binaries:\r\n Node: 21.5.0 - ~/.local/share/nvm/v21.5.0/bin/node\r\n Yarn: 1.22.19 - /usr/bin/yarn\r\n npm: 10.2.4 - ~/.local/share/nvm/v21.5.0/bin/npm\r\n pnpm: 8.14.1 - ~/.local/share/pnpm/pnpm\r\n bun: 1.0.7 - ~/.bun/bin/bun\r\n```\r\n\r\n\r\n### Used Package Manager\r\n\r\npnpm\r\n\r\n### Code of Conduct\r\n\r\n- [X] I agree to follow this project's [Code of Conduct](https://github.com/Tresjs/tres/blob/main/CODE_OF_CONDUCT.md)\r\n- [X] Read the [Contributing Guidelines](https://github.com/Tresjs/tres/blob/main/CONTRIBUTING.md).\r\n- [X] Read the [docs](https://tresjs.org/guide).\r\n- [X] Check that there isn't [already an issue](https://github.com/tresjs/tres/issues) that reports the same bug to avoid creating a duplicate.\r\n- [X] The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.",[2892,2895],{"name":2893,"color":2894},"pending-triage","97A4FE",{"name":2896,"color":2897},"waiting for author","B145BC",507,"Native html scroll and @tresjs/cientos Html component behaviour","2024-03-30T15:37:07Z","https://github.com/Tresjs/tres/issues/507",0.75756615,{"description":2904,"labels":2905,"number":2910,"owner":2857,"repository":2858,"state":2859,"title":2911,"updated_at":2912,"url":2913,"score":2914},"### Description\n\nI have a TresCanvas with a lower z-index that is under the main content on my site. I got around this in native Three by using events based on window pointer events. I don't see a way to do this in Tres. \r\n\n\n### Suggested solution\n\nAdd a prop to TresCanvas like window-size (window-pointer?) to use window pointer events instead of attaching events to the canvas itself\n\n### Alternative\n\n_No response_\n\n### Additional context\n\n_No response_\n\n### Validations\n\n- [X] I agree to follow this project's [Code of Conduct](https://github.com/Tresjs/tres/blob/main/CODE_OF_CONDUCT.md)\n- [X] Read the [Contributing Guidelines](https://github.com/Tresjs/tres/blob/main/CONTRIBUTING.md).\n- [X] Read the [docs](https://tresjs.org/guide).\n- [X] Check that there isn't [already an issue](https://github.com/tresjs/tres/issues) that reports the same bug to avoid creating a duplicate.",[2906,2907],{"name":2868,"color":2869},{"name":2908,"color":2909},"p2-nice-to-have","D4C5F9",581,"Use window for pointerevents","2024-07-24T00:40:31Z","https://github.com/Tresjs/tres/issues/581",0.7587083,{"description":2916,"labels":2917,"number":2921,"owner":2857,"repository":2858,"state":2859,"title":2922,"updated_at":2923,"url":2924,"score":2925},"## Description\n\nAs a developer using TresJS, I need a way to gracefully handle and display runtime errors that occur within the TresCanvas component and its children. This would improve the development experience and make it easier to debug issues in production.\n\n## Motivation\nCurrently, when an error occurs within TresCanvas or any of its child components (lights, meshes, materials, etc.) or threejs, the error can cause the entire application to crash or render a blank canvas without any meaningful feedback. This makes it difficult to:\n\n1. Identify the source of the error\n2. Debug issues in development\n3. Provide a fallback UI in production\n4. Handle errors gracefully without affecting the rest of the application\n\n## Proposal\n\nAdd an Error Boundary feature to TresCanvas that would:\n\n1. Catch runtime errors in:\n - Scene initialization\n - Component mounting/unmounting\n - Animation frame updates\n - Resource loading (textures, models, etc.)\n - Child component errors\n\n2. Provide a customizable error display that shows:\n - Error message and stack trace (in development)\n - Component tree path to the error\n - Simplified error message (in production)\n\n3. Include built-in error handling for common ThreeJS-specific errors:\n - WebGL context loss\n - Texture loading failures\n - Geometry errors\n - Material compilation errors\n\n\n## Suggested solution\n\n### Implementation Details\n\n```vue\n\u003Ctemplate>\n \u003CTresCanvas\n :error-boundary=\"true\"\n :error-fallback=\"customErrorComponent\"\n @error=\"handleError\"\n >\n \u003C!-- Scene content -->\n \u003C/TresCanvas>\n\u003C/template>\n```\n\nThe error boundary would inject necessary CSS styles automatically for the error display, eliminating the need for external CSS files. The styles would be scoped to the error boundary container to avoid conflicts.\n\n### Default Error Display\nThe default error display would be a styled overlay with:\n- Error message\n- Stack trace (in development)\n- Retry button\n- Option to copy error details\n- Responsive design that maintains the canvas aspect ratio\n\n```typescript\n// Internal styling injection\nconst errorStyles = `\n .tres-error-boundary {\n position: relative;\n width: 100%;\n height: 100%;\n background: rgba(30, 30, 30, 0.95);\n color: #fff;\n font-family: monospace;\n padding: 1rem;\n overflow: auto;\n }\n .tres-error-message {\n color: #ff5555;\n margin-bottom: 1rem;\n }\n .tres-error-stack {\n font-size: 0.9em;\n white-space: pre-wrap;\n }\n .tres-error-retry {\n background: #4a4a4a;\n border: none;\n color: white;\n padding: 0.5rem 1rem;\n margin-top: 1rem;\n cursor: pointer;\n }\n`\n```\n\n## Opt-in vs Opt-out Discussion\n\n### Opt-in Approach\n\n```vue\n\u003C!-- Explicit opt-in -->\n\u003CTresCanvas :error-boundary=\"true\">\n \u003C!-- Scene content -->\n\u003C/TresCanvas>\n```\n\n#### Pros:\n- More explicit and intentional usage\n- Smaller initial bundle size (code-splitting possible)\n- Developers consciously choose when to use error boundaries\n- Better control over error handling strategies\n\n#### Cons:\n- Requires additional configuration for each TresCanvas instance\n- May lead to inconsistent error handling across the application\n- Developers might forget to add error boundaries where needed\n\n### Opt-out Approach\n\n```vue\n\u003C!-- Error boundaries enabled by default -->\n\u003CTresCanvas>\n \u003C!-- Scene content -->\n\u003C/TresCanvas>\n\n\u003C!-- Explicit opt-out -->\n\u003CTresCanvas :error-boundary=\"false\">\n \u003C!-- Scene content -->\n\u003C/TresCanvas>\n```\n\n#### Pros:\n- Better developer experience out of the box\n- Consistent error handling across the application\n- Safer default behavior\n- Less configuration needed\n\n#### Cons:\n- Slightly larger initial bundle size\n- May be unnecessary for simple scenes\n- Less explicit about error handling behavior\n\n\n\n\n### Alternative\n\n_No response_\n\n### Additional context\n\n## Questions for Discussion\n\n1. Should error boundaries be opt-in or opt-out by default?\n2. What additional information would be helpful in the error display?\n3. Should we provide different error displays for development and production?\n4. How should we handle WebGL-specific errors differently from Vue component errors?\n\nFeel free to share your thoughts and suggestions on this proposal!\n\n### Validations\n\n- [x] I agree to follow this project's [Code of Conduct](https://github.com/Tresjs/tres/blob/main/CODE_OF_CONDUCT.md)\n- [x] Read the [Contributing Guidelines](https://github.com/Tresjs/tres/blob/main/CONTRIBUTING.md).\n- [x] Read the [docs](https://tresjs.org/guide).\n- [x] Check that there isn't [already an issue](https://github.com/tresjs/tres/issues) that reports the same bug to avoid creating a duplicate.",[2918],{"name":2919,"color":2920},"p3-significant","2C78E3",923,"Error Boundary for TresCanvas","2025-02-06T13:45:39Z","https://github.com/Tresjs/tres/issues/923",0.7663078,{"description":2927,"labels":2928,"number":2932,"owner":2857,"repository":2933,"state":2859,"title":2934,"updated_at":2935,"url":2936,"score":2937},"The current API is far from ideal, we initially followed the same DX as https://github.com/pmndrs/leva \r\nbut encountered number of issues\"\r\n\r\n- Need to use `value.value` for multiple controls #92 \r\n- Shared `useControls` composable, impossible to have multiple distinct instances #98 \r\n\r\nI will copy the different suggestions from @andretchen0 \r\n\r\n## Example: Tweakpane\r\n\r\n[Tweakpane | Bindings](https://tweakpane.github.io/docs/input-bindings/)\r\n\r\nTweakpane uses `.addBinding(stateObject, key, params)`.\r\n\r\n```ts\r\nconst PARAMS = {\r\n speed: 50,\r\n};\r\n\r\nconst pane = new Pane();\r\npane.addBinding(PARAMS, 'speed', {\r\n min: 0,\r\n max: 100,\r\n});\r\n```\r\n\r\nWith this setup, there's no need for a `watch` and so no `value.value`. The value is already being \"watched\" with the configuration above.\r\n\r\n## Example: v-tweakpane\r\n\r\nA variation of Tweakpane, this time with Vue. Like Tweakpane, it uses a specific method for creating a widget and binding at the same time. This avoids the need to `watch` and avoids `.value.value`.\r\n\r\n```ts\r\nconst onPaneTwoCreated = (pane: any) => {\r\n pane.registerPlugin(CamerakitPlugin);\r\n const PARAMS = {\r\n flen: 55,\r\n fnum: 1.8,\r\n iso: 100,\r\n };\r\n pane.addInput(PARAMS, 'flen', {\r\n view: 'cameraring',\r\n series: 0,\r\n unit: { pixels: 50, ticks: 10, value: 0.2 },\r\n min: 1,\r\n step: 0.02,\r\n });\r\n```\r\n\r\nThe [example](https://github.com/vinayakkulkarni/v-tweakpane/blob/main/example/src/App.vue) uses some callbacks for setup, which Leches doesn't need. Personally, I'd like to avoid having those.\r\n\r\n## Example: Vuetify\r\n\r\nIn this [Vuetify example](https://vuetifyjs.com/en/components/sliders/#min-and-max), most of the config that Leches does in `\u003Csetup>` is handled in `\u003Ctemplate>`. Bindings are created using `v-model` in the `\u003Ctemplate>`.\r\n\r\n```html\r\n\u003Ctemplate>\r\n \u003Cv-slider\r\n v-model=\"slider\"\r\n class=\"align-center\"\r\n :max=\"max\"\r\n :min=\"min\"\r\n hide-details\r\n >\r\n \u003Ctemplate v-slot:append>\r\n \u003Cv-text-field\r\n v-model=\"slider\"\r\n hide-details\r\n single-line\r\n density=\"compact\"\r\n type=\"number\"\r\n style=\"width: 70px\"\r\n >\u003C/v-text-field>\r\n \u003C/template>\r\n \u003C/v-slider>\r\n\u003C/template>\r\n\r\n\u003Cscript>\r\n export default {\r\n data () {\r\n return {\r\n min: -50,\r\n max: 90,\r\n slider: 40,\r\n }\r\n },\r\n }\r\n\u003C/script>\r\n```",[2929],{"name":2930,"color":2931},"enhancement","a2eeef",104,"leches","Rethink API and DX","2024-04-27T19:31:44Z","https://github.com/Tresjs/leches/issues/104",0.7682571,{"description":2939,"labels":2940,"number":2946,"owner":2857,"repository":2858,"state":2947,"title":2948,"updated_at":2949,"url":2950,"score":2951},"### Description\r\n\r\n## Problem\r\n\r\nUpdates/renders share the same unordered-from-the-components-perspective callback \"slot\", leading to out-of-sync visuals.\r\n\r\n## Example\r\n\r\nHere's the Cientos' playground demo for `MeshReflectionMaterial`. Notice the extra \"jumps\" in the reflection:\r\n\r\nhttps://github.com/Tresjs/tres/assets/20469369/314a4154-7cef-47d0-977e-e98fd53c8c13\r\n\r\nHere are two adjacent frames. Notice that the \"real\" elements haven't moved, but the reflection \"jumps\" from one frame to the next:\r\n\r\n\u003Cimg width=\"1044\" alt=\"Screenshot 2024-03-29 at 15 13 35\" src=\"https://github.com/Tresjs/tres/assets/20469369/47a6f2d1-817c-4bf1-a164-70969fb3aa7d\">\r\n\r\n## Why it happens\r\n\r\nThe \"jumps\" occur because the updates/renders are all firing in `onLoop`, but out-of-order from the perspective of the FBO reflection. So for a file like this ...\r\n\r\n```vue\r\n\u003Cscript setup lang=\"ts\">\r\nimport { TresCanvas, useRenderLoop } from '@tresjs/core'\r\nimport DemoComponent from './DemoComponent.vue'\r\n\r\nconst { onLoop } = useRenderLoop()\r\n\r\nonLoop(({ elapsed }) => {\r\n console.log(\"Demo update\", elapsed)\r\n})\r\n\u003C/script>\r\n\r\n\u003Ctemplate>\r\n \u003CTresCanvas>\r\n \u003CTresPerspectiveCamera />\r\n \u003CDemoComponent>\u003C/DemoComponent>\r\n \u003C/TresCanvas>\r\n\u003C/template>\r\n\r\n```\r\n\r\n... a single \"tick\" of `onLoop` looks like this:\r\n\r\n\u003Cimg width=\"238\" alt=\"Screenshot 2024-03-29 at 16 41 44\" src=\"https://github.com/Tresjs/tres/assets/20469369/63d33e65-de88-48dc-859d-709863672227\">\r\n\r\nWith this ordering, if `DemoComponent` renders the scene to an FBO, and is then rendered to the screen, it'll always be 1 frame behind `Demo`.\r\n\r\n\r\n\r\n### Suggested solution\r\n\r\nWe could follow R3F's lead here:\r\n\r\n* [Guarantee that rendering happens after `onLoop`](https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe)\r\n* Implement these:\r\n** https://docs.pmnd.rs/react-three-fiber/api/hooks#taking-over-the-render-loop\r\n** https://docs.pmnd.rs/react-three-fiber/api/hooks#negative-indices\r\n\r\nFor example, R3F's `OrbitControls` uses a negative index:\r\n\r\nhttps://github.com/pmndrs/drei/blob/c147c2b1064bc4b457150f995bf714c2e43cf56f/src/core/OrbitControls.tsx#L58C1-L61C13\r\n\r\nIf I understand correctly, that means that the OrbitControls camera is updated before the rest of the scene, which is important in the case of FBOs like in the reflection material.\r\n\r\n### Alternative\r\n\r\nAs a simpler – though less flexible – solution, we could add a few callbacks:\r\n\r\n* `useRenderLoop().onBeforeRender()` – for FBOs\r\n* `useRenderLoop().onRender()` – for actually rendering to the screen\r\n\r\n### Additional context\r\n\r\n_No response_\r\n\r\n### Validations\r\n\r\n- [X] I agree to follow this project's [Code of Conduct](https://github.com/Tresjs/tres/blob/main/CODE_OF_CONDUCT.md)\r\n- [X] Read the [Contributing Guidelines](https://github.com/Tresjs/tres/blob/main/CONTRIBUTING.md).\r\n- [X] Read the [docs](https://tresjs.org/guide).\r\n- [X] Check that there isn't [already an issue](https://github.com/tresjs/tres/issues) that reports the same bug to avoid creating a duplicate.",[2941,2944,2945],{"name":2942,"color":2943},"bug","d73a4a",{"name":2868,"color":2869},{"name":2871,"color":2872},607,"closed","`useRenderLoop`: render after updates","2024-05-30T06:58:57Z","https://github.com/Tresjs/tres/issues/607",0.7235038,{"description":2953,"labels":2954,"number":2961,"owner":2857,"repository":2858,"state":2947,"title":2962,"updated_at":2963,"url":2964,"score":2965},"### Describe the bug\n\n## Problem\r\n\r\n`useRenderLoop().onLoop` ticks before the renderer can meaningfully render. \r\n\r\nWhen `onLoop` is initially called, e.g.:\r\n\r\n* camera.aspect has its default value of 1, regardless of screen aspect\r\n* renderer.domElement.width has a value of 0\r\n* sizes.width has a value of 0\r\n\r\nThese values change on the subsequent frame, making coding/debugging more difficult than necessary.\r\n\r\n## Solution\r\n\r\n* `useRenderLoop()` should be dependent on the `context`'s renderer.\r\n* The system shouldn't tick `onLoop` until the renderer is ready. \r\n\r\n## Context\r\n\r\n* #251\r\n* #252\r\n\r\n\n\n### Reproduction\n\nhttps://stackblitz.com/edit/tresjs-basic-t6zfd2?file=src%2Fcomponents%2FUseRenderer.vue\n\n### Steps to reproduce\n\nSee StackBlitz.\n\n### System Info\n\n```shell\nSystem:\r\n OS: Linux 5.0 undefined\r\n CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz\r\n Memory: 0 Bytes / 0 Bytes\r\n Shell: 1.0 - /bin/jsh\r\n Binaries:\r\n Node: 18.18.0 - /usr/local/bin/node\r\n Yarn: 1.22.19 - /usr/local/bin/yarn\r\n npm: 10.2.3 - /usr/local/bin/npm\r\n pnpm: 8.15.3 - /usr/local/bin/pnpm\r\n npmPackages:\r\n @tresjs/cientos: ^3.5.1 => 3.5.1 \r\n @tresjs/core: ^3.4.1 => 3.4.1 \r\n @tresjs/eslint-config-vue: ^0.2.1 => 0.2.1 \r\n vite: ^4.5.0 => 4.5.0\n```\n\n\n### Used Package Manager\n\nnpm\n\n### Code of Conduct\n\n- [X] I agree to follow this project's [Code of Conduct](https://github.com/Tresjs/tres/blob/main/CODE_OF_CONDUCT.md)\n- [X] Read the [Contributing Guidelines](https://github.com/Tresjs/tres/blob/main/CONTRIBUTING.md).\n- [X] Read the [docs](https://tresjs.org/guide).\n- [X] Check that there isn't [already an issue](https://github.com/tresjs/tres/issues) that reports the same bug to avoid creating a duplicate.\n- [X] The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.",[2955,2958],{"name":2956,"color":2957},"PR welcome","2D76B0",{"name":2959,"color":2960},"p3-minor-bug","F28C37",595,"`useRenderLoop().onLoop` ticks before the renderer can meaningfully render","2024-06-15T09:59:36Z","https://github.com/Tresjs/tres/issues/595",0.73640424,{"description":2967,"labels":2968,"number":2972,"owner":2857,"repository":2858,"state":2947,"title":2973,"updated_at":2974,"url":2975,"score":2976},"### Description\r\n\r\nAs the author and maintainer of TresJS, I would like to simplify and clean the custom renderer `nodeOps` to make the code more readable and easier to maintain.\r\n\r\nAt, we are using overpopulation the property [userData](https://threejs.org/docs/#api/en/core/Object3D.userData) for the scene and objects on the scene graph as a workaround for accessing state or adding extra properties and methods that we need for TresJS nodeOps like this:\r\n\r\n` scene.userData.tres__registerAtPointerEventHandler = registerObject`\r\n\r\n`userData` is a property that the end-user can also use, we need to add the `.tres__` prefix to avoid naming collisions, adding an extra cognitive load to the code.\r\n\r\nCode ends up being kind of difficult to read:\r\n\r\n```ts\r\nremove(node) {\r\n if (!node) return\r\n // remove is only called on the node being removed and not on child nodes.\r\n\r\n if (node.isObject3D) {\r\n const object3D = node as unknown as Object3D\r\n\r\n const disposeMaterialsAndGeometries = (object3D: Object3D) => {\r\n const tresObject3D = object3D as TresObject3D\r\n\r\n if (!object3D.userData.tres__materialViaProp) {\r\n tresObject3D.material?.dispose()\r\n tresObject3D.material = undefined\r\n }\r\n\r\n if (!object3D.userData.tres__geometryViaProp) {\r\n tresObject3D.geometry?.dispose()\r\n tresObject3D.geometry = undefined\r\n }\r\n }\r\n\r\n const deregisterAtPointerEventHandler = scene?.userData.tres__deregisterAtPointerEventHandler\r\n const deregisterBlockingObjectAtPointerEventHandler\r\n = scene?.userData.tres__deregisterBlockingObjectAtPointerEventHandler\r\n\r\n const deregisterAtPointerEventHandlerIfRequired = (object: TresObject) => {\r\n\r\n if (!deregisterBlockingObjectAtPointerEventHandler)\r\n throw 'could not find tres__deregisterBlockingObjectAtPointerEventHandler on scene\\'s userData'\r\n\r\n scene?.userData.tres__deregisterBlockingObjectAtPointerEventHandler?.(object as Object3D)\r\n\r\n if (!deregisterAtPointerEventHandler)\r\n throw 'could not find tres__deregisterAtPointerEventHandler on scene\\'s userData'\r\n\r\n if (\r\n object && supportedPointerEvents.some(eventName => object[eventName])\r\n )\r\n deregisterAtPointerEventHandler?.(object as Object3D)\r\n }\r\n\r\n const deregisterCameraIfRequired = (object: Object3D) => {\r\n const deregisterCamera = scene?.userData.tres__deregisterCamera\r\n\r\n if (!deregisterCamera)\r\n throw 'could not find tres__deregisterCamera on scene\\'s userData'\r\n\r\n if ((object as Camera).isCamera)\r\n deregisterCamera?.(object as Camera)\r\n }\r\n\r\n node.removeFromParent?.()\r\n object3D.traverse((child: Object3D) => {\r\n disposeMaterialsAndGeometries(child)\r\n deregisterCameraIfRequired(child)\r\n deregisterAtPointerEventHandlerIfRequired?.(child as TresObject)\r\n })\r\n\r\n disposeMaterialsAndGeometries(object3D)\r\n deregisterCameraIfRequired(object3D)\r\n deregisterAtPointerEventHandlerIfRequired?.(object3D as TresObject)\r\n }\r\n\r\n node.dispose?.()\r\n },\r\n ``` \r\n\r\n### Suggested solution\r\n\r\nAdd a local state for each instance called `__tres` which contains:\r\n\r\n```ts\r\nexport interface LocalState = {\r\n type: string\r\n // objects and parent are used when children are added with `attach` instead of being added to the Object3D scene graph\r\n objects: Instance[]\r\n parent: Instance | null\r\n primitive?: boolean\r\n eventCount: number\r\n handlers: Partial\u003CEventHandlers>\r\n memoizedProps: { [key: string]: any }\r\n}\r\n```\r\n\r\n```ts\r\nexport interface TresObject3D extends THREE.Object3D\u003CTHREE.Object3DEventMap> {\r\n geometry?: THREE.BufferGeometry & TresBaseObject\r\n material?: THREE.Material & TresBaseObject\r\n __tres: LocalState\r\n}\r\n```\r\n\r\nWe could include the context of TresContextProvider on the scene object to handle the register of cameras and event handlers or even inside each LocalState on a potential property `root`\r\n\r\n```ts\r\nexport type LocalState = {\r\n type: string\r\n // objects and parent are used when children are added with `attach` instead of being added to the Object3D scene graph\r\n root: TresContext,\r\n objects: Instance[]\r\n parent: Instance | null\r\n primitive?: boolean\r\n eventCount: number\r\n handlers: Partial\u003CEventHandlers>\r\n memoizedProps: { [key: string]: any }\r\n}\r\n```\r\n\r\n\r\n### Alternative\r\n\r\n_No response_\r\n\r\n### Additional context\r\n\r\n_No response_\r\n\r\n### Validations\r\n\r\n- [X] I agree to follow this project's [Code of Conduct](https://github.com/Tresjs/tres/blob/main/CODE_OF_CONDUCT.md)\r\n- [X] Read the [Contributing Guidelines](https://github.com/Tresjs/tres/blob/main/CONTRIBUTING.md).\r\n- [X] Read the [docs](https://tresjs.org/guide).\r\n- [X] Check that there isn't [already an issue](https://github.com/tresjs/tres/issues) that reports the same bug to avoid creating a duplicate.",[2969],{"name":2970,"color":2971},"v4","7980EA",516,"LocalState for custom renderer node instances instead of userData","2024-04-03T06:58:19Z","https://github.com/Tresjs/tres/issues/516",0.743682,["Reactive",2978],{},["Set"],["ShallowReactive",2981],{"$fTRc1wZytZ_XrK4EfJfei_Sz-An4H4Yy6syhVxH_PVJc":-1,"$fuWiEJgZL8LAQfmg5Z-1X6dI7TkdPkdisYpWiLUXdVTE":-1},"/Tresjs/tres/689"]