### Three.js SpotLight Setup and Target Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md This example shows how to create a SpotLight in Three.js, which emits light in a cone shape, similar to a flashlight. It includes setting the light's position, its target, and configuring properties like angle, penumbra, distance, and decay. ```javascript // SpotLight(color, intensity, distance, angle, penumbra, decay) const spotLight = new THREE.SpotLight(0xffffff, 1, 100, Math.PI / 6, 0.5, 2); spotLight.position.set(0, 10, 0); // Target (light points at this) spotLight.target.position.set(0, 0, 0); scene.add(spotLight.target); scene.add(spotLight); // Properties spotLight.angle; // Cone angle (radians, max Math.PI/2) spotLight.penumbra; // Soft edge (0-1) spotLight.distance; // Range spotLight.decay; // Falloff ``` -------------------------------- ### Three.js Interaction: Quick Start with Raycasting and OrbitControls Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-interaction/SKILL.md A quick start guide demonstrating basic Three.js interaction. It sets up OrbitControls for camera manipulation and implements raycasting to detect object clicks. Requires Three.js and OrbitControls. ```javascript import * as THREE from "three"; import { OrbitControls } from "three/addons/controls/OrbitControls.js"; // Camera controls const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; // Raycasting for click detection const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); function onClick(event) { mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(scene.children); if (intersects.length > 0) { console.log("Clicked:", intersects[0].object); } } window.addEventListener("click", onClick); ``` -------------------------------- ### Three.js Shadow Setup and Configuration Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md Provides a comprehensive guide to enabling and optimizing shadows in Three.js. This involves enabling shadows on the renderer, lights, and meshes, as well as configuring shadow camera frustums, bias, and map sizes for quality and performance. It also includes an example for creating fast, fake contact shadows. ```javascript // 1. Enable on renderer renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Shadow map types: // THREE.BasicShadowMap - fastest, low quality // THREE.PCFShadowMap - default, filtered // THREE.PCFSoftShadowMap - softer edges // THREE.VSMShadowMap - variance shadow map // 2. Enable on light light.castShadow = true; // 3. Enable on objects mesh.castShadow = true; mesh.receiveShadow = true; // Ground plane floor.receiveShadow = true; floor.castShadow = false; // Usually false for floors ``` ```javascript // 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) ``` ```javascript import { ContactShadows } from "three/examples/jsm/objects/ContactShadows.js"; const contactShadows = new ContactShadows({ resolution: 512, blur: 2, opacity: 0.5, scale: 10, position: [0, 0, 0], }); scene.add(contactShadows); ``` -------------------------------- ### Basic Three.js Lighting Setup Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md This snippet demonstrates the fundamental setup for lighting in a Three.js scene, including adding an ambient light for overall illumination and a directional light to simulate a sun-like source. It requires the 'three' library. ```javascript import * as THREE from "three"; // Basic lighting setup const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 1); directionalLight.position.set(5, 5, 5); scene.add(directionalLight); ``` -------------------------------- ### Three.js EffectComposer Setup Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-postprocessing/SKILL.md Demonstrates the basic setup for Three.js's EffectComposer, including adding a RenderPass and handling window resize events. This is essential for managing multiple post-processing effects in sequence. ```javascript import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js"; import { RenderPass } from "three/addons/postprocessing/RenderPass.js"; const composer = new EffectComposer(renderer); // First pass: render scene const renderPass = new RenderPass(scene, camera); composer.addPass(renderPass); // Add more passes... composer.addPass(effectPass); // Last pass should render to screen effectPass.renderToScreen = true; // Default for last pass // Handle resize function onResize() { const width = window.innerWidth; const height = window.innerHeight; camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height); composer.setSize(width, height); } ``` -------------------------------- ### Three.js Post-Processing Quick Start Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-postprocessing/SKILL.md A quick start guide to setting up Three.js post-processing with EffectComposer, including rendering the scene and adding a bloom effect. This is useful for quickly integrating visual effects into your Three.js application. ```javascript import * as THREE from "three"; import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js"; import { RenderPass } from "three/addons/postprocessing/RenderPass.js"; import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js"; // Setup composer const composer = new EffectComposer(renderer); // Render scene const renderPass = new RenderPass(scene, camera); composer.addPass(renderPass); // Add bloom const bloomPass = new UnrealBloomPass( new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, // strength 0.4, // radius 0.85, // threshold ); composer.addPass(bloomPass); // Animation loop - use composer instead of renderer function animate() { requestAnimationFrame(animate); composer.render(); // NOT renderer.render() } ``` -------------------------------- ### Three.js HemisphereLight Configuration Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md This example illustrates the setup of a HemisphereLight in Three.js, which simulates lighting from a sky and ground color, ideal for outdoor scenes. It includes setting its position and demonstrates accessing its color and intensity properties. ```javascript // HemisphereLight(skyColor, groundColor, intensity) const hemi = new THREE.HemisphereLight(0x87ceeb, 0x8b4513, 0.6); hemi.position.set(0, 50, 0); scene.add(hemi); // Properties hemi.color; // Sky color hemi.groundColor; // Ground color hemi.intensity; ``` -------------------------------- ### Three.js RawShaderMaterial Example Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-materials/SKILL.md Demonstrates how to create a custom material using THREE.RawShaderMaterial, providing complete control over vertex and fragment shaders. This is useful for advanced rendering effects where built-in materials are insufficient. ```javascript const material = new THREE.RawShaderMaterial({ uniforms: { projectionMatrix: { value: camera.projectionMatrix }, modelViewMatrix: { value: new THREE.Matrix4() }, }, vertexShader: ` precision highp float; attribute vec3 position; uniform mat4 projectionMatrix; uniform mat4 modelViewMatrix; void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` precision highp float; void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } `, }); ``` -------------------------------- ### Quick Start: Load and Apply a Texture in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-textures/SKILL.md This snippet demonstrates the basic process of loading an image texture using `TextureLoader` and applying it to a `MeshStandardMaterial` in Three.js. It requires the `three` library. ```javascript 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, }); ``` -------------------------------- ### Indoor Studio Lighting in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md Creates an indoor studio lighting environment using multiple RectAreaLight instances. This setup requires initializing RectAreaLightUniformsLib and configuring individual lights with position, size, and intensity. ```javascript // Multiple area lights RectAreaLightUniformsLib.init(); const light1 = new THREE.RectAreaLight(0xffffff, 5, 2, 2); light1.position.set(3, 3, 3); light1.lookAt(0, 0, 0); scene.add(light1); const light2 = new THREE.RectAreaLight(0xffffff, 3, 2, 2); light2.position.set(-3, 3, 3); light2.lookAt(0, 0, 0); scene.add(light2); // Ambient fill const ambient = new THREE.AmbientLight(0x404040, 0.2); scene.add(ambient); ``` -------------------------------- ### Three.js Raycasting: Basic Setup and Intersection Data Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-interaction/SKILL.md Demonstrates the fundamental setup of Three.js Raycaster for detecting intersections with objects in the scene. It covers creating a raycaster, setting its origin and direction, and interpreting the intersection results. Dependencies include Three.js. ```javascript const raycaster = new THREE.Raycaster(); // From camera (mouse picking) raycaster.setFromCamera(mousePosition, camera); // From any origin and direction raycaster.set(origin, direction); // origin: Vector3, direction: normalized Vector3 // Get intersections const intersects = raycaster.intersectObjects(objects, recursive); // intersects array contains: // { // distance: number, // Distance from ray origin // point: Vector3, // Intersection point in world coords // face: Face3, // Intersected face // faceIndex: number, // Face index // object: Object3D, // Intersected object // uv: Vector2, // UV coordinates at intersection // uv1: Vector2, // Second UV channel // normal: Vector3, // Interpolated face normal // instanceId: number // For InstancedMesh // } ``` -------------------------------- ### Three-Point Lighting Setup in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md Implements a standard three-point lighting setup using DirectionalLight and AmbientLight. This setup includes a key light, fill light, back light, and ambient light to illuminate a scene effectively. ```javascript // Key light (main light) const keyLight = new THREE.DirectionalLight(0xffffff, 1); keyLight.position.set(5, 5, 5); scene.add(keyLight); // Fill light (softer, opposite side) const fillLight = new THREE.DirectionalLight(0xffffff, 0.5); fillLight.position.set(-5, 3, 5); scene.add(fillLight); // Back light (rim lighting) const backLight = new THREE.DirectionalLight(0xffffff, 0.3); backLight.position.set(0, 5, -5); scene.add(backLight); // Ambient fill const ambient = new THREE.AmbientLight(0x404040, 0.3); scene.add(ambient); ``` -------------------------------- ### Three.js Lighting Setup Source: https://context7.com/cloudai-x/threejs-skills/llms.txt Demonstrates the setup of various light types in Three.js: AmbientLight for uniform illumination, DirectionalLight for sun-like effects, PointLight for bulb-like sources, and SpotLight for focused beams. It also includes enabling shadows on the renderer and scene objects. ```javascript import * as THREE from "three"; // AmbientLight - Uniform everywhere const ambient = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambient); // DirectionalLight - Parallel rays (sun) const dirLight = new THREE.DirectionalLight(0xffffff, 1); dirLight.position.set(5, 10, 5); dirLight.castShadow = true; dirLight.shadow.mapSize.width = 2048; dirLight.shadow.mapSize.height = 2048; scene.add(dirLight); // PointLight - Omnidirectional (bulb) const pointLight = new THREE.PointLight(0xffffff, 1, 100, 2); pointLight.position.set(0, 5, 0); pointLight.castShadow = true; scene.add(pointLight); // SpotLight - Cone-shaped const spotLight = new THREE.SpotLight(0xffffff, 1, 100, Math.PI / 6, 0.5, 2); spotLight.position.set(0, 10, 0); spotLight.castShadow = true; scene.add(spotLight); // Enable shadows on renderer renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Enable shadows on objects mesh.castShadow = true; floor.receiveShadow = true; ``` -------------------------------- ### Three.js PointLight Setup and Properties Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md This snippet demonstrates how to create a PointLight in Three.js, simulating a light source emitting light in all directions from a single point. It includes setting the light's position and configuring its distance and decay properties for falloff. ```javascript // PointLight(color, intensity, distance, decay) const pointLight = new THREE.PointLight(0xffffff, 1, 100, 2); pointLight.position.set(0, 5, 0); scene.add(pointLight); // Properties pointLight.distance; // Maximum range (0 = infinite) pointLight.decay; // Light falloff (physically correct = 2) ``` -------------------------------- ### Three.js Scene Setup and Fundamentals Source: https://context7.com/cloudai-x/threejs-skills/llms.txt Sets up a basic Three.js scene with a camera, renderer, a cube mesh, ambient and directional lights, and an animation loop. It also includes a resize handler for responsiveness. Requires the Three.js library. ```javascript import * as THREE from "three"; // Create scene, camera, renderer const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); document.body.appendChild(renderer.domElement); // Add a mesh const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // Add light scene.add(new THREE.AmbientLight(0xffffff, 0.5)); const dirLight = new THREE.DirectionalLight(0xffffff, 1); dirLight.position.set(5, 5, 5); scene.add(dirLight); camera.position.z = 5; // Animation loop const clock = new THREE.Clock(); function animate() { const delta = clock.getDelta(); cube.rotation.x += delta; cube.rotation.y += delta; requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); // Handle resize window.addEventListener("resize", () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); ``` -------------------------------- ### Create Three.js ShaderMaterial with Basic Shaders Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-shaders/SKILL.md Demonstrates the creation of a basic ShaderMaterial in Three.js, defining simple vertex and fragment shaders. This is useful for getting started with custom shader effects. ```javascript import * as THREE from "three"; const material = new THREE.ShaderMaterial({ uniforms: { time: { value: 0 }, color: { value: new THREE.Color(0xff0000) }, }, vertexShader: ` void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` uniform vec3 color; void main() { gl_FragColor = vec4(color, 1.0); } `, }); // Update in animation loop material.uniforms.time.value = clock.getElapsedTime(); ``` -------------------------------- ### Custom ShaderPass Example in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-postprocessing/SKILL.md Demonstrates how to create a custom post-processing effect using ShaderPass in Three.js. This example includes a basic vertex and fragment shader that applies a wave distortion to the rendered image. It shows how to define uniforms and update them dynamically. ```javascript import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js"; const CustomShader = { uniforms: { tDiffuse: { value: null }, // Required: input texture time: { value: 0 }, intensity: { value: 1.0 }, }, vertexShader: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` uniform sampler2D tDiffuse; uniform float time; uniform float intensity; varying vec2 vUv; void main() { vec2 uv = vUv; // Wave distortion uv.x += sin(uv.y * 10.0 + time) * 0.01 * intensity; vec4 color = texture2D(tDiffuse, uv); gl_FragColor = color; } `, }; const customPass = new ShaderPass(CustomShader); composer.addPass(customPass); // Update in animation loop customPass.uniforms.time.value = clock.getElapsedTime(); ``` -------------------------------- ### Initialize Three.js Scene, Camera, and Renderer Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-fundamentals/SKILL.md Sets up a basic Three.js scene with a perspective camera and WebGL renderer. It includes adding a simple cube mesh and ambient/directional lights. Handles window resizing to maintain aspect ratio and renderer size. This is a common starting point for most Three.js applications. ```javascript import * as THREE from "three"; // Create scene, camera, renderer const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000, ); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); document.body.appendChild(renderer.domElement); // Add a mesh const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // Add light scene.add(new THREE.AmbientLight(0xffffff, 0.5)); const dirLight = new THREE.DirectionalLight(0xffffff, 1); dirLight.position.set(5, 5, 5); scene.add(dirLight); camera.position.z = 5; // Animation loop function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate(); // Handle resize window.addEventListener("resize", () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); ``` -------------------------------- ### Three.js OrbitControls: Camera Manipulation Setup Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-interaction/SKILL.md Details the setup and configuration of Three.js OrbitControls for interactive camera movement. It covers enabling damping, setting rotation and zoom limits, enabling/disabling pan and rotate, and configuring auto-rotation. Requires Three.js and OrbitControls. ```javascript import { OrbitControls } from "three/addons/controls/OrbitControls.js"; const controls = new OrbitControls(camera, renderer.domElement); // Damping (smooth movement) controls.enableDamping = true; controls.dampingFactor = 0.05; // Rotation limits controls.minPolarAngle = 0; // Top controls.maxPolarAngle = Math.PI / 2; // Horizon controls.minAzimuthAngle = -Math.PI / 4; // Left controls.maxAzimuthAngle = Math.PI / 4; // Right // Zoom limits controls.minDistance = 2; controls.maxDistance = 50; // Enable/disable features controls.enableRotate = true; controls.enableZoom = true; controls.enablePan = true; // Auto-rotate controls.autoRotate = true; controls.autoRotateSpeed = 2.0; // Target (orbit point) controls.target.set(0, 1, 0); // Update in animation loop function animate() { controls.update(); // Required for damping and auto-rotate renderer.render(scene, camera); } ``` -------------------------------- ### Three.js DirectionalLight Setup and Target Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md This snippet shows how to create a DirectionalLight in Three.js, simulating parallel light rays like those from the sun. It includes setting the light's position and its target, which defines the direction the light points towards. ```javascript // DirectionalLight(color, intensity) const dirLight = new THREE.DirectionalLight(0xffffff, 1); dirLight.position.set(5, 10, 5); // Light points at target (default: 0, 0, 0) dirLight.target.position.set(0, 0, 0); scene.add(dirLight.target); scene.add(dirLight); ``` -------------------------------- ### Three.js Material Performance Tips and Pooling Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-materials/SKILL.md Provides performance optimization strategies for Three.js materials, including reusing materials for draw call batching, avoiding transparency when possible, using alpha testing, choosing simpler materials, and limiting lights. Includes an example of material pooling. ```javascript // Material pooling const materialCache = new Map(); function getMaterial(color) { const key = color.toString(16); if (!materialCache.has(key)) { materialCache.set(key, new THREE.MeshStandardMaterial({ color })); } return materialCache.get(key); } // Dispose when done material.dispose(); ``` -------------------------------- ### GLSL Performance Optimization Example Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-shaders/SKILL.md Illustrates a performance optimization technique in GLSL by replacing an `if/else` statement with `mix` and `step` functions. This avoids branching, which can improve shader performance. ```glsl // Instead of: if (value > 0.5) { color = colorA; } else { color = colorB; } // Use: color = mix(colorB, colorA, step(0.5, value)); ``` -------------------------------- ### Configure MeshStandardMaterial (PBR) in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-materials/SKILL.md Provides a comprehensive example of configuring `MeshStandardMaterial` for PBR rendering in Three.js. It covers essential properties like color, roughness, metalness, and various texture maps for albedo, roughness, metalness, normal, AO, and displacement. ```javascript const material = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0.5, // 0 = mirror, 1 = diffuse metalness: 0.0, // 0 = dielectric, 1 = metal // Textures map: colorTexture, // Albedo/base color roughnessMap: roughTexture, // Per-pixel roughness metalnessMap: metalTexture, // Per-pixel metalness normalMap: normalTexture, // Surface detail normalScale: new THREE.Vector2(1, 1), aoMap: aoTexture, // Ambient occlusion (uses uv2!) aoMapIntensity: 1, displacementMap: dispTexture, // Vertex displacement displacementScale: 0.1, displacementBias: 0, // Emissive emissive: 0x000000, emissiveIntensity: 1, emissiveMap: emissiveTexture, // Environment envMap: envTexture, envMapIntensity: 1, // Other flatShading: false, wireframe: false, fog: true, }); // Note: aoMap requires second UV channel geometry.setAttribute("uv2", geometry.attributes.uv); ``` -------------------------------- ### Rectangular Area Light Setup in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md Demonstrates how to create and add a RectAreaLight to a Three.js scene. This light type is suitable for soft, realistic lighting. It requires initializing RectAreaLightUniformsLib and optionally uses RectAreaLightHelper for visualization. Note that it only works with MeshStandardMaterial and MeshPhysicalMaterial and does not cast shadows natively. ```javascript import { RectAreaLightHelper } from "three/examples/jsm/helpers/RectAreaLightHelper.js"; import { RectAreaLightUniformsLib } from "three/examples/jsm/lights/RectAreaLightUniformsLib.js"; // Must initialize uniforms first RectAreaLightUniformsLib.init(); // RectAreaLight(color, intensity, width, height) const rectLight = new THREE.RectAreaLight(0xffffff, 5, 4, 2); rectLight.position.set(0, 5, 0); rectLight.lookAt(0, 0, 0); scene.add(rectLight); // Helper const helper = new RectAreaLightHelper(rectLight); rectLight.add(helper); // Note: Only works with MeshStandardMaterial and MeshPhysicalMaterial // Does not cast shadows natively ``` -------------------------------- ### Three.js Basic Shape Geometries Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-geometry/SKILL.md Provides examples for creating various basic geometric shapes in Three.js, including Box, Sphere, Plane, Circle, Cylinder, Cone, Torus, TorusKnot, and Ring geometries. Each shape has specific parameters for customization. ```javascript // Box - width, height, depth, widthSegments, heightSegments, depthSegments new THREE.BoxGeometry(1, 1, 1, 1, 1, 1); // Sphere - radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength new THREE.SphereGeometry(1, 32, 32); new THREE.SphereGeometry(1, 32, 32, 0, Math.PI * 2, 0, Math.PI); // Full sphere new THREE.SphereGeometry(1, 32, 32, 0, Math.PI); // Hemisphere // Plane - width, height, widthSegments, heightSegments new THREE.PlaneGeometry(10, 10, 1, 1); // Circle - radius, segments, thetaStart, thetaLength new THREE.CircleGeometry(1, 32); new THREE.CircleGeometry(1, 32, 0, Math.PI); // Semicircle // Cylinder - radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded new THREE.CylinderGeometry(1, 1, 2, 32, 1, false); new THREE.CylinderGeometry(0, 1, 2, 32); // Cone new THREE.CylinderGeometry(1, 1, 2, 6); // Hexagonal prism // Cone - radius, height, radialSegments, heightSegments, openEnded new THREE.ConeGeometry(1, 2, 32, 1, false); // Torus - radius, tube, radialSegments, tubularSegments, arc new THREE.TorusGeometry(1, 0.4, 16, 100); // TorusKnot - radius, tube, tubularSegments, radialSegments, p, q new THREE.TorusKnotGeometry(1, 0.4, 100, 16, 2, 3); // Ring - innerRadius, outerRadius, thetaSegments, phiSegments new THREE.RingGeometry(0.5, 1, 32, 1); ``` -------------------------------- ### Three.js Light Helper Visualization Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md Shows how to add visual helpers for various light types in Three.js to aid in debugging and scene setup. This includes helpers for DirectionalLight, PointLight, SpotLight, HemisphereLight, and RectAreaLight. Helpers need to be updated manually if the light's properties change. ```javascript import { RectAreaLightHelper } from "three/examples/jsm/helpers/RectAreaLightHelper.js"; // DirectionalLight helper const dirHelper = new THREE.DirectionalLightHelper(dirLight, 5); scene.add(dirHelper); // PointLight helper const pointHelper = new THREE.PointLightHelper(pointLight, 1); scene.add(pointHelper); // SpotLight helper const spotHelper = new THREE.SpotLightHelper(spotLight); scene.add(spotHelper); // Hemisphere helper const hemiHelper = new THREE.HemisphereLightHelper(hemiLight, 5); scene.add(hemiHelper); // RectAreaLight helper const rectHelper = new RectAreaLightHelper(rectLight); rectLight.add(rectHelper); // Update helpers when light changes dirHelper.update(); spotHelper.update(); ``` -------------------------------- ### Light Probes for Ambient Lighting in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md Details how to use Light Probes in Three.js to capture lighting from a specific point in space, providing realistic ambient lighting for objects. Examples show generating light probes from cube textures or render targets using LightProbeGenerator. ```javascript import { LightProbeGenerator } from "three/examples/jsm/lights/LightProbeGenerator.js"; // Generate from cube texture const lightProbe = new THREE.LightProbe(); scene.add(lightProbe); lightProbe.copy(LightProbeGenerator.fromCubeTexture(cubeTexture)); // Or from render target const cubeCamera = new THREE.CubeCamera( 0.1, 100, new THREE.WebGLCubeRenderTarget(256), ); cubeCamera.update(renderer, scene); lightProbe.copy( LightProbeGenerator.fromCubeRenderTarget(renderer, cubeCamera.renderTarget), ); ``` -------------------------------- ### Update InstancedMesh and Raycasting in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-geometry/SKILL.md Provides code examples for updating individual instances within an InstancedMesh at runtime and performing raycasting to identify which instance was hit. It shows how to retrieve, modify, and set the matrix for a specific instance, and how to access the `instanceId` from raycast intersection results. ```javascript // Update single instance const matrix = new THREE.Matrix4(); instancedMesh.getMatrixAt(index, matrix); // Modify matrix... instancedMesh.setMatrixAt(index, matrix); instancedMesh.instanceMatrix.needsUpdate = true; // Raycasting with instanced mesh const intersects = raycaster.intersectObject(instancedMesh); if (intersects.length > 0) { const instanceId = intersects[0].instanceId; } ``` -------------------------------- ### Initialize and Use PointerLockControls in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-interaction/SKILL.md Illustrates the setup and usage of PointerLockControls for capturing the mouse pointer within the browser window, commonly used in FPS games for seamless camera control. It requires the PointerLockControls module and event listeners for pointer locking and movement input. ```javascript import { PointerLockControls } from "three/addons/controls/PointerLockControls.js"; const controls = new PointerLockControls(camera, document.body); // Lock pointer on click document.addEventListener("click", () => { controls.lock(); }); controls.addEventListener("lock", () => { console.log("Pointer locked"); }); controls.addEventListener("unlock", () => { console.log("Pointer unlocked"); }); // Movement const velocity = new THREE.Vector3(); const direction = new THREE.Vector3(); let moveForward = false; let moveBackward = false; document.addEventListener("keydown", (event) => { switch (event.code) { case "KeyW": moveForward = true; break; case "KeyS": moveBackward = true; break; } }); function animate() { if (controls.isLocked) { direction.z = Number(moveForward) - Number(moveBackward); direction.normalize(); velocity.z -= direction.z * 0.1; velocity.z *= 0.9; // Friction controls.moveForward(-velocity.z); } } ``` -------------------------------- ### WebGPU Post-Processing with Nodes (JavaScript) Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-postprocessing/SKILL.md An example of using Three.js's node-based system for post-processing, compatible with WebGPU (r150+). It defines scene passes and effects like bloom using node structures. A THREE.PostProcessing instance is created, its output node is set, and rendering is handled by calling its render method within the animation loop. ```javascript import { postProcessing } from "three/addons/nodes/Nodes.js"; import { pass, bloom, dof } from "three/addons/nodes/Nodes.js"; // Using node-based system const scenePass = pass(scene, camera); const bloomNode = bloom(scenePass, 0.5, 0.4, 0.85); const postProcessing = new THREE.PostProcessing(renderer); postProcessing.outputNode = bloomNode; // Render function animate() { postProcessing.render(); } ``` -------------------------------- ### Create and Render InstancedMesh in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-geometry/SKILL.md Demonstrates how to create an InstancedMesh to render a large number of identical geometries efficiently. It covers setting up the geometry, material, and count, then iterating to set the position, rotation, and scale for each instance using dummy Object3D and Matrix4. Finally, it shows how to enable per-instance colors. ```javascript const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const count = 1000; const instancedMesh = new THREE.InstancedMesh(geometry, material, count); // Set transforms for each instance const dummy = new THREE.Object3D(); const matrix = new THREE.Matrix4(); for (let i = 0; i < count; i++) { dummy.position.set( (Math.random() - 0.5) * 20, (Math.random() - 0.5) * 20, (Math.random() - 0.5) * 20, ); dummy.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, 0); dummy.scale.setScalar(0.5 + Math.random()); dummy.updateMatrix(); instancedMesh.setMatrixAt(i, dummy.matrix); } // Flag for GPU update instancedMesh.instanceMatrix.needsUpdate = true; // Optional: per-instance colors instancedMesh.instanceColor = new THREE.InstancedBufferAttribute( new Float32Array(count * 3), 3, ); for (let i = 0; i < count; i++) { instancedMesh.setColorAt( i, new THREE.Color(Math.random(), Math.random(), Math.random()), ); } instancedMesh.instanceColor.needsUpdate = true; scene.add(instancedMesh); ``` -------------------------------- ### Create a PBR Material in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-materials/SKILL.md Demonstrates the creation of a PBR (Physically Based Rendering) material using `MeshStandardMaterial` in Three.js. This is recommended for realistic rendering and requires specifying properties like color, roughness, and metalness. ```javascript import * as THREE from "three"; // PBR material (recommended for realistic rendering) const material = new THREE.MeshStandardMaterial({ color: 0x00ff00, roughness: 0.5, metalness: 0.5, }); const mesh = new THREE.Mesh(geometry, material); ``` -------------------------------- ### Implement Various Oscillation Animations Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-animation/SKILL.md Shows how to create different oscillation effects using mathematical functions within an animation loop. Examples include sine waves, bouncing, circular motion, and figure-eight patterns. ```javascript function animate() { const t = clock.getElapsedTime(); // Sine wave mesh.position.y = Math.sin(t * 2) * 0.5; // Bouncing mesh.position.y = Math.abs(Math.sin(t * 3)) * 2; // Circular motion mesh.position.x = Math.cos(t) * 2; mesh.position.z = Math.sin(t) * 2; // Figure 8 mesh.position.x = Math.sin(t) * 2; mesh.position.z = Math.sin(t * 2) * 1; } ``` -------------------------------- ### Three.js Material Cloning and Runtime Modification Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-materials/SKILL.md Explains how to clone existing materials in Three.js for creating variations and how to modify material properties at runtime. It also highlights when `needsUpdate` must be set to true for changes to take effect. ```javascript // Clone material const clone = material.clone(); clone.color.set(0x00ff00); // Modify at runtime material.color.set(0xff0000); material.needsUpdate = true; // Only needed for some changes // When needsUpdate is required: // - Changing flat shading // - Changing texture // - Changing transparent // - Custom shader code changes ``` -------------------------------- ### Animating Light Properties in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md Provides a function to animate light properties over time using a clock. This example demonstrates orbiting a light, pulsing its intensity, and cycling its color using trigonometric functions and HSL color space. ```javascript const clock = new THREE.Clock(); function animate() { const time = clock.getElapsedTime(); // Orbit light around scene light.position.x = Math.cos(time) * 5; light.position.z = Math.sin(time) * 5; // Pulsing intensity light.intensity = 1 + Math.sin(time * 2) * 0.5; // Color cycling light.color.setHSL((time * 0.1) % 1, 1, 0.5); // Update helpers if using lightHelper.update(); } ``` -------------------------------- ### Three.js Compressed Texture Loading with KTX2Loader Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-textures/SKILL.md Shows how to load compressed texture formats like KTX2 in Three.js using the `KTX2Loader`. This involves setting up the loader, specifying the path to the Basis Universal transcoder, detecting renderer support, and then loading the KTX2 file. ```javascript import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader.js"; const ktx2Loader = new KTX2Loader(); ktx2Loader.setTranscoderPath("path/to/basis/"); kts2Loader.detectSupport(renderer); ktx2Loader.load("texture.ktx2", (texture) => { material.map = texture; }); ``` -------------------------------- ### Progressive Loading with Placeholder in JavaScript Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-loaders/SKILL.md Demonstrates a progressive loading technique where a placeholder object is displayed while the actual model is being loaded asynchronously. Once loaded, the placeholder is removed and the model is added to the scene. ```javascript // Progressive loading with placeholder const placeholder = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), new THREE.MeshBasicMaterial({ wireframe: true }), ); scene.add(placeholder); loadModel("model.glb").then((gltf) => { scene.remove(placeholder); scene.add(gltf.scene); }); ``` -------------------------------- ### Optimizing Light Performance and Shadows in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md Offers performance tips for lighting in Three.js, focusing on limiting light count, using baked lighting, optimizing shadow map size and frustums, and disabling unnecessary shadows. It also shows how to use light layers for selective rendering. ```javascript // Light layers light.layers.set(1); // Light only affects layer 1 mesh.layers.enable(1); // Mesh is on layer 1 otherMesh.layers.disable(1); // Other mesh not affected // Selective shadows mesh.castShadow = true; mesh.receiveShadow = true; decorMesh.castShadow = false; // Small objects often don't need to cast ``` -------------------------------- ### Animate Bones Programmatically in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-animation/SKILL.md Shows how to animate individual bones programmatically within the animation loop. This example animates the 'Head' bone's rotation based on the elapsed time. It also includes updating the AnimationMixer if other animations are playing. ```javascript function animate() { const time = clock.getElapsedTime(); // Animate bone const headBone = skeleton.bones.find((b) => b.name === "Head"); if (headBone) { headBone.rotation.y = Math.sin(time) * 0.3; } // Update mixer if also playing clips mixer.update(clock.getDelta()); } ``` -------------------------------- ### Clock for Animation in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-fundamentals/SKILL.md Manages animation timing using THREE.Clock to get delta time and elapsed time. This ensures consistent animation speeds across different framerates by using delta time for updates. It integrates with requestAnimationFrame for smooth rendering. ```javascript const clock = new THREE.Clock(); function animate() { const delta = clock.getDelta(); // Time since last frame (seconds) const elapsed = clock.getElapsedTime(); // Total time (seconds) mesh.rotation.y += delta * 0.5; // Consistent speed regardless of framerate requestAnimationFrame(animate); renderer.render(scene, camera); } ``` -------------------------------- ### Image-Based Lighting (IBL) with HDR in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-lighting/SKILL.md Explains how to implement Image-Based Lighting (IBL) in Three.js using HDR environment maps for realistic reflections and lighting. It demonstrates loading HDR textures with RGBELoader and setting them as the scene's environment and background. It also shows how to use PMREMGenerator for improved reflections. ```javascript import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js"; const rgbeLoader = new RGBELoader(); rgbeLoader.load("environment.hdr", (texture) => { texture.mapping = THREE.EquirectangularReflectionMapping; // Set as scene environment (affects all PBR materials) scene.environment = texture; // Optional: also use as background scene.background = texture; scene.backgroundBlurriness = 0; // 0-1, blur the background scene.backgroundIntensity = 1; }); // PMREMGenerator for better reflections const pmremGenerator = new THREE.PMREMGenerator(renderer); pmremGenerator.compileEquirectangularShader(); rgbeLoader.load("environment.hdr", (texture) => { const envMap = pmremGenerator.fromEquirectangular(texture).texture; scene.environment = envMap; texture.dispose(); pmremGenerator.dispose(); }); ``` ```javascript const cubeLoader = new THREE.CubeTextureLoader(); const envMap = cubeLoader.load([ "px.jpg", "nx.jpg", "py.jpg", "ny.jpg", "pz.jpg", "nz.jpg", ]); scene.environment = envMap; scene.background = envMap; ``` -------------------------------- ### Initialize and Use DragControls in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-interaction/SKILL.md Shows how to set up and use DragControls for directly dragging objects within a Three.js scene. It requires the DragControls module and allows for event handling during the drag start, drag, and drag end phases. ```javascript import { DragControls } from "three/addons/controls/DragControls.js"; const draggableObjects = [mesh1, mesh2, mesh3]; const dragControls = new DragControls( draggableObjects, camera, renderer.domElement, ); dragControls.addEventListener("dragstart", (event) => { orbitControls.enabled = false; event.object.material.emissive.set(0xaaaaaa); }); dragControls.addEventListener("drag", (event) => { // Constrain to ground plane event.object.position.y = 0; }); dragControls.addEventListener("dragend", (event) => { orbitControls.enabled = true; event.object.material.emissive.set(0x000000); }); ``` -------------------------------- ### Loading Manager for Assets in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-fundamentals/SKILL.md Utilizes THREE.LoadingManager to track the progress and completion of asset loading. It provides callbacks for start, load, progress, and error events, allowing for custom logic during asset loading. This is useful for managing multiple loaders like TextureLoader and GLTFLoader. ```javascript const manager = new THREE.LoadingManager(); manager.onStart = (url, loaded, total) => console.log("Started loading"); manager.onLoad = () => console.log("All loaded"); manager.onProgress = (url, loaded, total) => console.log(`${loaded}/${total}`); manager.onError = (url) => console.error(`Error loading ${url}`); const textureLoader = new THREE.TextureLoader(manager); const gltfLoader = new GLTFLoader(manager); ``` -------------------------------- ### Initialize and Use FlyControls in Three.js Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-interaction/SKILL.md Demonstrates how to initialize and use FlyControls for camera navigation in a Three.js scene. It allows for free-form movement similar to a flight simulator. Requires the FlyControls module and a clock for delta time updates. ```javascript import { FlyControls } from "three/addons/controls/FlyControls.js"; const controls = new FlyControls(camera, renderer.domElement); controls.movementSpeed = 10; controls.rollSpeed = Math.PI / 24; controls.dragToLook = true; // Update with delta function animate() { controls.update(clock.getDelta()); renderer.render(scene, camera); } ``` -------------------------------- ### Configure Asset Loading Paths and URL Modifiers in JavaScript Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-loaders/SKILL.md Sets the base path for loaders and custom URL modifiers in Three.js. This allows assets to be loaded from specific directories or to have their URLs rewritten, for example, to load from a CDN. ```javascript // Set base path loader.setPath("assets/models/"); loader.load("model.glb"); // Loads from assets/models/model.glb // Set resource path (for textures referenced in model) loader.setResourcePath("assets/textures/"); // Custom URL modifier manager.setURLModifier((url) => { return `https://cdn.example.com/${url}`; }); ``` -------------------------------- ### Implementing Instanced Shaders Source: https://github.com/cloudai-x/threejs-skills/blob/main/skills/threejs-shaders/SKILL.md Demonstrates how to use instancing in shaders by adding an instanced buffer attribute (e.g., `offset`) to the geometry and accessing it in the vertex shader to position individual instances. ```javascript // Instanced attribute const offsets = new Float32Array(instanceCount * 3); // Fill offsets... geometry.setAttribute("offset", new THREE.InstancedBufferAttribute(offsets, 3)); const material = new THREE.ShaderMaterial({ vertexShader: ` attribute vec3 offset; void main() { vec3 pos = position + offset; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } `, fragmentShader: ` void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } `, }); ```