r3f-materials
React Three Fiber materials - PBR materials, Drei materials, shader materials, material properties. Use when styling meshes, creating custom materials, working with textures, or implementing visual effects.
Best use case
r3f-materials is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
React Three Fiber materials - PBR materials, Drei materials, shader materials, material properties. Use when styling meshes, creating custom materials, working with textures, or implementing visual effects.
Teams using r3f-materials should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/r3f-materials/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How r3f-materials Compares
| Feature / Agent | r3f-materials | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
React Three Fiber materials - PBR materials, Drei materials, shader materials, material properties. Use when styling meshes, creating custom materials, working with textures, or implementing visual effects.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# React Three Fiber Materials
## Quick Start
```tsx
import { Canvas } from '@react-three/fiber'
function Scene() {
return (
<Canvas>
<ambientLight intensity={0.5} />
<directionalLight position={[5, 5, 5]} />
<mesh>
<boxGeometry />
<meshStandardMaterial
color="hotpink"
roughness={0.5}
metalness={0.5}
/>
</mesh>
</Canvas>
)
}
```
## Material Types Overview
| Material | Use Case | Lighting |
|----------|----------|----------|
| meshBasicMaterial | Unlit, flat colors | No |
| meshLambertMaterial | Matte surfaces, fast | Yes (diffuse) |
| meshPhongMaterial | Shiny, specular | Yes |
| meshStandardMaterial | PBR, realistic | Yes (PBR) |
| meshPhysicalMaterial | Advanced PBR | Yes (PBR+) |
| meshToonMaterial | Cel-shaded | Yes (toon) |
| meshNormalMaterial | Debug normals | No |
| shaderMaterial | Custom GLSL | Custom |
## meshBasicMaterial
No lighting calculations. Always visible, fast.
```tsx
<mesh>
<boxGeometry />
<meshBasicMaterial
color="red"
transparent
opacity={0.5}
side={THREE.DoubleSide} // FrontSide, BackSide, DoubleSide
wireframe={false}
map={colorTexture}
alphaMap={alphaTexture}
envMap={envTexture}
fog={true}
/>
</mesh>
```
## meshStandardMaterial (PBR)
Physically-based rendering. Recommended for realistic results.
```tsx
import { useTexture } from '@react-three/drei'
import * as THREE from 'three'
function PBRMesh() {
// Load PBR texture set
const [colorMap, normalMap, roughnessMap, metalnessMap, aoMap] = useTexture([
'/textures/color.jpg',
'/textures/normal.jpg',
'/textures/roughness.jpg',
'/textures/metalness.jpg',
'/textures/ao.jpg',
])
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshStandardMaterial
// Base color
color="#ffffff"
map={colorMap}
// PBR properties
roughness={1} // 0 = mirror, 1 = diffuse
roughnessMap={roughnessMap}
metalness={0} // 0 = dielectric, 1 = metal
metalnessMap={metalnessMap}
// Surface detail
normalMap={normalMap}
normalScale={[1, 1]}
// Ambient occlusion (requires uv2)
aoMap={aoMap}
aoMapIntensity={1}
// Emissive
emissive="#000000"
emissiveIntensity={1}
emissiveMap={emissiveTexture}
// Environment
envMap={envTexture}
envMapIntensity={1}
// Other
flatShading={false}
fog={true}
transparent={false}
/>
</mesh>
)
}
```
## meshPhysicalMaterial (Advanced PBR)
Extends Standard with clearcoat, transmission, sheen, etc.
```tsx
// Glass material
function Glass() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshPhysicalMaterial
color="#ffffff"
metalness={0}
roughness={0}
transmission={1} // 0 = opaque, 1 = fully transparent
thickness={0.5} // Volume thickness for refraction
ior={1.5} // Index of refraction (glass ~1.5)
envMapIntensity={1}
/>
</mesh>
)
}
// Car paint
function CarPaint() {
return (
<mesh>
<boxGeometry />
<meshPhysicalMaterial
color="#ff0000"
metalness={0.9}
roughness={0.5}
clearcoat={1} // Clearcoat layer strength
clearcoatRoughness={0.1} // Clearcoat roughness
/>
</mesh>
)
}
// Fabric/velvet (sheen)
function Fabric() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshPhysicalMaterial
color="#8844aa"
roughness={0.8}
sheen={1}
sheenRoughness={0.5}
sheenColor="#ff88ff"
/>
</mesh>
)
}
// Iridescent (soap bubbles)
function Iridescent() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshPhysicalMaterial
color="#ffffff"
iridescence={1}
iridescenceIOR={1.3}
iridescenceThicknessRange={[100, 400]}
/>
</mesh>
)
}
```
## Drei Special Materials
### MeshReflectorMaterial
Realistic mirror-like reflections.
```tsx
import { MeshReflectorMaterial } from '@react-three/drei'
function ReflectiveFloor() {
return (
<mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.5, 0]}>
<planeGeometry args={[10, 10]} />
<MeshReflectorMaterial
blur={[400, 100]} // Blur amount [x, y]
resolution={1024} // Reflection resolution
mixBlur={1} // Mix blur with reflection
mixStrength={0.5} // Reflection strength
roughness={1}
depthScale={1.2}
minDepthThreshold={0.4}
maxDepthThreshold={1.4}
color="#333"
metalness={0.5}
mirror={0.5}
/>
</mesh>
)
}
```
### MeshWobbleMaterial
Animated wobble effect.
```tsx
import { MeshWobbleMaterial } from '@react-three/drei'
function WobblyMesh() {
return (
<mesh>
<torusKnotGeometry args={[1, 0.4, 100, 16]} />
<MeshWobbleMaterial
factor={1} // Wobble amplitude
speed={2} // Wobble speed
color="hotpink"
metalness={0}
roughness={0.5}
/>
</mesh>
)
}
```
### MeshDistortMaterial
Perlin noise distortion.
```tsx
import { MeshDistortMaterial } from '@react-three/drei'
function DistortedMesh() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<MeshDistortMaterial
distort={0.5} // Distortion amount
speed={2} // Animation speed
color="cyan"
roughness={0.2}
/>
</mesh>
)
}
```
### MeshTransmissionMaterial
Better glass/refractive materials.
```tsx
import { MeshTransmissionMaterial } from '@react-three/drei'
function GlassSphere() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<MeshTransmissionMaterial
backside // Render backside
samples={16} // Refraction samples
resolution={1024} // Buffer resolution
transmission={1} // Transmission factor
roughness={0.0}
thickness={0.5} // Volume thickness
ior={1.5} // Index of refraction
chromaticAberration={0.06}
anisotropy={0.1}
distortion={0.0}
distortionScale={0.3}
temporalDistortion={0.5}
clearcoat={1}
attenuationDistance={0.5}
attenuationColor="#ffffff"
color="#c9ffa1"
/>
</mesh>
)
}
```
### MeshDiscardMaterial
Discard fragments - useful for shadows only.
```tsx
import { MeshDiscardMaterial } from '@react-three/drei'
function ShadowOnlyMesh() {
return (
<mesh castShadow>
<boxGeometry />
<MeshDiscardMaterial /> {/* Invisible but casts shadows */}
</mesh>
)
}
```
## Points and Lines Materials
```tsx
// Points material
<points>
<bufferGeometry />
<pointsMaterial
size={0.1}
sizeAttenuation={true}
color="white"
map={spriteTexture}
transparent
alphaTest={0.5}
vertexColors
/>
</points>
// Line materials
<line>
<bufferGeometry />
<lineBasicMaterial color="white" linewidth={1} />
</line>
<line>
<bufferGeometry />
<lineDashedMaterial
color="white"
dashSize={0.5}
gapSize={0.25}
scale={1}
/>
</line>
```
## Common Material Properties
All materials share these base properties:
```tsx
<meshStandardMaterial
// Visibility
visible={true}
transparent={false}
opacity={1}
alphaTest={0} // Discard pixels with alpha < value
// Rendering
side={THREE.FrontSide} // FrontSide, BackSide, DoubleSide
depthTest={true}
depthWrite={true}
colorWrite={true}
// Blending
blending={THREE.NormalBlending}
// NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending
// Polygon offset (z-fighting fix)
polygonOffset={false}
polygonOffsetFactor={0}
polygonOffsetUnits={0}
// Misc
dithering={false}
toneMapped={true}
/>
```
## Dynamic Materials
### Updating Material Properties
```tsx
import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'
function AnimatedMaterial() {
const materialRef = useRef()
useFrame(({ clock }) => {
const t = clock.elapsedTime
// Update color
materialRef.current.color.setHSL((t * 0.1) % 1, 1, 0.5)
// Update properties
materialRef.current.roughness = (Math.sin(t) + 1) / 2
})
return (
<mesh>
<boxGeometry />
<meshStandardMaterial ref={materialRef} />
</mesh>
)
}
```
### Shared Materials
```tsx
import { useMemo } from 'react'
import * as THREE from 'three'
function SharedMaterial() {
// Create once, use many times
const material = useMemo(() =>
new THREE.MeshStandardMaterial({ color: 'red' }),
[])
return (
<>
<mesh position={[-2, 0, 0]} material={material}>
<boxGeometry />
</mesh>
<mesh position={[0, 0, 0]} material={material}>
<sphereGeometry />
</mesh>
<mesh position={[2, 0, 0]} material={material}>
<coneGeometry />
</mesh>
</>
)
}
```
## Multiple Materials
```tsx
// Different materials per face (BoxGeometry has 6 material groups)
<mesh>
<boxGeometry />
<meshStandardMaterial attach="material-0" color="red" /> {/* +X */}
<meshStandardMaterial attach="material-1" color="green" /> {/* -X */}
<meshStandardMaterial attach="material-2" color="blue" /> {/* +Y */}
<meshStandardMaterial attach="material-3" color="yellow" />{/* -Y */}
<meshStandardMaterial attach="material-4" color="cyan" /> {/* +Z */}
<meshStandardMaterial attach="material-5" color="magenta" />{/* -Z */}
</mesh>
```
## Material with Textures
```tsx
import { useTexture } from '@react-three/drei'
import * as THREE from 'three'
function TexturedMaterial() {
// Named object pattern (recommended)
const textures = useTexture({
map: '/textures/color.jpg',
normalMap: '/textures/normal.jpg',
roughnessMap: '/textures/roughness.jpg',
})
// Set texture properties
Object.values(textures).forEach(texture => {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
texture.repeat.set(2, 2)
})
return (
<mesh>
<planeGeometry args={[5, 5]} />
<meshStandardMaterial {...textures} />
</mesh>
)
}
```
## Emissive Materials (Glow)
```tsx
// For bloom effect, emissive colors should exceed normal range
<meshStandardMaterial
color="black"
emissive="#ff0000"
emissiveIntensity={2} // > 1 for bloom
toneMapped={false} // Required for colors > 1
/>
// With emissive map
<meshStandardMaterial
emissive="white"
emissiveMap={emissiveTexture}
emissiveIntensity={2}
toneMapped={false}
/>
```
## Environment Maps
```tsx
import { useEnvironment } from '@react-three/drei'
function EnvMappedMaterial() {
const envMap = useEnvironment({ preset: 'sunset' })
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshStandardMaterial
metalness={1}
roughness={0}
envMap={envMap}
envMapIntensity={1}
/>
</mesh>
)
}
```
## Custom Shader Materials
See `r3f-shaders` for detailed shader material usage.
```tsx
import { shaderMaterial } from '@react-three/drei'
import { extend } from '@react-three/fiber'
const CustomMaterial = shaderMaterial(
{ time: 0, color: new THREE.Color('hotpink') },
// Vertex shader
`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
// Fragment shader
`
uniform float time;
uniform vec3 color;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(color * (sin(time + vUv.x * 10.0) * 0.5 + 0.5), 1.0);
}
`
)
extend({ CustomMaterial })
function CustomShaderMesh() {
const materialRef = useRef()
useFrame(({ clock }) => {
materialRef.current.time = clock.elapsedTime
})
return (
<mesh>
<boxGeometry />
<customMaterial ref={materialRef} />
</mesh>
)
}
```
## Performance Tips
1. **Reuse materials**: Same material instance = batched draw calls
2. **Avoid transparent**: Requires sorting, slower
3. **Use alphaTest over transparent**: When possible, faster
4. **Simpler materials**: Basic > Lambert > Phong > Standard > Physical
5. **Limit texture sizes**: 1024-2048 usually sufficient
```tsx
// Material caching pattern
const materialCache = new Map()
function getCachedMaterial(color) {
const key = color.toString()
if (!materialCache.has(key)) {
materialCache.set(key, new THREE.MeshStandardMaterial({ color }))
}
return materialCache.get(key)
}
```
## See Also
- `r3f-textures` - Texture loading and configuration
- `r3f-shaders` - Custom shader development
- `r3f-lighting` - Light interaction with materialsRelated Skills
effect-best-practices
Enforces Effect-TS patterns for services, errors, layers, and atoms. Use when writing code with Effect.Service, Schema.TaggedError, Layer composition, or effect-atom React components.
web-design-guidelines
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
vercel-react-best-practices
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
vercel-composition-patterns
React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes.
remotion-best-practices
Best practices for Remotion - Video creation in React
react-email
Use when building HTML email templates with React components, adding a visual email editor to an application using the React Email visual editor, rendering emails to HTML, or sending emails with Resend. Covers welcome emails, password resets, notifications, order confirmations, newsletters, transactional emails, and the embeddable email editor component.
r3f-textures
React Three Fiber textures - useTexture, texture loading, environment maps, texture configuration. Use when loading images, working with PBR texture sets, cubemaps, HDR environments, or optimizing texture usage.
r3f-shaders
React Three Fiber shaders - GLSL, shaderMaterial, uniforms, custom effects. Use when creating custom visual effects, modifying vertices, writing fragment shaders, or extending built-in materials.
r3f-postprocessing
React Three Fiber post-processing - @react-three/postprocessing, bloom, DOF, screen effects. Use when adding visual effects, color grading, blur, glow, or creating custom screen-space shaders.
r3f-physics
React Three Fiber physics with Rapier - RigidBody, colliders, forces, joints, sensors. Use when adding physics simulation, collision detection, character controllers, or creating interactive physics-based experiences.
r3f-loaders
React Three Fiber asset loading - useGLTF, useLoader, Suspense patterns, preloading. Use when loading 3D models, textures, HDR environments, or managing loading states.
r3f-lighting
React Three Fiber lighting - light types, shadows, Environment component, IBL. Use when adding lights, configuring shadows, setting up environment lighting, or optimizing lighting performance.