r3f-textures — how to use r3f-textures r3f-textures, r3f-skills, EnzeD, community, how to use r3f-textures, ai agent skill, mcp server, agent automation, r3f-textures setup guide, react three fiber textures, useTexture hook, 3D texture rendering

v1.0.0
GitHub

About this Skill

Perfect for Frontend Agents needing advanced 3D texture rendering capabilities with React Three Fiber r3f-textures is a React Three Fiber skill that enables developers to create and manage 3D textures using the useTexture hook from @react-three/drei

Features

Imports textures using the useTexture hook from @react-three/drei
Supports rendering 3D models with textures using meshStandardMaterial
Uses the Canvas component from @react-three/fiber for rendering
Enables creation of textured boxes using the boxGeometry component
Utilizes ambientLight for scene illumination
Leverages the @react-three/fiber and @react-three/drei libraries for 3D rendering

# Core Topics

EnzeD EnzeD
[0]
[0]
Updated: 3/12/2026

Quality Score

Top 5%
36
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
> npx killer-skills add EnzeD/r3f-skills/r3f-textures
Supports 18+ Platforms
Cursor
Windsurf
VS Code
Trae
Claude
OpenClaw
+12 more

Agent Capability Analysis

The r3f-textures MCP Server by EnzeD is an open-source community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for how to use r3f-textures, r3f-textures setup guide, react three fiber textures.

Ideal Agent Persona

Perfect for Frontend Agents needing advanced 3D texture rendering capabilities with React Three Fiber

Core Value

Empowers agents to create realistic textures for 3D models using the useTexture hook from @react-three/drei, supporting various image formats like .jpg

Capabilities Granted for r3f-textures MCP Server

Rendering 3D scenes with custom textures
Creating immersive experiences with ambientLight and meshStandardMaterial
Optimizing 3D model performance with efficient texture loading

! Prerequisites & Limits

  • Requires React Three Fiber and @react-three/drei libraries
  • Limited to 3D texture rendering only
Project
SKILL.md
13.2 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

React Three Fiber Textures

Quick Start

tsx
1import { Canvas } from '@react-three/fiber' 2import { useTexture } from '@react-three/drei' 3 4function TexturedBox() { 5 const texture = useTexture('/textures/wood.jpg') 6 7 return ( 8 <mesh> 9 <boxGeometry /> 10 <meshStandardMaterial map={texture} /> 11 </mesh> 12 ) 13} 14 15export default function App() { 16 return ( 17 <Canvas> 18 <ambientLight /> 19 <TexturedBox /> 20 </Canvas> 21 ) 22}

useTexture Hook (Drei)

The recommended way to load textures in R3F.

Single Texture

tsx
1import { useTexture } from '@react-three/drei' 2 3function SingleTexture() { 4 const texture = useTexture('/textures/color.jpg') 5 6 return ( 7 <mesh> 8 <planeGeometry args={[5, 5]} /> 9 <meshBasicMaterial map={texture} /> 10 </mesh> 11 ) 12}

Multiple Textures (Array)

tsx
1function MultipleTextures() { 2 const [colorMap, normalMap, roughnessMap] = useTexture([ 3 '/textures/color.jpg', 4 '/textures/normal.jpg', 5 '/textures/roughness.jpg', 6 ]) 7 8 return ( 9 <mesh> 10 <sphereGeometry args={[1, 64, 64]} /> 11 <meshStandardMaterial 12 map={colorMap} 13 normalMap={normalMap} 14 roughnessMap={roughnessMap} 15 /> 16 </mesh> 17 ) 18}

Named Object (Recommended for PBR)

