update: add agent.md + skills

This commit is contained in:
2026-04-14 09:20:30 +02:00
parent afd72b9f6c
commit 82c4b612bf
8 changed files with 672 additions and 6 deletions
+88
View File
@@ -0,0 +1,88 @@
# Skill — GPU Memory Management
## Principle
Dispose only what you own. Never blindly traverse and dispose shared or cached assets.
## What to dispose
| Resource | When to dispose |
| ---------------------------------- | ------------------------------------ |
| Custom `THREE.ShaderMaterial` | When the component using it unmounts |
| `THREE.WebGLRenderTarget` | When the pass or effect is destroyed |
| Manually created `THREE.Geometry` | When no longer needed |
| Manually created `THREE.Texture` | When no longer needed |
| Cloned scenes with owned materials | When the clone is removed |
## What NOT to dispose
| Resource | Why |
| -------------------------------- | ----------------------------------------------- |
| GLTF scenes loaded via `useGLTF` | drei caches them — disposing breaks other users |
| Textures loaded via `useTexture` | drei caches them — same reason |
| Shared materials from a GLTF | Other instances may reference them |
## Dispose utility
```ts
// src/utils/Dispose.ts
import * as THREE from "three";
export class Dispose {
static material(material: THREE.Material): void {
for (const value of Object.values(material)) {
if (value instanceof THREE.Texture) {
value.dispose();
}
}
material.dispose();
}
static mesh(mesh: THREE.Mesh): void {
mesh.geometry?.dispose();
const materials = Array.isArray(mesh.material)
? mesh.material
: [mesh.material];
for (const mat of materials) {
if (mat) this.material(mat);
}
}
static renderTarget(rt: THREE.WebGLRenderTarget): void {
rt.texture.dispose();
rt.dispose();
}
}
```
## Usage in React components
```tsx
useEffect(() => {
const material = new THREE.ShaderMaterial({ vertexShader, fragmentShader });
meshRef.current.material = material;
return () => {
Dispose.material(material);
};
}, []);
```
## Usage in managers
```ts
destroy(): void {
if (this.renderTarget) {
Dispose.renderTarget(this.renderTarget)
this.renderTarget = null
}
SomeManager._instance = null
}
```
## Rules
- Every `useEffect` that creates a GPU resource must return a cleanup that disposes it
- Every manager `destroy()` must dispose its owned GPU resources
- Never call `.dispose()` on assets returned by drei loaders (`useGLTF`, `useTexture`)
- When in doubt, don't dispose — a small leak is better than a crash from disposing shared resources