threejs-textures
💡 Summary
A comprehensive guide for using textures in Three.js, covering various types and configurations.
🎯 Target Audience
🤖 AI Roast: “Powerful, but the setup might scare off the impatient.”
Risk: Low. Review: filesystem read/write scope and path traversal. Run with least privilege and audit before enabling in production.
name: threejs-textures description: Three.js textures - texture types, UV mapping, environment maps, texture settings. Use when working with images, UV coordinates, cubemaps, HDR environments, or texture optimization.
Three.js Textures
Quick Start
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, });
Texture Loading
Basic Loading
const loader = new THREE.TextureLoader(); // Async with callbacks loader.load( "texture.jpg", (texture) => console.log("Loaded"), (progress) => console.log("Progress"), (error) => console.error("Error"), ); // Synchronous style (loads async internally) const texture = loader.load("texture.jpg"); material.map = texture;
Promise Wrapper
function loadTexture(url) { return new Promise((resolve, reject) => { new THREE.TextureLoader().load(url, resolve, undefined, reject); }); } // Usage const [colorMap, normalMap, roughnessMap] = await Promise.all([ loadTexture("color.jpg"), loadTexture("normal.jpg"), loadTexture("roughness.jpg"), ]);
Texture Configuration
Color Space
Critical for accurate color reproduction.
// Color/albedo textures - use sRGB colorTexture.colorSpace = THREE.SRGBColorSpace; // Data textures (normal, roughness, metalness, AO) - leave as default // Do NOT set colorSpace for data textures (NoColorSpace is default)
Wrapping Modes
texture.wrapS = THREE.RepeatWrapping; // Horizontal texture.wrapT = THREE.RepeatWrapping; // Vertical // Options: // THREE.ClampToEdgeWrapping - Stretches edge pixels (default) // THREE.RepeatWrapping - Tiles the texture // THREE.MirroredRepeatWrapping - Tiles with mirror flip
Repeat, Offset, Rotation
// Tile texture 4x4 texture.repeat.set(4, 4); texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; // Offset (0-1 range) texture.offset.set(0.5, 0.5); // Rotation (radians, around center) texture.rotation = Math.PI / 4; texture.center.set(0.5, 0.5); // Rotation pivot
Filtering
// Minification (texture larger than screen pixels) texture.minFilter = THREE.LinearMipmapLinearFilter; // Default, smooth texture.minFilter = THREE.NearestFilter; // Pixelated texture.minFilter = THREE.LinearFilter; // Smooth, no mipmaps // Magnification (texture smaller than screen pixels) texture.magFilter = THREE.LinearFilter; // Smooth (default) texture.magFilter = THREE.NearestFilter; // Pixelated (retro games) // Anisotropic filtering (sharper at angles) texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
Generate Mipmaps
// Usually true by default texture.generateMipmaps = true; // Disable for non-power-of-2 textures or data textures texture.generateMipmaps = false; texture.minFilter = THREE.LinearFilter;
Texture Types
Regular Texture
const texture = new THREE.Texture(image); texture.needsUpdate = true;
Data Texture
Create texture from raw data.
// Create gradient texture const size = 256; const data = new Uint8Array(size * size * 4); for (let i = 0; i < size; i++) { for (let j = 0; j < size; j++) { const index = (i * size + j) * 4; data[index] = i; // R data[index + 1] = j; // G data[index + 2] = 128; // B data[index + 3] = 255; // A } } const texture = new THREE.DataTexture(data, size, size); texture.needsUpdate = true;
Canvas Texture
const canvas = document.createElement("canvas"); canvas.width = 256; canvas.height = 256; const ctx = canvas.getContext("2d"); // Draw on canvas ctx.fillStyle = "red"; ctx.fillRect(0, 0, 256, 256); ctx.fillStyle = "white"; ctx.font = "48px Arial"; ctx.fillText("Hello", 50, 150); const texture = new THREE.CanvasTexture(canvas); // Update when canvas changes texture.needsUpdate = true;
Video Texture
const video = document.createElement("video"); video.src = "video.mp4"; video.loop = true; video.muted = true; video.play(); const texture = new THREE.VideoTexture(video); texture.colorSpace = THREE.SRGBColorSpace; // No need to set needsUpdate - auto-updates
Compressed Textures
import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader.js"; const ktx2Loader = new KTX2Loader(); ktx2Loader.setTranscoderPath("path/to/basis/"); ktx2Loader.detectSupport(renderer); ktx2Loader.load("texture.ktx2", (texture) => { material.map = texture; });
Cube Textures
For environment maps and skyboxes.
CubeTextureLoader
const loader = new THREE.CubeTextureLoader(); const cubeTexture = loader.load([ "px.jpg", "nx.jpg", // +X, -X "py.jpg", "ny.jpg", // +Y, -Y "pz.jpg", "nz.jpg", // +Z, -Z ]); // As background scene.background = cubeTexture; // As environment map scene.environment = cubeTexture; material.envMap = cubeTexture;
Equirectangular to Cubemap
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js"; const pmremGenerator = new THREE.PMREMGenerator(renderer); pmremGenerator.compileEquirectangularShader(); new RGBELoader().load("environment.hdr", (texture) => { const envMap = pmremGenerator.fromEquirectangular(texture).texture; scene.environment = envMap; scene.background = envMap; texture.dispose(); pmremGenerator.dispose(); });
HDR Textures
RGBELoader
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js"; const loader = new RGBELoader(); loader.load("environment.hdr", (texture) => { texture.mapping = THREE.EquirectangularReflectionMapping; scene.environment = texture; scene.background = texture; });
EXRLoader
import { EXRLoader } from "three/examples/jsm/loaders/EXRLoader.js"; const loader = new EXRLoader(); loader.load("environment.exr", (texture) => { texture.mapping = THREE.EquirectangularReflectionMapping; scene.environment = texture; });
Background Options
scene.background = texture; scene.backgroundBlurriness = 0.5; // 0-1, blur background scene.backgroundIntensity = 1.0; // Brightness scene.backgroundRotation.y = Math.PI; // Rotate background
Render Targets
Render to texture for effects.
// Create render target const renderTarget = new THREE.WebGLRenderTarget(512, 512, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, }); // Render scene to target renderer.setRenderTarget(renderTarget); renderer.render(scene, camera); renderer.setRenderTarget(null); // Back to screen // Use as texture material.map = renderTarget.texture;
Depth Texture
const renderTarget = new THREE.WebGLRenderTarget(512, 512); renderTarget.depthTexture = new THREE.DepthTexture( 512, 512, THREE.UnsignedShortType, ); // Access depth const depthTexture = renderTarget.depthTexture;
Multi-Sample Render Target
const renderTarget = new THREE.WebGLRenderTarget(512, 512, { samples: 4, // MSAA });
CubeCamera
Dynamic environment maps for reflections.
const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(256, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter, }); const cubeCamera = new THREE.CubeCamera(0.1, 1000, cubeRenderTarget); scene.add(cubeCamera); // Apply to reflective material reflectiveMaterial.envMap = cubeRenderTarget.texture; // Update in animation loop (expensive!) function animate() { // Hide reflective object, update env map, show again reflectiveObject.visible = false; cubeCamera.position.copy(reflectiveObject.position); cubeCamera.update(renderer, scene); reflectiveObject.visible = true; }
UV Mapping
Accessing UVs
const uvs = geometry.attributes.uv; // Read UV const u = uvs.getX(vertexIndex); const v = uvs.getY(vertexIndex); // Modify UV uvs.setXY(vertexIndex, newU, newV); uvs.needsUpdate = true;
Second UV Channel (for AO maps)
// Required for aoMap geometry.setAttribute("uv2", geometry.attributes.uv); // Or create custom second UV const uv2 = new Float32Array(vertexCount * 2); // ... fill uv2 data geometry.setAttribute("uv2", new THREE.BufferAttribute(uv2, 2));
UV Transform in Shader
const material = new THREE.ShaderMaterial({ uniforms: { map: { value: texture }, uvOffset: { value: new THREE.Vector2(0, 0) }, uvScale: { value: new THREE.Vector2(1, 1) }, }, vertexShader: ` varying vec2 vUv; uniform vec2 uvOffset; uniform vec2 uvScale; void main() { vUv = uv * uvScale + uvOffset; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` varying vec2 vUv; uniform sampler2D map; void main() { gl_FragColor = texture2D(map, vUv); } `, });
Texture Atlas
Multiple images in one texture.
// Atlas with 4 sprites (2x2 grid) const atlas = loader.load("atlas.png"); atlas.wrapS = THREE.ClampToEdgeWrapping; atlas.wrapT = THREE.ClampToEdgeWrapping; // Select sprite by UV offset/scale function selectSprite(row, col, gridSize = 2) { atlas.offset.set(col / gridSize, 1 - (row + 1) / gridSize); atlas.repeat.set(1 / gridSize, 1 / gridSize); } // Select top-left sprite selectSprite(0, 0);
Material Texture Maps
PBR Texture Set
const material = new THREE.MeshStandardMaterial({ // Base color (sRGB) map: colorTexture, // Surface detail (Linear) normalMap: normalTexture, normalScale: new THREE.Vector2(1, 1), // Roughness (Linear, grayscale) roughnessMap: roughnessTexture, roughness: 1, // Multiplier // Metalness (Linear, grayscale) metalnessMap: metalnessTex
Pros
- Detailed examples for various texture types
- Clear explanations of texture settings
- Useful for both beginners and advanced users
Cons
- Lacks installation instructions
- No troubleshooting section
- Could benefit from more visual examples
Related Skills
pytorch
S“It's the Swiss Army knife of deep learning, but good luck figuring out which of the 47 installation methods is the one that won't break your system.”
agno
S“It promises to be the Kubernetes for agents, but let's see if developers have the patience to learn yet another orchestration layer.”
nuxt-skills
S“It's essentially a well-organized cheat sheet that turns your AI assistant into a Nuxt framework parrot.”
Disclaimer: This content is sourced from GitHub open source projects for display and rating purposes only.
Copyright belongs to the original author CloudAI-X.
