` currently only accepts 1 string flag from the user. Using only flags means the system relies solely on us predicting users' needs and implementing a \"mode\" for them.\r\nAccepting only a single flag means we can't have a compound policy, e.g., \"rerender if advance or invalidate were called or the window resized. Afaik, this currently leads to cases where manual is the mode – the canvas will be blank if the window is resized, until invalidate is called.\r\n\r\n\r\n\r\n### Suggested solution\r\n\r\nEncapsulate the logic for \"Should the next tick update/render?\" in a module – maybe `src/core/renderPolicy.ts`?\r\nLet the render policy be specified via functions/objects as follows:\r\n\r\n```ts\r\nimport { createRenderPolicy, manual } from '...'\r\nconst policy = createRenderPolicy(manual)\r\nconst { invalidate } = policy\r\n...\r\n\u003CTresCanvas :render-policy=\"policy\" />\r\n```\r\n\r\nAbove, \r\n\r\n- manual is \"rule\" function that contains its own state, tracking if invalidate() was called since the last update.\r\n- policy is an object that relays calls to invalidate and advance to its rules, then asks the rules if the next tick should update/render or not.\r\n\r\nIn this way, we could have compound policies. E.g.,\r\n\r\n```ts\r\n// NOTE: This policy will approve the next tick of jobs if ...\r\n// - `invalidate()` was called\r\n// - the window was resized\r\n// but cancel if ...\r\n// - the canvas is off-screen\r\nconst { shouldUpdate, invalidate } = createRenderPolicy([manual, windowResize, cancelIfOffScreen])\r\nshouldUpdate() // false\r\ninvalidate()\r\nshouldUpdate() // true\r\n```\r\n\r\nRules would be evaluated in FILO order, with the result of lower ranking rules being passed to higher ranking rules, so this ...\r\n\r\n```\r\ncreateRenderPolicy([manual, cancelIfOffScreen, windowResize])\r\n```\r\n\r\n... cancels true from windowResize if the canvas is offscreen. But if the canvas is off-screen, manual's advance(n) will still take precedence.\r\n\r\nWhereas here ...\r\n\r\n```\r\ncreateRenderPolicy([cancelIfOffScreen, manual, windowResize])\r\n```\r\n\r\n... `cancelIfOffScreen` takes precedence over the other 2 rules and cancels both if the canvas is off-screen. \r\n----\r\n\r\nRules are relatively simple to write and users could supply their own rules, if we surface that in the API. Here's a \"complicated\" rule – `windowResize` – in its current form:\r\n\r\n```ts\r\nexport const windowResize: CreateUpdateRule = () => {\r\n let invalidated = true\r\n const invalidate = () => { invalidated = true }\r\n window.addEventListener('resize', invalidate)\r\n return {\r\n shouldUpdate: (lowRankResult: boolean) => {\r\n const result = invalidated\r\n invalidated = false\r\n return result || lowRankResult\r\n },\r\n dispose: () => {\r\n window.removeEventListener('resize', invalidate)\r\n }\r\n }\r\n}\r\n```\r\nHere's manual:\r\n\r\n```ts\r\nexport const manual: CreateUpdateRule = () => {\r\n let numFramesToAdvance = 0\r\n return {\r\n advance: (numFrames = 1) => {\r\n numFramesToAdvance = Math.max(numFramesToAdvance, numFrames)\r\n },\r\n shouldUpdate: (lowRankResult: boolean) => {\r\n const result = numFramesToAdvance > 0\r\n numFramesToAdvance = Math.max(0, numFramesToAdvance - 1)\r\n return result || lowRankResult\r\n }\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.\r\n\r\nEdit (andretchen0): fixed formatting ",[2856,2859],{"name":2857,"color":2858},"feature","c2e0c6",{"name":2860,"color":2861},"pending-triage","97A4FE",689,"Tresjs","tres","open","Render mode policies","2024-05-24T14:21:03Z","https://github.com/Tresjs/tres/issues/689",0.7455459,{"description":2871,"labels":2872,"number":2877,"owner":2863,"repository":2864,"state":2865,"title":2878,"updated_at":2879,"url":2880,"score":2881},"As a developer using Tres, I would like a to have a render mode that pauses rendering when:\r\n\r\n* the window/app containing the Tres Scene is blurred/backgrounded\r\n* OR the tab/page containing the Tres Scene is blurred/backgrounded\r\n\r\nAnd resumes rendering when:\r\n\r\n* the window/app containing the Tres Scene is focused/foregrounded\r\n* AND the tab/page containing the Tres Scene is focused/foregrounded\r\n\r\n### Context\r\n\r\n> @andretchen0 @alvarosabu In my tests with `babylonjs` (other engine but should be similar) this worked well, when the tab was in the background yes. But using multiple windows where the window running the engine is visible but not focused left it running at 60 FPS. Given many 3d websites/applications are very resource intensive I'd still consider adding the option to pause rendering when the tab/window is not focused.\r\n\r\n_Originally posted by @thomasaull in https://github.com/Tresjs/tres/issues/497#issuecomment-1900650512_\r\n ",[2873,2874],{"name":2857,"color":2858},{"name":2875,"color":2876},"p2-to-be-discussed","97C1B1",517,"feat: render mode to pause rendering when window is blurred","2024-03-30T15:41:46Z","https://github.com/Tresjs/tres/issues/517",0.7526365,{"description":2883,"labels":2884,"number":2888,"owner":2863,"repository":2864,"state":2865,"title":2889,"updated_at":2890,"url":2891,"score":2892},"## 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.",[2885],{"name":2886,"color":2887},"p3-significant","2C78E3",923,"Error Boundary for TresCanvas","2025-02-06T13:45:39Z","https://github.com/Tresjs/tres/issues/923",0.75380486,{"description":2894,"labels":2895,"number":2896,"owner":2863,"repository":2897,"state":2898,"title":2899,"updated_at":2900,"url":2901,"score":2902},"### Describe the bug\n\nI am trying to use a TresCanvas that is known to work when using in a staticly declared way\r\nbut if I use it in a component that is dynamicly loaded using \r\n\r\n`defineAsyncComponent(() => import('@/components/pageBuilder/component.vue'))`\r\n\r\nit doesn't render the canvas the most I can get is the following\r\n\r\n`\u003Cdiv window-size=\"\" clear-color=\"#241246\" shadows=\"\" data-v-3789b801=\"\">\u003Ccanvas style=\"\">\u003C/canvas>\u003C/div>`\r\n\r\n## Recent findings\r\n\r\njust having the TresCanvas in a component that is nested 2 levels deep doesn't work.\r\nno idea why or what is causing this. \r\n\r\nI've provided a reproduction of this\r\n\n\n### Reproduction\n\nhttps://stackblitz.com/edit/tresjs-basic-z2g8yk?file=src%2Fcomponents%2FTheExperience.vue\n\n### Steps to reproduce\n\n_No response_\n\n### System Info\n\n_No response_\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.",[],79,"nuxt","closed","TresCanvas doesn't render in Dynamicly loaded components or deeply nested components","2024-01-26T12:08:01Z","https://github.com/Tresjs/nuxt/issues/79",0.7141672,{"description":2904,"labels":2905,"number":2906,"owner":2863,"repository":2864,"state":2898,"title":2907,"updated_at":2908,"url":2909,"score":2910},"# Goal\r\nGenerate three-shakeable components on build time to avoid the need for a catalog of global components. This will be probably a BREAKING CHANGE, especially for cientos.\r\n\r\n```vue\r\n\u003Cscript setup lang=\"ts\">\r\n\r\nimport { TresCanvas, TresPerspectiveCamera, TresScene, TresAmbienLight, useRenderLoop } from '@tresjs/core' \r\nimport { OrbitControls, TransformControls } from '@tresjs/cientos'\r\n\r\nconst sphereRef = ref()\r\n\r\nconst { onLoop } = useRenderLoop()\r\n\r\nonLoop(({ elapsed }) => {\r\n sphereRef.value.position.y += Math.sin(elapsed * 0.01) * 0.1\r\n})\r\n\u003C/script>\r\n\u003Ctemplate>\r\n \u003CTresCanvas v-bind=\"state\">\r\n \u003CTresPerspectiveCamera :position=\"[5, 5, 5]\" :fov=\"45\" :near=\"0.1\" :far=\"1000\" :look-at=\"[-8, 3, -3]\" />\r\n \u003COrbitControls make-default />\r\n \u003CTresScene>\r\n \u003CTresAmbientLight :intensity=\"0.5\" />\r\n \u003CTransformControls mode=\"scale\" :object=\"sphereRef\" />\r\n\r\n \u003CTresMesh ref=\"sphereRef\" :position=\"[0, 4, 0]\" cast-shadow>\r\n \u003CTresSphereGeometry />\r\n \u003CTresMeshToonMaterial color=\"#FBB03B\" />\r\n \u003C!-- \u003CTresMeshToonMaterial color=\"#FBB03B\" /> -->\r\n \u003C/TresMesh>\r\n \u003CTresDirectionalLight :position=\"[0, 8, 4]\" :intensity=\"0.7\" cast-shadow />\r\n \u003CTresMesh :rotation=\"[-Math.PI / 2, 0, 0]\" receive-shadow>\r\n \u003CTresPlaneGeometry :args=\"[10, 10, 10, 10]\" />\r\n \u003CTresMeshToonMaterial />\r\n \u003C/TresMesh>\r\n \u003CTresDirectionalLight :position=\"[0, 2, 4]\" :intensity=\"1\" cast-shadow />\r\n \u003C/TresScene>\r\n \u003C/TresCanvas>\r\n\u003C/template>\r\n\r\n```\r\n\r\n- [ ] Using a vite plugin to generate all the components from THREE instances (Except Scene)\r\n- [ ] Each component should locally register components on the slots (is possible?)\r\n- [ ] Typescript Definition for the components generated from the ThreeJS instance\r\n- [ ] Include them in the final bundle\r\n- [ ] Strategy for replacing catalog `extend` \r\n- [ ] Update the way `cientos` extends the catalog\r\n",[],104,"Generate instances on build-time rather than run-time","2023-03-13T14:26:46Z","https://github.com/Tresjs/tres/issues/104",0.7238742,{"description":2912,"labels":2913,"number":1657,"owner":2863,"repository":2917,"state":2898,"title":2918,"updated_at":2919,"url":2920,"score":2921},"**Is your feature request related to a problem? Please describe.**\r\nAs of now, effects are typescript `.ts` files with `defineComponent`.\r\n\r\n```ts\r\nexport const Glitch = defineComponent\u003CGlitchProps>({\r\n name: 'Glitch',\r\n props: [\r\n 'delay',\r\n 'duration',\r\n 'strength',\r\n 'mode',\r\n 'active',\r\n 'ratio',\r\n 'columns',\r\n 'chromaticAberrationOffset',\r\n 'peturbationMap',\r\n 'dtSize',\r\n ] as unknown as undefined,\r\n\r\n async setup(props, { expose }) {\r\n const { state } = useCore()\r\n const composer = inject\u003Cany>('effectComposer')\r\n const pass = ref\u003CEffectPass | null>(null)\r\n\r\n expose({ getPass: () => pass.value })\r\n\r\n watchEffect(() => {\r\n if (state.camera && composer && composer.value) {\r\n pass.value = new EffectPass(unref(state.camera), new GlitchEffect(props))\r\n composer.value?.addPass(toRaw(pass.value))\r\n }\r\n })\r\n\r\n watch(\r\n () => props.active,\r\n value => {\r\n if (pass.value) {\r\n pass.value.enabled = value as boolean\r\n }\r\n },\r\n )\r\n\r\n return () => {\r\n pass\r\n }\r\n },\r\n})\r\n\r\n```\r\n\r\n**Describe the solution you'd like**\r\n\r\nUse a similar approach as cientos and use vue SFC components \r\n\r\n",[2914],{"name":2915,"color":2916},"enhancement","a2eeef","post-processing","Refactor Effects to .vue files","2023-06-23T16:06:50Z","https://github.com/Tresjs/post-processing/issues/23",0.72397065,{"description":2923,"labels":2924,"number":1657,"owner":2863,"repository":2864,"state":2898,"title":2931,"updated_at":2932,"url":2933,"score":2921},"Atm HMR disposal is not working as expected. Meshes are duplicated and this could lead to performance issues on large scenes.\n\nAlso not nice for DX. User needs to reload everytime.\n\nThis one is pretty tricky.\n\n# Desired solution.\n\nRenderer, scene and object follow a disposal flow when HMR hits",[2925,2928],{"name":2926,"color":2927},"help wanted","008672",{"name":2929,"color":2930},"discussion 💭","AE4C80","HMR disposal","2023-09-12T18:58:32Z","https://github.com/Tresjs/tres/issues/23",{"description":2935,"labels":2936,"number":2937,"owner":2863,"repository":2864,"state":2898,"title":2938,"updated_at":2939,"url":2940,"score":2941},"### Describe the bug\r\n\r\nHi, I'm using TresJs v2(@tres/core) in Nuxt3.\r\nThrough your docs and kind explanations, I succeeded in configuring the environment and displaying 3d objects in Nuxt3.\r\n\r\nHowever, if a vue component (I made) containing the TresCanvas tag is unmounted according to the page route movement or certain conditions, and then re-enters the page and is newly mounted, it seems that the object is not rendered on the canvas tag.\r\n\r\nCan you check this?\r\nYou can see an example in the reproduction link below. You can check it when you toggle v-if with the toggle button.\r\nThank you.\r\n\r\n### Reproduction\r\n\r\nhttps://stackblitz.com/edit/nuxt-starter-36xfsn?file=nuxt.config.ts,app.vue (in Nuxt3)\r\nhttps://stackblitz.com/edit/tresjs-basic-i4h4kk?file=src%2FApp.vue (same in Vue3)\r\n\r\n### Steps to reproduce\r\n\r\n_No response_\r\n\r\n### System Info\r\n\r\n```shell\r\nnpm packages version\r\n- nuxt: 3.5.3\r\n- three: 0.153.0\r\n- @tresjs/core: 2.1.3\r\n```\r\n\r\n\r\n### Used Package Manager\r\n\r\nyarn\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.",[],302,"Nuxt3 + Tresjs rendering issue(when remounting, not displaying)","2023-06-19T15:26:29Z","https://github.com/Tresjs/tres/issues/302",0.7253847,{"description":2943,"labels":2944,"number":2949,"owner":2863,"repository":2950,"state":2898,"title":2951,"updated_at":2952,"url":2953,"score":2954},"### Description\r\n\r\nAs a developer using TresJS, I want \r\n- Environment props to be reactive\r\n- More presets other than 'sunset' (city, etc)\r\n\r\n so that:\r\n- I can dynamically configure the preset or toggle the `background` property\r\n\r\n### Suggested solution\r\n\r\nModify the `useEnvironment/component.ts` component so:\r\n\r\n- Convert to vue file SFC\r\n- texture should be a ref\r\n- Set the default for the props here.\r\n\r\nModify the `useEnvironment/index.ts` composable so:\r\n\r\n- Reacts to prop changes (Using watchers and computed)\r\n- Return the texture as a ref\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/cientos/blob/main/CODE_OF_CONDUCT.md)\r\n- [X] Read the [Contributing Guidelines](https://github.com/Tresjs/cientos/blob/main/CONTRIBUTING.md).\r\n- [X] Read the [docs](https://cientos.tresjs.org/guide).\r\n- [X] Check that there isn't [already an issue](https://github.com/tresjs/cientos/issues) that reports the same bug to avoid creating a duplicate.",[2945,2948],{"name":2946,"color":2947},"good first issue","7057ff",{"name":2926,"color":2927},147,"cientos","Enhance Environment and useEnvironment abstractions","2023-10-09T17:33:47Z","https://github.com/Tresjs/cientos/issues/147",0.7271085,{"description":2956,"labels":2957,"number":2949,"owner":2863,"repository":2917,"state":2898,"title":2967,"updated_at":2968,"url":2969,"score":2954},"Attempting to use the 1.0.0 release with Nuxt, I get an error on the `nuxt prepare` step. This is reproducible within this repo's nuxt playground if you update the dependency to 1.0.0.\r\n\r\n```\r\n ERROR ENOENT: no such file or directory, open '/Users/.../.../post-processing/playground-nuxt/@tresjs/post-processing' 10:29:39 AM\r\n ```\r\n\r\nThis does not happen when using `1.0.0-next.1`.\r\n\r\n```\r\n- Operating System: Darwin\r\n- Node Version: v20.10.0\r\n- Nuxt Version: 3.14.1592\r\n- CLI Version: 3.15.0\r\n- Nitro Version: 2.10.4\r\n- Package Manager: npm@10.8.3\r\n- Builder: -\r\n- User Config: default\r\n- Runtime Modules: @nuxt/eslint@0.7.2, @pinia/nuxt@0.7.0, @nuxtjs/supabase@1.4.3, @primevue/nuxt-module@4.2.4, @nuxtjs/tailwindcss@6.12.2, nuxt-lodash@2.5.3, @nuxt/icon@1.8.2, @tresjs/nuxt@3.0.7\r\n- Build Modules: -\r\n```\r\n\r\nThanks for maintaining this project!",[2958,2961,2964],{"name":2959,"color":2960},"bug","d73a4a",{"name":2962,"color":2963},"p4-important-bug","D93F0B",{"name":2965,"color":2966},"types","5C076E","Broken imports in v1.0.0 w/ Nuxt","2025-01-03T09:37:19Z","https://github.com/Tresjs/post-processing/issues/147",["Reactive",2971],{},["Set"],["ShallowReactive",2974],{"$fTRc1wZytZ_XrK4EfJfei_Sz-An4H4Yy6syhVxH_PVJc":-1,"$f75fQwYwfyBsnHDrXA7gtYNGjzaZkWagI3e56wMSIm7Y":-1},"/Tresjs/cientos/276"]