tsx
1function PBRTextures() { 2 // Named object automatically spreads to material 3 const textures = useTexture({ 4 map: '/textures/color.jpg', 5 normalMap: '/textures/normal.jpg', 6 roughnessMap: '/textures/roughness.jpg', 7 metalnessMap: '/textures/metalness.jpg', 8 aoMap: '/textures/ao.jpg', 9 displacementMap: '/textures/displacement.jpg', 10 }) 11 12 return ( 13 <mesh> 14 <sphereGeometry args={[1, 64, 64]} /> 15 <meshStandardMaterial 16 {...textures} 17 displacementScale={0.1} 18 /> 19 </mesh> 20 ) 21}

With Texture Configuration

tsx
1import { useTexture } from '@react-three/drei' 2import * as THREE from 'three' 3 4function ConfiguredTextures() { 5 const textures = useTexture({ 6 map: '/textures/color.jpg', 7 normalMap: '/textures/normal.jpg', 8 }, (textures) => { 9 // Configure textures after loading 10 Object.values(textures).forEach(texture => { 11 texture.wrapS = texture.wrapT = THREE.RepeatWrapping 12 texture.repeat.set(4, 4) 13 }) 14 }) 15 16 return ( 17 <mesh> 18 <planeGeometry args={[10, 10]} /> 19 <meshStandardMaterial {...textures} /> 20 </mesh> 21 ) 22}

Preloading

tsx
1import { useTexture } from '@react-three/drei' 2 3// Preload at module level 4useTexture.preload('/textures/hero.jpg') 5useTexture.preload(['/tex1.jpg', '/tex2.jpg']) 6 7function Component() { 8 // Will be instant if preloaded 9 const texture = useTexture('/textures/hero.jpg') 10}

useLoader (Core R3F)

For more control over loading.

tsx
1import { useLoader } from '@react-three/fiber' 2import { TextureLoader } from 'three' 3 4function WithUseLoader() { 5 const texture = useLoader(TextureLoader, '/textures/color.jpg') 6 7 // Multiple textures 8 const [color, normal] = useLoader(TextureLoader, [ 9 '/textures/color.jpg', 10 '/textures/normal.jpg', 11 ]) 12 13 return ( 14 <mesh> 15 <boxGeometry /> 16 <meshStandardMaterial map={color} normalMap={normal} /> 17 </mesh> 18 ) 19} 20 21// Preload 22useLoader.preload(TextureLoader, '/textures/color.jpg')

Texture Configuration

Wrapping Modes

tsx
1import * as THREE from 'three' 2 3function ConfigureWrapping() { 4 const texture = useTexture('/textures/tile.jpg', (tex) => { 5 // Wrapping 6 tex.wrapS = THREE.RepeatWrapping // Horizontal: ClampToEdgeWrapping, RepeatWrapping, MirroredRepeatWrapping 7 tex.wrapT = THREE.RepeatWrapping // Vertical 8 9 // Repeat 10 tex.repeat.set(4, 4) // Tile 4x4 11 12 // Offset 13 tex.offset.set(0.5, 0.5) // Shift UV 14 15 // Rotation 16 tex.rotation = Math.PI / 4 // Rotate 45 degrees 17 tex.center.set(0.5, 0.5) // Rotation pivot 18 }) 19 20 return ( 21 <mesh> 22 <planeGeometry args={[10, 10]} /> 23 <meshStandardMaterial map={texture} /> 24 </mesh> 25 ) 26}

Filtering

tsx
1function ConfigureFiltering() { 2 const texture = useTexture('/textures/color.jpg', (tex) => { 3 // Minification (texture larger than screen pixels) 4 tex.minFilter = THREE.LinearMipmapLinearFilter // Smooth with mipmaps (default) 5 tex.minFilter = THREE.NearestFilter // Pixelated 6 tex.minFilter = THREE.LinearFilter // Smooth, no mipmaps 7 8 // Magnification (texture smaller than screen pixels) 9 tex.magFilter = THREE.LinearFilter // Smooth (default) 10 tex.magFilter = THREE.NearestFilter // Pixelated (retro style) 11 12 // Anisotropic filtering (sharper at angles) 13 tex.anisotropy = 16 // Usually renderer.capabilities.getMaxAnisotropy() 14 15 // Generate mipmaps 16 tex.generateMipmaps = true // Default 17 }) 18}

Color Space

Important for accurate colors.

tsx
1function ConfigureColorSpace() { 2 const [colorMap, normalMap, roughnessMap] = useTexture([ 3 '/textures/color.jpg', 4 '/textures/normal.jpg', 5 '/textures/roughness.jpg', 6 ], (textures) => { 7 // Color/albedo textures should use sRGB 8 textures[0].colorSpace = THREE.SRGBColorSpace 9 10 // Data textures (normal, roughness, metalness, ao) use Linear 11 // This is the default, so usually no action needed 12 // textures[1].colorSpace = THREE.LinearSRGBColorSpace 13 // textures[2].colorSpace = THREE.LinearSRGBColorSpace 14 }) 15}

Environment Maps

useEnvironment Hook

tsx
1import { useEnvironment, Environment } from '@react-three/drei' 2 3// Use as texture 4function EnvMappedSphere() { 5 const envMap = useEnvironment({ preset: 'sunset' }) 6 7 return ( 8 <mesh> 9 <sphereGeometry args={[1, 64, 64]} /> 10 <meshStandardMaterial 11 metalness={1} 12 roughness={0} 13 envMap={envMap} 14 /> 15 </mesh> 16 ) 17} 18 19// Or use Environment component for scene-wide 20function Scene() { 21 return ( 22 <> 23 <Environment preset="sunset" background /> 24 <Mesh /> 25 </> 26 ) 27}

HDR Environment

tsx
1import { useEnvironment } from '@react-three/drei' 2 3function HDREnvironment() { 4 const envMap = useEnvironment({ files: '/hdri/studio.hdr' }) 5 6 return ( 7 <mesh> 8 <sphereGeometry args={[1, 64, 64]} /> 9 <meshStandardMaterial 10 metalness={1} 11 roughness={0} 12 envMap={envMap} 13 envMapIntensity={1} 14 /> 15 </mesh> 16 ) 17}

Cube Map

tsx
1import { useCubeTexture } from '@react-three/drei' 2 3function CubeMapTexture() { 4 const envMap = useCubeTexture( 5 ['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg'], 6 { path: '/textures/cube/' } 7 ) 8 9 return ( 10 <mesh> 11 <sphereGeometry args={[1, 64, 64]} /> 12 <meshStandardMaterial envMap={envMap} metalness={1} roughness={0} /> 13 </mesh> 14 ) 15}

Video Textures

tsx
1import { useVideoTexture } from '@react-three/drei' 2 3function VideoPlane() { 4 const texture = useVideoTexture('/videos/sample.mp4', { 5 start: true, 6 loop: true, 7 muted: true, 8 }) 9 10 return ( 11 <mesh> 12 <planeGeometry args={[16, 9].map(x => x * 0.5)} /> 13 <meshBasicMaterial map={texture} toneMapped={false} /> 14 </mesh> 15 ) 16}

Canvas Textures

tsx
1import { useRef, useEffect } from 'react' 2import { useFrame } from '@react-three/fiber' 3import * as THREE from 'three' 4 5function CanvasTexture() { 6 const meshRef = useRef() 7 const textureRef = useRef() 8 9 useEffect(() => { 10 const canvas = document.createElement('canvas') 11 canvas.width = 256 12 canvas.height = 256 13 const ctx = canvas.getContext('2d') 14 15 // Draw on canvas 16 ctx.fillStyle = 'red' 17 ctx.fillRect(0, 0, 256, 256) 18 ctx.fillStyle = 'white' 19 ctx.font = '48px Arial' 20 ctx.fillText('Hello', 50, 150) 21 22 textureRef.current = new THREE.CanvasTexture(canvas) 23 }, []) 24 25 // Update texture dynamically 26 useFrame(({ clock }) => { 27 if (textureRef.current) { 28 const canvas = textureRef.current.image 29 const ctx = canvas.getContext('2d') 30 ctx.fillStyle = `hsl(${clock.elapsedTime * 50}, 100%, 50%)` 31 ctx.fillRect(0, 0, 256, 256) 32 textureRef.current.needsUpdate = true 33 } 34 }) 35 36 return ( 37 <mesh ref={meshRef}> 38 <planeGeometry args={[2, 2]} /> 39 <meshBasicMaterial map={textureRef.current} /> 40 </mesh> 41 ) 42}

Data Textures

tsx
1import { useMemo } from 'react' 2import * as THREE from 'three' 3 4function NoiseTexture() { 5 const texture = useMemo(() => { 6 const size = 256 7 const data = new Uint8Array(size * size * 4) 8 9 for (let i = 0; i < size * size; i++) { 10 const value = Math.random() * 255 11 data[i * 4] = value 12 data[i * 4 + 1] = value 13 data[i * 4 + 2] = value 14 data[i * 4 + 3] = 255 15 } 16 17 const texture = new THREE.DataTexture(data, size, size) 18 texture.needsUpdate = true 19 return texture 20 }, []) 21 22 return ( 23 <mesh> 24 <planeGeometry args={[2, 2]} /> 25 <meshBasicMaterial map={texture} /> 26 </mesh> 27 ) 28}

Render Targets

Render to texture.

tsx
1import { useFBO } from '@react-three/drei' 2import { useFrame } from '@react-three/fiber' 3import { useRef } from 'react' 4 5function RenderToTexture() { 6 const fbo = useFBO(512, 512) 7 const meshRef = useRef() 8 const otherSceneRef = useRef() 9 10 useFrame(({ gl, camera }) => { 11 // Render other scene to FBO 12 gl.setRenderTarget(fbo) 13 gl.render(otherSceneRef.current, camera) 14 gl.setRenderTarget(null) 15 }) 16 17 return ( 18 <> 19 {/* Scene to render to texture */} 20 <group ref={otherSceneRef}> 21 <mesh position={[0, 0, -5]}> 22 <sphereGeometry args={[1, 32, 32]} /> 23 <meshStandardMaterial color="red" /> 24 </mesh> 25 </group> 26 27 {/* Display the texture */} 28 <mesh ref={meshRef}> 29 <planeGeometry args={[4, 4]} /> 30 <meshBasicMaterial map={fbo.texture} /> 31 </mesh> 32 </> 33 ) 34}

Texture Atlas / Sprite Sheet

tsx
1import { useTexture } from '@react-three/drei' 2import { useState } from 'react' 3import { useFrame } from '@react-three/fiber' 4import * as THREE from 'three' 5 6function SpriteAnimation() { 7 const texture = useTexture('/textures/spritesheet.png') 8 const [frame, setFrame] = useState(0) 9 10 // Configure texture 11 texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping 12 texture.repeat.set(1/4, 1/4) // 4x4 sprite sheet 13 14 useFrame(({ clock }) => { 15 const newFrame = Math.floor(clock.elapsedTime * 10) % 16 16 if (newFrame !== frame) { 17 setFrame(newFrame) 18 const col = newFrame % 4 19 const row = Math.floor(newFrame / 4) 20 texture.offset.set(col / 4, 1 - (row + 1) / 4) 21 } 22 }) 23 24 return ( 25 <mesh> 26 <planeGeometry args={[1, 1]} /> 27 <meshBasicMaterial map={texture} transparent /> 28 </mesh> 29 ) 30}

Material Texture Maps Reference

tsx
1<meshStandardMaterial 2 // Base color (sRGB) 3 map={colorTexture} 4 5 // Surface detail (Linear) 6 normalMap={normalTexture} 7 normalScale={[1, 1]} 8 9 // Roughness (Linear, grayscale) 10 roughnessMap={roughnessTexture} 11 roughness={1} // Multiplier 12 13 // Metalness (Linear, grayscale) 14 metalnessMap={metalnessTexture} 15 metalness={1} // Multiplier 16 17 // Ambient Occlusion (Linear, requires uv2) 18 aoMap={aoTexture} 19 aoMapIntensity={1} 20 21 // Self-illumination (sRGB) 22 emissiveMap={emissiveTexture} 23 emissive="#ffffff" 24 emissiveIntensity={1} 25 26 // Vertex displacement (Linear) 27 displacementMap={displacementTexture} 28 displacementScale={0.1} 29 displacementBias={0} 30 31 // Alpha (Linear) 32 alphaMap={alphaTexture} 33 transparent={true} 34 35 // Environment reflection 36 envMap={envTexture} 37 envMapIntensity={1} 38 39 // Lightmap (requires uv2) 40 lightMap={lightmapTexture} 41 lightMapIntensity={1} 42/>

Second UV Channel (for AO/Lightmaps)

tsx
1import { useEffect, useRef } from 'react' 2 3function MeshWithUV2() { 4 const meshRef = useRef() 5 6 useEffect(() => { 7 // Copy uv to uv2 for aoMap/lightMap 8 const geometry = meshRef.current.geometry 9 geometry.setAttribute('uv2', geometry.attributes.uv) 10 }, []) 11 12 return ( 13 <mesh ref={meshRef}> 14 <boxGeometry /> 15 <meshStandardMaterial 16 aoMap={aoTexture} 17 aoMapIntensity={1} 18 /> 19 </mesh> 20 ) 21}

Suspense Loading

tsx
1import { Suspense } from 'react' 2import { useTexture } from '@react-three/drei' 3 4function TexturedMesh() { 5 const texture = useTexture('/textures/large.jpg') 6 return ( 7 <mesh> 8 <boxGeometry /> 9 <meshStandardMaterial map={texture} /> 10 </mesh> 11 ) 12} 13 14function Fallback() { 15 return ( 16 <mesh> 17 <boxGeometry /> 18 <meshBasicMaterial color="gray" wireframe /> 19 </mesh> 20 ) 21} 22 23function Scene() { 24 return ( 25 <Suspense fallback={<Fallback />}> 26 <TexturedMesh /> 27 </Suspense> 28 ) 29}

Performance Tips

  1. Use power-of-2 dimensions: 256, 512, 1024, 2048
  2. Compress textures: Use KTX2/Basis for web
  3. Enable mipmaps: For distant objects
  4. Limit texture size: 2048 usually sufficient
  5. Reuse textures: Same texture = better batching
  6. Preload important textures: Avoid pop-in
tsx
1// Preload critical textures 2useTexture.preload('/textures/hero.jpg') 3 4// Check texture memory 5useFrame(({ gl }) => { 6 console.log('Textures:', gl.info.memory.textures) 7}) 8 9// Dispose unused textures (R3F usually handles this) 10texture.dispose()

See Also

  • r3f-materials - Applying textures to materials
  • r3f-loaders - Asset loading patterns
  • r3f-shaders - Custom texture sampling

FAQ & Installation Steps

These questions and steps mirror the structured data on this page for better search understanding.

? Frequently Asked Questions

What is r3f-textures?

Perfect for Frontend Agents needing advanced 3D texture rendering capabilities with React Three Fiber r3f-textures is a React Three Fiber skill that enables developers to create and manage 3D textures using the useTexture hook from @react-three/drei

How do I install r3f-textures?

Run the command: npx killer-skills add EnzeD/r3f-skills/r3f-textures. It works with Cursor, Windsurf, VS Code, Claude Code, and 15+ other IDEs.

What are the use cases for r3f-textures?

Key use cases include: Rendering 3D scenes with custom textures, Creating immersive experiences with ambientLight and meshStandardMaterial, Optimizing 3D model performance with efficient texture loading.

Which IDEs are compatible with r3f-textures?

This skill is compatible with Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use the Killer-Skills CLI for universal one-command installation.

Are there any limitations for r3f-textures?

Requires React Three Fiber and @react-three/drei libraries. Limited to 3D texture rendering only.

How To Install

  1. 1. Open your terminal

    Open the terminal or command line in your project directory.

  2. 2. Run the install command

    Run: npx killer-skills add EnzeD/r3f-skills/r3f-textures. The CLI will automatically detect your IDE or AI agent and configure the skill.

  3. 3. Start using the skill

    The skill is now active. Your AI agent can use r3f-textures immediately in the current project.

Related Skills

Looking for an alternative to r3f-textures or building a community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

linear

Logo of lobehub
lobehub

Linear is a workflow management system that enables multi-agent collaboration, effortless agent team design, and introduces agents as the unit of work interaction.

73.4k
0
Communication

testing

Logo of lobehub
lobehub

Testing is a process for verifying AI agent functionality using commands like bunx vitest run and optimizing workflows with targeted test runs.

73.3k
0
Communication

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication