Claude-skill-registry dev-assets-texture-loading

Texture loading and optimization for R3F. Use when loading image textures.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/dev-assets-texture-loading" ~/.claude/skills/majiayu000-claude-skill-registry-dev-assets-texture-loading && rm -rf "$T"
manifest: skills/data/dev-assets-texture-loading/SKILL.md
source content

Texture Loading

Optimized texture loading patterns for React Three Fiber.

When to Use

Use when:

  • Loading textures for materials
  • Optimizing texture memory usage
  • Setting up texture filtering

Quick Start

import { useLoader } from '@react-three/fiber';
import { TextureLoader } from 'three';
import { useMemo } from 'react';

function TexturedMaterial({ textureUrl, color = '#ffffff' }) {
  const texture = useLoader(TextureLoader, textureUrl);

  // Optimize texture settings
  useMemo(() => {
    if (texture) {
      texture.colorSpace = THREE.SRGBColorSpace;
      texture.generateMipmaps = true;
      texture.minFilter = THREE.LinearMipmapLinearFilter;
      texture.magFilter = THREE.LinearFilter;
      texture.anisotropy = 4;
    }
  }, [texture]);

  return (
    <meshStandardMaterial
      map={texture}
      color={color}
    />
  );
}

Vite Asset Import

// Import texture with ?url suffix
import woodTexture from '@/assets/textures/wood.jpg?url';

// Use in material
function WoodMaterial() {
  const texture = useLoader(TextureLoader, woodTexture);
  return <meshStandardMaterial map={texture} />;
}

Texture Optimization

// Pre-compress textures before adding to src/assets/
// Use WebP format for better compression

const textureOptimization = {
  // Power of 2 dimensions for GPU
  width: 512,   // 512, 1024, 2048, 4096
  height: 512,

  // Compression
  format: 'webp', // WebP > PNG > JPEG

  // Mipmaps for distance
  generateMipmaps: true,
  minFilter: THREE.LinearMipmapLinearFilter,

  // Anisotropic filtering
  anisotropy: 4,  // Max: 16
};

Multiple Textures

function MultiTextureMaterial() {
  const [colorMap, normalMap, roughnessMap] = useLoader(TextureLoader, [
    '/textures/diffuse.jpg',
    '/textures/normal.jpg',
    '/textures/roughness.jpg',
  ]);

  return (
    <meshStandardMaterial
      map={colorMap}
      normalMap={normalMap}
      roughnessMap={roughnessMap}
    />
  );
}

Environment Maps

import { Environment, CubeCamera } from '@react-three/drei';

function SceneWithReflection() {
  return (
    <>
      {/* Pre-generated environment map */}
      <Environment preset="city" />

      {/* Or custom HDRI */}
      <Environment files="/hdr/studio.hdr" />
    </>
  );
}

Texture Disposal

useEffect(() => {
  const texture = textureLoader.load('/texture.jpg');

  return () => {
    // Always dispose textures when done
    texture.dispose();
  };
}, []);

Common Mistakes

❌ Wrong✅ Right
Non-power-of-2 dimensionsUse 512, 1024, 2048
Not setting colorSpaceSet to SRGBColorSpace
Large textures for mobileUse smaller textures on mobile
Not disposingAlways dispose in cleanup
Using PNG unnecessarilyUse WebP for better compression

Mobile Optimization

const isMobile = /iPhone|iPad|Android/i.test(navigator.userAgent);

const textureSize = isMobile ? 512 : 2048;
const textureFormat = isMobile ? 'webp' : 'jpg';

Reference