threejs-textures
Configures texture properties, UV mapping, and color spaces for Three.js 3D scenes.
Install
mkdir -p .claude/skills/threejs-textures && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/4722" && unzip -o skill.zip -d .claude/skills/threejs-textures && rm skill.zipInstalls to .claude/skills/threejs-textures
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Three.js textures - texture types, UV mapping, environment maps, texture settings. Use when working with images, UV coordinates, cubemaps, HDR environments, or texture optimization.Key capabilities
- →Load and configure 3D textures
- →Manage texture color spaces
- →Configure UV mapping and wrapping
- →Optimize environment map textures
How it works
The skill provides methods for loading, configuring, and optimizing textures in Three.js, including support for various mapping and filtering modes.
Inputs & outputs
When to use threejs-textures
- →Applying textures to 3D meshes
- →Configuring UV mapping and wrapping
- →Setting correct color spaces for PBR maps
- →Optimizing environment map textures
About this skill
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: metalnessTexture,
metalness: 1, // Multiplier
// Ambient occlusion (Linear, uses uv2)
aoMap: aoTexture,
aoMapIntensity: 1,
// Self-illumination (sRGB)
emissiveMap: emissiveTexture,
emissive: 0xffffff,
emissiveIntensity: 1
---
*Content truncated.*
When not to use it
- →Non-Three.js 3D projects
- →General image processing
Limitations
- →Limited to Three.js framework
- →Requires valid texture file formats
How it compares
It provides a structured API for texture management compared to manual Three.js texture implementation.
Compared to similar skills
threejs-textures side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| threejs-textures (this skill) | 1 | 6mo | No flags | Intermediate |
| zustand | 113 | 2mo | No flags | Intermediate |
| threejs-skills | 61 | 4mo | No flags | Intermediate |
| accessibility-compliance | 45 | 2mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by CloudAI-X
View all by CloudAI-X →You might also like
zustand
lobehub
Zustand state management guide. Use when working with store code (src/store/**), implementing actions, managing state, or creating slices. Triggers on Zustand store development, state management questions, or action implementation.
threejs-skills
sickn33
Three.js skills for creating 3D elements and interactive experiences
accessibility-compliance
wshobson
Implement WCAG 2.2 compliant interfaces with mobile accessibility, inclusive design patterns, and assistive technology support. Use when auditing accessibility, implementing ARIA patterns, building for screen readers, or ensuring inclusive user experiences.
react-modernization
wshobson
Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, migrating to React Hooks, or upgrading to latest React versions.
3d-graphics
samhvw8
3D web graphics with Three.js (WebGL/WebGPU). Capabilities: scenes, cameras, geometries, materials, lights, animations, model loading (GLTF/FBX), PBR materials, shadows, post-processing (bloom, SSAO, SSR), custom shaders, instancing, LOD, physics, VR/XR. Actions: create, build, animate, render 3D scenes/models. Keywords: Three.js, WebGL, WebGPU, 3D graphics, scene, camera, geometry, material, light, animation, GLTF, FBX, OrbitControls, PBR, shadow mapping, post-processing, bloom, SSAO, shader, instancing, LOD, WebXR, VR, AR, product configurator, data visualization, architectural walkthrough, interactive 3D, canvas. Use when: creating 3D visualizations, building WebGL/WebGPU apps, loading 3D models, adding animations, implementing VR/XR, creating interactive graphics, building product configurators.
d3-visualization
lyndonkl
Use when creating custom, interactive data visualizations with D3.js—building bar/line/scatter charts from scratch, creating network diagrams or geographic maps, binding changing data to visual elements, adding zoom/pan/brush interactions, animating chart transitions, or when chart libraries (Highcharts, Chart.js) don't support your specific visualization design and you need low-level control over data-driven DOM manipulation, scales, shapes, and layouts.