Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add hamzabellouch/agent-skills --skill webgl-and-threejs-3d-experiencesgit clone --depth 1 https://github.com/hamzabellouch/agent-skillsWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/hamzabellouch/agent-skills/webgl-and-threejs-3d-experiences)<a href="https://agentmods.dev/skills/hamzabellouch/agent-skills/webgl-and-threejs-3d-experiences"><img src="https://agentmods.dev/badge/skills/hamzabellouch/agent-skills/webgl-and-threejs-3d-experiences/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/hamzabellouch/agent-skills/webgl-and-threejs-3d-experiences"><img src="https://agentmods.dev/badge/skills/hamzabellouch/agent-skills/webgl-and-threejs-3d-experiences.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00048 | $0.02794 |
| Opus 5 | $0.00024 | $0.01397 |
| Sonnet 5 | $0.00010 | $0.00559 |
| Haiku 4.5 | $0.00005 | $0.00279 |
Grade A, and why
webgl-and-threejs-3d-experiences scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 8d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 350 lines — stays where its author put it; the contents beside it link to each section on GitHub.
WebGL & Three.js 3D Experiences Architecture Guide
Core Architectural Principles
1. Scene Graph Architecture & Render Lifecycle
- Unified Engine Class Pattern: Enforce OOP or functional composition encapsulating
WebGLRenderer,Scene,PerspectiveCamera, and RAF loop into a self-contained renderer manager. - Render Loop Delta Capping: Always cap
clock.getDelta()(e.g.,Math.min(delta, 0.1)) to avoid physics explosion/teleportation during window unfocus or frame drops. - Pixel Ratio Guardrails: Cap
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))to prevent mobile GPUs from rendering native 4K/8K viewports at unusable framerates.
2. GPU Memory Management & Resource Lifecycle
- Explicit Garbage Collection: JavaScript GC does not manage VRAM allocated to WebGL buffers, textures, geometries, or render targets.
- Disposal Traversal: Recursively traverse scenes and call
.dispose()on geometries, materials, textures, and render targets upon component unmount or scene switching. - Resource Pooling & Material Sharing: Instantiation of geometries and materials must happen outside animation loops. Share materials across meshes wherever possible.
3. High-Performance WebGL Techniques
- InstancedMesh: Use
InstancedMeshfor rendering thousands of repetitive objects (particles, trees, debris) using single draw calls. - BVH (Bounding Volume Hierarchy): Integrate
three-mesh-bvhfor sub-millisecond raycasting against high-poly meshes instead of brute-force triangle intersection checks. - Compressed Assets: Standardize on KTX2/Basis for textures and DRACO/Meshopt compression for GLTF/GLB models.
Production Code Examples
Example 1: Full Production Three.js Engine Lifecycle with Automatic GPU Disposal
Location: src/3d/Engine.ts
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
export class Engine {
private container: HTMLElement
private scene: THREE.Scene
private camera: THREE.PerspectiveCamera
private renderer: THREE.WebGLRenderer
private controls: OrbitControls
private clock: THREE.Clock
private animationFrameId: number | null = null
private isDisposed = false
constructor(container: HTMLElement) {
this.container = container
// 1. Scene Initialization
this.scene = new THREE.Scene()
this.scene.background = new THREE.Color('#0a0a0c')
// 2. Camera Setup
const aspect = container.clientWidth / container.clientHeight
this.camera = new THREE.PerspectiveCamera(60, aspect, 0.1, 1000)
this.camera.position.set(0, 5, 10)
// 3. WebGL Renderer Setup with Pixel Ratio Capping
this.renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: false,
powerPreference: 'high-performance'
})
this.renderer.setSize(container.clientWidth, container.clientHeight)
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
this.renderer.shadowMap.enabled = true
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
this.renderer.outputColorSpace = THREE.SRGBColorSpace
container.appendChild(this.renderer.domElement)
// 4. Controls & Time Tracking
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
this.controls.enableDamping = true
this.controls.dampingFactor = 0.05
this.clock = new THREE.Clock()
// 5. Setup Listeners & Start Loop
window.addEventListener('resize', this.onResize)
this.start()
}
private onResize = () => {
if (this.isDisposed) return
const width = this.container.clientWidth
const height = this.container.clientHeight
this.camera.aspect = width / height
this.camera.updateProjectionMatrix()
this.renderer.setSize(width, height)
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
}
private start() {
const tick = () => {
if (this.isDisposed) return
// Delta capping to prevent un-focused window physics explosions
const delta = Math.min(this.clock.getDelta(), 0.1)
this.controls.update()
this.renderer.render(this.scene, this.camera)
this.animationFrameId = requestAnimationFrame(tick)
}
tick()
}
public getScene(): THREE.Scene {
return this.scene
}
// Comprehensive GPU Memory Cleanup Pipeline
public dispose() {
this.isDisposed = true
if (this.animationFrameId !== null) {
cancelAnimationFrame(this.animationFrameId)
}
window.removeEventListener('resize', this.onResize)
this.controls.dispose()
// Recursive traversal and disposal of all geometries, materials, and textures
this.scene.traverse((object: THREE.Object3D) => {
if (!(object instanceof THREE.Mesh)) return
// Dispose geometry
object.geometry.dispose()
// Dispose material(s)
if (Array.isArray(object.material)) {
object.material.forEach((mat) => this.disposeMaterial(mat))
} else if (object.material) {
this.disposeMaterial(object.material)
}
})
this.renderer.dispose()
if (this.renderer.domElement && this.renderer.domElement.parentElement) {
this.renderer.domElement.parentElement.removeChild(this.renderer.domElement)
}
}
private disposeMaterial(material: THREE.Material) {
material.dispose()
// Dispose all potential texture maps on the material
for (const key of Object.keys(material)) {
const value = (material as any)[key]
if (value && value instanceof THREE.Texture) {
value.dispose()
}
}
}
}
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 8d ago First seen · 350 lines · 48 tokens per session scan A ad32d9f8749e
webgl-and-threejs-3d-experiences is a skill published in the GitHub repository hamzabellouch/agent-skills (4 stars, last pushed 1mo ago), licensed MIT. It adds 48 tokens to every session and 2,794 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-03.
Other skills, from other repositories
gsap-plugins
Official GSAP skill for GSAP plugins — registration, ScrollToPlugin, ScrollSmoother, Flip, Draggable, Inertia, Observer, SplitText, ScrambleText, SVG and physics plugins, CustomEase, EasePack, CustomWiggle, CustomBounce, GSDevTools. Use when the user asks about a GSAP plugin, scroll-to, flip animations, draggable, SVG…
threejs-interaction
Three.js interaction - raycasting, controls, mouse/touch input, object selection. Use when handling user input, implementing click detection, adding camera controls, or creating interactive 3D experiences.
threejs-materials
Three.js materials - PBR, basic, phong, shader materials, material properties. Use when styling meshes, working with textures, creating custom shaders, or optimizing material performance.
threejs-postprocessing
Three.js post-processing - EffectComposer, bloom, DOF, screen effects. Use when adding visual effects, color grading, blur, glow, or creating custom screen-space shaders.
threejs-shaders
Three.js shaders - GLSL, ShaderMaterial, uniforms, custom effects. Use when creating custom visual effects, modifying vertices, writing fragment shaders, or extending built-in materials.
threejs-textures
Three.js textures - texture types, UV mapping, environment maps, texture settings. Use when working with images, UV coordinates, cubemaps, HDR environments, or texture optimization.