Three.js Skills for Claude Code

repository·main·Indexed 25 days ago

https://github.com/cloudai-x/threejs-skills

A curated collection of skill files designed to augment Claude Code with deep knowledge of the Three.js API, best practices, and 3D development patterns. Includes specialized modules for fundamentals, geometry, materials, lighting, textures, animation, loaders, shaders, post-processing, and interaction.

Tokens
52K
Snippets
154
Records
165
Agent score
85%

What's inside threejs-skills

  1. Overview of Three.js Light Types

    main

    Use the following table to choose the appropriate light type based on your scene requirements and performance budget:

    LightDescriptionShadow SupportCost
    AmbientLightUniform everywhereNoVery Low
    HemisphereLightSky/ground gradientNoVery Low
    DirectionalLightParallel rays (sun)YesLow
    PointLightOmnidirectional (bulb)YesMedium
    SpotLightCone-shapedYesMedium
    RectAreaLightArea light (window)No*High

    *RectAreaLight shadows require custom solutions.

  2. Overview of available Three.js skills

    main

    The repository contains several specialized skill files that Claude Code automatically loads based on your request context. The available skills are:

    SkillDescription
    threejs-fundamentalsScene setup, cameras, renderer, Object3D hierarchy, coordinate systems
    threejs-geometryBuilt-in shapes, BufferGeometry, custom geometry, instancing
    threejs-materialsPBR materials, basic/phong/standard materials, shader materials
    threejs-lightingLight types, shadows, environment lighting, light helpers
    threejs-texturesTexture types, UV mapping, environment maps, render targets
    threejs-animationKeyframe animation, skeletal animation, morph targets, animation mixing
    threejs-loadersGLTF/GLB loading, texture loading, async patterns, caching
    threejs-shadersGLSL basics, ShaderMaterial, uniforms, custom effects
    threejs-postprocessingEffectComposer, bloom, DOF, screen effects, custom passes
    threejs-interactionRaycasting, camera controls, mouse/touch input, object selection
  3. Overview of Three.js Material Types

    main

    Choose a material based on your lighting requirements and desired visual style:

    MaterialUse CaseLighting
    MeshBasicMaterialUnlit, flat colors, wireframesNo
    MeshLambertMaterialMatte surfaces, performanceYes (diffuse only)
    MeshPhongMaterialShiny surfaces, specular highlightsYes
    MeshStandardMaterialPBR, realistic materialsYes (PBR)
    MeshPhysicalMaterialAdvanced PBR, clearcoat, transmissionYes (PBR+)
    MeshToonMaterialCel-shaded, cartoon lookYes (toon)
    MeshNormalMaterialDebug normalsNo
    MeshDepthMaterialDepth visualizationNo
    ShaderMaterialCustom GLSL shadersCustom
    RawShaderMaterialFull shader controlCustom
  4. Overview of the Three.js Animation System

    main

    The Three.js animation system consists of three core components:

    1. AnimationClip: A container that holds keyframe data.
    2. AnimationMixer: The engine that plays animations on a specific root object and its descendants.
    3. AnimationAction: The controller used to manage the playback (play, stop, loop, etc.) of a specific AnimationClip via the mixer.
  5. Load GLTF with Draco compression

    main

    To load compressed GLTF models, use DRACOLoader in conjunction with GLTFLoader. You must provide a path to the Draco decoder files using setDecoderPath().

    import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
    import { DRACOLoader } from "three/addons/loaders/DRACOLoader.js";
    
    const dracoLoader = new DRACOLoader();
    dracoLoader.setDecoderPath(
      "https://www.gstatic.com/draco/versioned/decoders/1.5.6/",
    );
    dracoLoader.preload();
    
    const gltfLoader = new GLTFLoader();
    gltfLoader.setDRACOLoader(dracoLoader);
    
    gltfLoader.load("compressed-model.glb", (gltf) => {
      scene.add(gltf.scene);
    });
  6. Render Scene to a Texture

    main

    To use the output of a render as a texture on a material, create a WebGLRenderTarget, set the renderer's target to it, render the scene, and then reset the target to null.

    // Create render target
    const renderTarget = new THREE.WebGLRenderTarget(512, 512);
    
    // Render scene to target
    renderer.setRenderTarget(renderTarget);
    renderer.render(scene, camera);
    renderer.setRenderTarget(null);
    
    // Use texture
    const texture = renderTarget.texture;
    otherMaterial.map = texture;
  7. Optimize Shadow Performance

    main

    Use these techniques to improve shadow performance and quality:

    • Tight Frustum: Adjust the shadow camera's left, right, top, bottom, near, and far to cover only the necessary area.
    • Fix Shadow Acne: Use shadow.bias (depth bias) and shadow.normalBias (bias along normal).
    • Balance Map Size: Use 512 (low), 1024 (medium), 2048 (high), or 4096 (very high/expensive) for shadow.mapSize.
    // Tight shadow camera frustum
    const d = 10;
    dirLight.shadow.camera.left = -d;
    dirLight.shadow.camera.right = d;
    dirLight.shadow.camera.top = d;
    dirLight.shadow.camera.bottom = -d;
    dirLight.shadow.camera.near = 0.5;
    dirLight.shadow.camera.far = 30;
    
    // Fix shadow acne
    dirLight.shadow.bias = -0.0001; // Depth bias
    dirLight.shadow.normalBias = 0.02; // Bias along normal
    
    // Shadow map size (balance quality vs performance)
    // 512 - low quality
    // 1024 - medium quality
    // 2048 - high quality
    // 4096 - very high quality (expensive)
  8. Use Additive Blending for Animation Layers

    main

    Additive blending allows you to layer animations (like a 'breathing' effect) on top of a base pose. Use THREE.AnimationUtils.makeClipAdditive(clip) to convert a clip to additive mode, and set the action's blendMode to THREE.AdditiveAnimationBlendMode.

    // Convert clip to additive
    THREE.AnimationUtils.makeClipAdditive(additiveClip);
    
    // Apply as additive layer
    const additiveAction = mixer.clipAction(additiveClip);
    additiveAction.blendMode = THREE.AdditiveAnimationBlendMode;
    additiveAction.play();
  9. Quick Start: Load and apply a texture

    main

    To load a basic image texture and apply it to a material, use THREE.TextureLoader and assign the resulting texture to a material property like map.

    import * as THREE from "three";
    
    // Load texture
    const loader = new THREE.TextureLoader();
    const texture = loader.load("texture.jpg");
    
    // Apply to material
    const material = new THREE.MeshStandardMaterial({
      map: texture,
    });
  10. Optimize Post-Processing Performance

    main

    Post-processing can be GPU-intensive. Use these strategies to maintain performance:

    • Limit passes: Each pass requires a full-screen render.
    • Lower resolution: Use smaller render targets for expensive passes like blur.
    • Toggle effects: Use the .enabled property to disable unused passes.
    • Choose efficient AA: Use FXAA instead of MSAA for lower cost.
    • Device-specific logic: Disable expensive effects on mobile devices.
    // Disable pass
    bloomPass.enabled = false;
    
    // Reduce bloom resolution
    const bloomPass = new UnrealBloomPass(
      new THREE.Vector2(window.innerWidth / 2, window.innerHeight / 2),
      strength,
      radius,
      threshold,
    );
    
    // Only apply effects in high-performance scenarios
    const isMobile = /iPhone|iPad|Android/i.test(navigator.userAgent);
    if (!isMobile) {
      composer.addPass(expensivePass);
    }
  11. Use Three.js Shader Chunks in custom shaders

    main

    You can inject standard Three.js shader logic (like common functions or packing utilities) into your custom GLSL code using ShaderChunk. This allows you to use built-in utilities like perspectiveDepthToViewZ without manually defining them.

    import { ShaderChunk } from "three";
    
    const fragmentShader = `
      ${ShaderChunk.common}
      ${ShaderChunk.packing}
    
      uniform sampler2D depthTexture;
      varying vec2 vUv;
    
      void main() {
        float depth = texture2D(depthTexture, vUv).r;
        float linearDepth = perspectiveDepthToViewZ(depth, 0.1, 1000.0);
        gl_FragColor = vec4(vec3(-linearDepth / 100.0), 1.0);
      }
    `;