3d-visuals
Skill3 starsChanged 10 days agoMITView on GitHub
Activate this skill for tasks involving Three.js, WebGL, shaders, 3D models, canvas rendering, or spatial visuals. Use when building interactive 3D web experiences, optimizing GPU memory, or rendering GLTF scenes.
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 4 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 30
InstancedMesh: When rendering many identical geometries (e.g., thousands of particles, trees, or repetitive items), use THREE.InstancedMesh …
- Distinctive: line 34
Always size textures to powers of two (POT: 512x512, 1024x1024, 2048x2048) for optimal GPU mipmapping.
- Distinctive: line 35
Prefer KTX2 / Basis Universal compressed textures over raw PNGs/JPEGs.
- Very specific: line 46
Draco Compression: Use Draco or Meshopt compression (gltf-pipeline or gltfpack) to reduce geometry file sizes by 70-90%.
- Distinctive: line 51
Always load 3D assets asynchronously with a visible loading state or progressive disclosure:
- Distinctive: line 111
Always pass viewport resolution to shaders to prevent distortion on resize:
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
3D Visuals & WebGL Engineering
Scope: Three.js, React Three Fiber (R3F), GLSL shader programming, GLTF/GLB 3D model optimization, Draco compression, GPU draw call batching, memory lifecycle management, and spatial visual experiences.
When to Activate
- Creating 3D product visualizers, interactive globes, or procedural canvas backgrounds
- Building Three.js or React Three Fiber (R3F) scenes
- Writing custom vertex and fragment shaders in GLSL
- Loading, optimizing, and animating GLTF/GLB models
- Debugging WebGL performance bottlenecks, memory leaks, and frame rate drops
- Implementing accessibility fallbacks for 3D canvas elements
1. WebGL Performance Fundamentals
Draw Call Minimization
The primary bottleneck in WebGL is often CPU-to-GPU communication (draw calls), not raw polygon count.
- InstancedMesh: When rendering many identical geometries (e.g., thousands of particles, trees, or repetitive items), use
THREE.InstancedMeshrather than creating individualTHREE.Meshinstances. This renders thousands of objects in a single draw call. - Geometry Merging: Merge static, non-moving geometries sharing the same material using
BufferGeometryUtils.mergeGeometries.
Texture & Memory Budget
- Always size textures to powers of two (POT: 512x512, 1024x1024, 2048x2048) for optimal GPU mipmapping.
- Prefer KTX2 / Basis Universal compressed textures over raw PNGs/JPEGs. KTX2 remains compressed directly in GPU VRAM, dramatically reducing mobile crash rates.
- Cap render target resolution on high-DPI displays:
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // Never exceed 2
2. GLTF / GLB 3D Model Optimization
Pipeline Optimization
- Draco Compression: Use Draco or Meshopt compression (
gltf-pipelineorgltfpack) to reduce geometry file sizes by 70-90%. - Remove Unused Attributes: Strip unused vertex colors, secondary UV channels, and excessive bone weights.
- Decimation: Simplify polygon density for web delivery. High-poly models belong in offline rendering, not mobile WebGL.
Loading Strategy
Always load 3D assets asynchronously with a visible loading state or progressive disclosure:
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/');
const loader = new GLTFLoader();
loader.setDRACOLoader(dracoLoader);
loader.load('/models/product.glb', (gltf) => {
scene.add(gltf.scene);
}, onProgress, onError);3. Strict WebGL Memory Management (Prevent Leaks)
JavaScript garbage collection DOES NOT automatically free WebGL GPU memory. Every geometry, material, texture, and render target MUST be explicitly disposed of:
function cleanupObject(obj) {
if (!obj) return;
if (obj.geometry) {
obj.geometry.dispose();
}
if (obj.material) {
if (Array.isArray(obj.material)) {
obj.material.forEach(cleanMaterial);
} else {
cleanMaterial(obj.material);
}
}
}
function cleanMaterial(material) {
material.dispose();
// Dispose all associated textures
for (const key of Object.keys(material)) {
const value = material[key];
if (value && typeof value === 'object' && 'minFilter' in value) {
value.dispose();
}
}
}
// In React / R3F, run cleanup on component unmount4. Custom GLSL Shaders
Shader Structure
- Vertex Shader: Handles coordinate transformations (model space → world space → view space → clip space). Keep calculations here rather than fragment shaders when values can be smoothly interpolated.
- Fragment Shader: Computes the final color per pixel. Avoid branching (
if/else) inside inner loops; prefer GLSL math intrinsics (mix,step,smoothstep,clamp).
Responsive Screen Coordinates & Aspect Ratio
Always pass viewport resolution to shaders to prevent distortion on resize:
uniform vec2 u_resolution;
uniform float u_time;
void main() {
vec2 uv = (gl_FragCoord.xy * 2.0 - u_resolution.xy) / min(u_resolution.x, u_resolution.y);
// Procedural shader logic...
}5. Accessibility & Mobile Fallbacks
- Provide an accessible HTML description or static image fallback for users whose hardware or browser does not support WebGL or has hardware acceleration disabled.
- Pause the render loop (
cancelAnimationFrame) when the canvas scrolls out of the viewport (usingIntersectionObserver) to conserve user battery life:const observer = new IntersectionObserver(([entry]) => { isCanvasVisible = entry.isIntersecting; }); observer.observe(renderer.domElement); - Disable heavy post-processing effects (bloom, depth of field, ambient occlusion) on low-power devices.
In this repository50 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .cursor/rules/always-on.mdcCursor rule
- 3d-visualsSkill
- agent-researchSkill
- api-architectureSkill
- assets-mediaSkill
- cavemanSkill
- cloudflare-expertSkill
- devops-cicdSkill
- firebase-expertSkill
- git-collaborationSkill
- gravitasSkill
- gsd-coreSkill
- llm-optimizationSkill
- mobile-engineeringSkill
- ponytailSkill
- postgres-ecosystemSkill
- security-auditorSkill
- sentry-expertSkill
- seo-marketingSkill
- state-managementSkill
- testing-qaSkill
- ui-ux-pro-maxSkill
- ux-researchSkill
- web-animationSkill
- web-gamedevSkill
- agent-researchSkill
- api-architectureSkill
- assets-mediaSkill
- cavemanSkill
- cloudflare-expertSkill
- devops-cicdSkill
- firebase-expertSkill
- git-collaborationSkill
- gravitasSkill
- gsd-coreSkill
- llm-optimizationSkill
- mobile-engineeringSkill
- ponytailSkill
- postgres-ecosystemSkill
- security-auditorSkill
- sentry-expertSkill
- seo-marketingSkill
- state-managementSkill
- testing-qaSkill
- ui-ux-pro-maxSkill
- ux-researchSkill
- web-animationSkill
- web-gamedevSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

