{"id":15021297,"url":"https://github.com/agargaro/instanced-mesh","last_synced_at":"2025-04-04T10:02:03.792Z","repository":{"id":248163671,"uuid":"820931553","full_name":"agargaro/instanced-mesh","owner":"agargaro","description":"Enhanced InstancedMesh with frustum culling, fast raycasting (using a BVH), sorting, visibility, LOD, skinning and more.","archived":false,"fork":false,"pushed_at":"2025-03-26T21:22:47.000Z","size":39814,"stargazers_count":244,"open_issues_count":7,"forks_count":16,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-26T22:27:38.729Z","etag":null,"topics":["bvh","frustum-culling","instancedmesh2","instances","lod","performance","shadow-lod","skinning","three-js","threejs","uniforms","visibility"],"latest_commit_sha":null,"homepage":"https://agargaro.github.io/instanced-mesh/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/agargaro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-27T13:15:14.000Z","updated_at":"2025-03-26T21:22:51.000Z","dependencies_parsed_at":"2024-09-14T01:45:03.349Z","dependency_job_id":"392018bd-eca2-41f1-a5db-a68ff3cf3b8a","html_url":"https://github.com/agargaro/instanced-mesh","commit_stats":{"total_commits":134,"total_committers":3,"mean_commits":"44.666666666666664","dds":"0.20149253731343286","last_synced_commit":"ad8d7a8cc83c86ca56b9040daa76ca9aa117a0bb"},"previous_names":["three-ez/instanced-mesh","agargaro/instanced-mesh"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agargaro%2Finstanced-mesh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agargaro%2Finstanced-mesh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agargaro%2Finstanced-mesh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agargaro%2Finstanced-mesh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/agargaro","download_url":"https://codeload.github.com/agargaro/instanced-mesh/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247157047,"owners_count":20893202,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bvh","frustum-culling","instancedmesh2","instances","lod","performance","shadow-lod","skinning","three-js","threejs","uniforms","visibility"],"created_at":"2024-09-24T19:56:24.828Z","updated_at":"2025-04-04T10:02:03.754Z","avatar_url":"https://github.com/agargaro.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \n  \u003ch1\u003eThree.ez - InstancedMesh2\u003c/h1\u003e\n  \u003cp\u003e\n    \u003cem\u003eSimplify your \u003cb\u003ethree.js\u003c/b\u003e application development with \u003cb\u003ethree.ez\u003c/b\u003e!\u003c/em\u003e\n  \u003c/p\u003e\n\n  \u003cimg src=\"public/banner.png\" alt=\"banner\" /\u003e \u003cbr\u003e\n\n  [![Discord](https://img.shields.io/badge/chat-discord-blue?style=flat\u0026logo=discord)](https://discord.gg/MVTwrdX3JM)\n  [![npm](https://img.shields.io/npm/v/@three.ez/instanced-mesh)](https://www.npmjs.com/package/@three.ez/instanced-mesh)\n  [![Stars](https://badgen.net/github/stars/three-ez/instanced-mesh)](https://github.com/three-ez/instanced-mesh)\n  [![BundlePhobia](https://badgen.net/bundlephobia/min/@three.ez/instanced-mesh)](https://bundlephobia.com/package/@three.ez/instanced-mesh)\n  [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=agargaro_instanced-mesh\u0026metric=alert_status)](https://sonarcloud.io/summary/new_code?id=agargaro_instanced-mesh)\n  [![DeepScan grade](https://deepscan.io/api/teams/21196/projects/27990/branches/896898/badge/grade.svg)](https://deepscan.io/dashboard#view=project\u0026tid=21196\u0026pid=27990\u0026bid=896898)\n\n\u003c/div\u003e\n\n`InstancedMesh2` is an alternative version of `InstancedMesh` with enhanced features for performance and usability:\n- [**Per-instance frustum culling**](#per-instance-frustum-culling): *skip rendering for out-of-view instances.*\n- [**Sorting**](#sorting): *reduce overdraw and manage transparent objects efficiently.*\n- [**Spatial indexing (dynamic BVH)**](#spatial-indexing-dynamic-bvh): *speed up raycasting and frustum culling.*\n- [**Dynamic capacity**](#dynamic-capacity): *add or remove instances seamlessly.*\n- [**Per-instance visibility**](#per-instance-visibility): *toggle visibility for each instance individually.*\n- [**Per-instance opacity**](#per-instance-opacity): *set opacity for each instance individually.*\n- [**Object3D-like instances**](#object3d-like-instances): *use instances like `Object3D` with transforms and custom data.*\n- [**Per-instance uniforms**](#per-instance-uniforms): *assign unique shader data to individual instances.*\n- [**Level of Detail (LOD)**](#level-of-detail-lod): *dynamically adjust instance detail based on distance.*\n- [**Shadow LOD**](#shadow-lod): *optimize shadow rendering with lower detail for distant instances.*\n- [**Skinning**](#skinning): *apply skeletal animations to instances for more complex and dynamic movements.*\n\n```ts\nconst myInstancedMesh = new InstancedMesh2(geometry, material);\n\nmyInstancedMesh.addInstances(count, (obj, index) =\u003e {\n  obj.position.x = index;\n});\n```\n\n## 🧑‍💻 Live Examples\n\n**Vanilla**\n- \u003cimg src=\"public/js.png\" alt=\"js\" width=\"16\" /\u003e [Dynamic adding with BVH](https://stackblitz.com/edit/stackblitz-starters-au96fmqz?file=index.html) (thanks to [Saumac](https://github.com/saumac))\n\n**Using three.ez/main**\n- \u003cimg src=\"public/ts.png\" alt=\"ts\" width=\"16\" /\u003e [1kk static trees](https://stackblitz.com/edit/three-ezinstancedmesh2-1kk-static-trees?file=src%2Fmain.ts\u0026embed=1\u0026hideDevTools=1\u0026view=preview)\n- \u003cimg src=\"public/ts.png\" alt=\"ts\" width=\"16\" /\u003e [Instances array dynamic](https://stackblitz.com/edit/three-ezinstancedmesh2-instances-array-dynamic?file=src%2Fmain.ts\u0026embed=1\u0026hideDevTools=1\u0026view=preview)\n- \u003cimg src=\"public/ts.png\" alt=\"ts\" width=\"16\" /\u003e [Sorting](https://stackblitz.com/edit/three-ezinstancedmesh2-sorting?file=src%2Fmain.ts\u0026embed=1\u0026hideDevTools=1\u0026view=preview)\n- \u003cimg src=\"public/ts.png\" alt=\"ts\" width=\"16\" /\u003e [Uniforms per instance](https://stackblitz.com/edit/three-ezinstancedmesh2-custom-material?file=src%2Fmain.ts\u0026embed=1\u0026hideDevTools=1\u0026view=preview)\n- \u003cimg src=\"public/ts.png\" alt=\"ts\" width=\"16\" /\u003e [Dynamic BVH (no vite)](https://stackblitz.com/edit/three-ezinstancedmesh2-dynamic-bvh?file=index.ts\u0026embed=1\u0026hideDevTools=1\u0026view=preview)\n- \u003cimg src=\"public/ts.png\" alt=\"ts\" width=\"16\" /\u003e [Fast raycasting](https://stackblitz.com/edit/three-ezinstancedmesh2-fast-raycasting?file=src%2Fmain.ts\u0026embed=1\u0026hideDevTools=1\u0026view=preview)\n- \u003cimg src=\"public/ts.png\" alt=\"ts\" width=\"16\" /\u003e [LOD](https://stackblitz.com/edit/three-ezinstancedmesh2-instancedmeshlod?file=src%2Fmain.ts\u0026embed=1\u0026hideDevTools=1\u0026view=preview)\n- \u003cimg src=\"public/ts.png\" alt=\"ts\" width=\"16\" /\u003e [Shadow LOD](https://stackblitz.com/edit/three-ezinstancedmesh2-shadow-lod?file=src%2Fmain.ts\u0026embed=1\u0026hideDevTools=1\u0026view=preview)\n- \u003cimg src=\"public/ts.png\" alt=\"js\" width=\"16\" /\u003e [Skinning 3k instances](https://stackblitz.com/edit/three-ezinstancedmesh2-skinning?file=src%2Fmain.ts\u0026embed=1\u0026hideDevTools=1\u0026view=preview)\n- \u003cimg src=\"public/js.png\" alt=\"js\" width=\"16\" /\u003e [Dynamic adding with BVH](https://glitch.com/edit/#!/three-ez-instanced-mesh-dynamic-adding-with-bvh?path=main.js)\n- \u003cimg src=\"public/js.png\" alt=\"js\" width=\"16\" /\u003e [Skinning](https://glitch.com/edit/#!/instancedmesh2-skinning?path=main.js)\n\n**Using other libraries**\n- Threlte\n- \u003cimg src=\"public/ts.png\" alt=\"ts\" width=\"16\" /\u003e [React-three-fiber](https://stackblitz.com/edit/vitejs-vite-zahmbaan?file=src%2FApp.tsx) (thanks to [Saumac](https://github.com/saumac))\n\n## ❔ Need help?\n\nJoin us on [Discord](https://discord.gg/MVTwrdX3JM) or open an issue on GitHub.\n\n## ⭐ Like it?\n\nIf you like this project, please leave a star. Thank you! ❤️\n\n## 📚 Documentation\n\nThe documentation is available [here](https://agargaro.github.io/instanced-mesh).\n\n## ⬇️ Installation\n\nYou can install it via npm using the following command:\n\n```bash\nnpm install @three.ez/instanced-mesh\n```\n\nOr you can import it from CDN:\n\n```html\n\u003cscript type=\"importmap\"\u003e\n{\n  \"imports\": {\n    \"three\": \"https://cdn.jsdelivr.net/npm/three/build/three.module.js\",\n    \"three/addons/\": \"https://cdn.jsdelivr.net/npm/three/examples/jsm/\",\n    \"@three.ez/instanced-mesh\": \"https://cdn.jsdelivr.net/npm/@three.ez/instanced-mesh/build/index.js\",\n    \"bvh.js\": \"https://cdn.jsdelivr.net/npm/bvh.js/build/index.js\"\n  }\n}\n\u003c/script\u003e\n```\n\n## 🚀 Features\n\n### Per-instance frustum culling\n\nAvoiding rendering objects outside the camera frustum can drastically improve performance (especially for complex geometries). \u003cbr\u003e\nFrustum culling by default is performed by iterating all instances, [but it is possible to speed up this process by creating a spatial indexing data structure **(BVH)**](#spatial-indexing-dynamic-bvh). \u003cbr\u003e\n\nBy default `perObjectFrustumCulled` is `true`.\n\n### Sorting\n\nSorting can be used to decrease overdraw and render transparent objects. \u003cbr\u003e\n\nIt's possible to improve sort performance adding a `customSort`, like built-in `createRadixSort`.\n\nBy default `sortObjects` is `false`. \u003cbr\u003e\n\n```ts\nimport { createRadixSort } from '@three.ez/instanced-mesh';\n\nmyInstancedMesh.sortObjects = true;\nmyInstancedMesh.customSort = createRadixSort(myInstancedMesh);\n```\n\n### Spatial indexing (dynamic BVH)\n\n**To speed up raycasting and frustum culling**, a spatial indexing data structure can be created to contain the boundingBoxes of all instances. \u003cbr\u003e\nThis works very well if the instances are **mostly static** (updating a BVH can be expensive) and scattered in world space. \u003cbr\u003e\nSetting a margin makes BVH updating faster, but may make raycasting and frustum culling slightly slower.\n```ts\nmyInstancedMesh.computeBVH({ margin: 0 });\n```\n\n### Dynamic capacity\n\nManage a dynamic number of instances, automatically expanding the data buffers as needed to accommodate additional instances. \u003cbr\u003e\n\nIf not specified, `capacity` is `1000`. \u003cbr\u003e\n\n```ts\nconst myInstancedMesh = new InstancedMesh2(geometry, material, { capacity: count }); \n\nmyInstancedMesh.addInstances(count, (obj, index) =\u003e { ... }); // add instances and expand buffer if necessary\n\nmyInstancedMesh.removeInstances(id0, idx, ...);\n\nmyInstancedMesh.clearInstances(); // remove all instances\n```\n\n### Per-instance visibility\n\nSet the visibility status of each instance:\n\n```ts\nmyInstancedMesh.setVisibilityAt(index, false);\nmyInstancedMesh.instances[0].visible = false; // if instances array is created\n```\n\n### Per-instance opacity\n\nSet the opacity of each instance:\n\n```ts\nmyInstancedMesh.setOpacityAt(index, 0.5);\nmyInstancedMesh.instances[0].opacity = 0.5; // if instances array is created\n```\n\n### Object3D-like instances\n\nIt's possible to create an array of `InstancedEntity` **(Object3D-like)** in order to easily manipulate instances, using more memory.\n\n```ts\nconst myInstancedMesh = new InstancedMesh2(geometry, material, { createEntities: true });\n\nmyInstancedMesh.instances[0].customData = {};\nmyInstancedMesh.instances[0].position.random();\nmyInstancedMesh.instances[0].rotateX(Math.PI);\nmyInstancedMesh.instances[0].updateMatrix(); // necessary after transformations\n```     \n\n### Per-instance uniforms\n\nAssign unique shader uniforms to each instance, working with every materials.\n\n```ts\nmyInstancedMesh.initUniformsPerInstance({ fragment: { metalness: 'float', roughness: 'float', emissive: 'vec3' } });\n\nmyInstancedMesh.setUniformAt(index, 'metalness', 0.5);\nmyInstancedMesh.instances[0].setUniform('emissive', new Color('white')); // if instances array is created\n```\n\n### Level of Detail (LOD)\n\nImprove rendering performance by dynamically adjusting the detail level of instances based on their distance from the camera. \u003cbr\u003e\nUse simplified geometries for distant objects to optimize resources.\n\n```ts\nmyInstancedMesh.addLOD(geometryMid, material, 50);\nmyInstancedMesh.addLOD(geometryLow, material, 200);\n```     \n\n### Shadow LOD\n\nOptimize shadow rendering by reducing the detail level of instances casting shadows based on their distance from the camera.\n\n```ts\nmyInstancedMesh.addShadowLOD(geometryMid);\nmyInstancedMesh.addShadowLOD(geometryLow, 100);\n```    \n\n### Skinning\n\nApply skeletal animations to instances for more complex and dynamic movements.\n\n```ts\nmyInstancedMesh.initSkeleton(skeleton);\n\nmixer.update(time);\nmyInstancedMesh.setBonesAt(index);\n```   \n\n### Raycasting tips\n\nIf you are not using a BVH, you can set the `raycastOnlyFrustum` property to **true** to avoid iterating over all instances.\n\nIt's recommended to use [three-mesh-bvh](https://github.com/gkjohnson/three-mesh-bvh) to create a geometry BVH.\n\n## 🤝 Special thanks to\n\n- [gkjohnson](https://github.com/gkjohnson)\n- [manthrax](https://github.com/manthrax)\n- [jungle_hacker](https://github.com/lambocorp)\n\n## 📖 References\n\n- [three-mesh-bvh](https://github.com/gkjohnson/three-mesh-bvh)\n- [ErinCatto_DynamicBVH](https://box2d.org/files/ErinCatto_DynamicBVH_Full.pdf)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagargaro%2Finstanced-mesh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fagargaro%2Finstanced-mesh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagargaro%2Finstanced-mesh/lists"}