# Textures

Map images and data onto 3D surfaces.

## Texture Types

### Standard 2D Texture
```javascript
const texture = new THREE.Texture(image);
texture.needsUpdate = true; // required after manual creation

// Or use loader (auto-updates)
const texture = new THREE.TextureLoader().load('image.jpg');
```

### Canvas Texture
```javascript
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Draw on canvas...
const texture = new THREE.CanvasTexture(canvas);
```

### Video Texture
```javascript
const video = document.createElement('video');
video.src = 'video.mp4';
video.play();
const texture = new THREE.VideoTexture(video);
```

### Data Texture
```javascript
const size = 512;
const data = new Uint8Array(size * size * 4);
// Fill data with RGBA values...
const texture = new THREE.DataTexture(data, size, size);
texture.needsUpdate = true;
```

### Cube Texture (Environment/Skybox)
```javascript
const loader = new THREE.CubeTextureLoader();
const texture = loader.load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);
```

## Material Maps

Multiple texture types for different effects:

```javascript
const material = new THREE.MeshStandardMaterial({
  map: diffuseTexture,           // base color
  normalMap: normalTexture,       // surface detail
  roughnessMap: roughnessTexture, // surface roughness variation
  metalnessMap: metalnessTexture, // metallic areas
  aoMap: aoTexture,               // ambient occlusion
  emissiveMap: emissiveTexture,   // glow areas
  alphaMap: alphaTexture,         // transparency
  bumpMap: bumpTexture,           // height variation
  displacementMap: dispTexture    // vertex displacement
});

// AO map requires second UV set
geometry.setAttribute('uv2', geometry.attributes.uv);
```

## Wrapping Modes

Control texture repeat behavior:

```javascript
texture.wrapS = THREE.RepeatWrapping;      // horizontal
texture.wrapT = THREE.RepeatWrapping;      // vertical

// Options:
// THREE.RepeatWrapping - tile infinitely
// THREE.ClampToEdgeWrapping - stretch edge pixels
// THREE.MirroredRepeatWrapping - mirror on each repeat

// Set repeat count
texture.repeat.set(4, 4);

// Offset texture
texture.offset.set(0.5, 0.5);
```

## Filtering

Control texture sampling quality:

```javascript
// Magnification (when texel < pixel)
texture.magFilter = THREE.LinearFilter; // smooth
// or THREE.NearestFilter // pixelated

// Minification (when texel > pixel)
texture.minFilter = THREE.LinearMipmapLinearFilter; // best quality
// Options:
// THREE.NearestFilter
// THREE.LinearFilter
// THREE.NearestMipmapNearestFilter
// THREE.NearestMipmapLinearFilter
// THREE.LinearMipmapNearestFilter
// THREE.LinearMipmapLinearFilter

// Anisotropic filtering (better at angles)
texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
```

## UV Mapping

Control how texture is mapped to geometry:

```javascript
// Flip texture vertically
texture.flipY = false;

// Rotate texture
texture.rotation = Math.PI / 4; // 45 degrees
texture.center.set(0.5, 0.5); // rotation center

// Transform UV coordinates
const uvAttribute = geometry.attributes.uv;
for (let i = 0; i < uvAttribute.count; i++) {
  let u = uvAttribute.getX(i);
  let v = uvAttribute.getY(i);
  uvAttribute.setXY(i, u * 2, v * 2); // scale UVs
}
uvAttribute.needsUpdate = true;
```

## Color Space

Handle color space correctly:

```javascript
// For color data (diffuse, emissive)
texture.colorSpace = THREE.SRGBColorSpace;

// For non-color data (normal, roughness, etc.)
texture.colorSpace = THREE.NoColorSpace; // or LinearSRGBColorSpace
```

## Performance Optimization

```javascript
// Use mipmaps (auto-generated by default)
texture.generateMipmaps = true;

// Dispose when done
texture.dispose();

// Compress textures (use KTX2Loader for .ktx2 files)
// Reduce resolution for distant objects
// Use texture atlases to reduce draw calls
```

## Advanced Textures

```javascript
// 3D Texture (volumetric)
const texture3d = new THREE.Data3DTexture(data, width, height, depth);

// Depth Texture (for advanced effects)
const depthTexture = new THREE.DepthTexture(width, height);

// Compressed Texture
const compressedTexture = new THREE.CompressedTexture(...);
```
