---
name: r3f-materials
description: Three.js materials in R3F, built-in materials (Standard, Physical, Basic, etc.), ShaderMaterial with custom GLSL, uniforms binding and animation, and material properties. Use when choosing materials, creating custom shaders, or binding dynamic uniforms.
---
# R3F Materials
Materials define surface appearance—color, texture, reflectivity, transparency, and custom shader effects.
## Quick Start
```tsx
// Built-in material
// Custom shader
```
## Built-in Materials
### Material Comparison
| Material | Lighting | Use Case | Performance |
|----------|----------|----------|-------------|
| `MeshBasicMaterial` | None | UI, unlit, debug | Fastest |
| `MeshStandardMaterial` | PBR | General 3D | Good |
| `MeshPhysicalMaterial` | PBR+ | Glass, car paint | Slower |
| `MeshLambertMaterial` | Diffuse | Matte surfaces | Fast |
| `MeshPhongMaterial` | Specular | Shiny plastic | Fast |
| `MeshToonMaterial` | Cel-shaded | Stylized | Good |
| `MeshNormalMaterial` | None | Debug normals | Fastest |
| `MeshDepthMaterial` | None | Depth passes | Fastest |
### MeshBasicMaterial (Unlit)
```tsx
```
### MeshStandardMaterial (PBR)
```tsx
```
### MeshPhysicalMaterial (Advanced PBR)
```tsx
```
### MeshToonMaterial (Cel-shaded)
```tsx
// Create gradient texture
const gradientTexture = useMemo(() => {
const canvas = document.createElement('canvas');
canvas.width = 4;
canvas.height = 1;
const ctx = canvas.getContext('2d')!;
// 4-step toon shading
ctx.fillStyle = '#444'; ctx.fillRect(0, 0, 1, 1);
ctx.fillStyle = '#888'; ctx.fillRect(1, 0, 1, 1);
ctx.fillStyle = '#bbb'; ctx.fillRect(2, 0, 1, 1);
ctx.fillStyle = '#fff'; ctx.fillRect(3, 0, 1, 1);
const texture = new THREE.CanvasTexture(canvas);
texture.minFilter = THREE.NearestFilter;
texture.magFilter = THREE.NearestFilter;
return texture;
}, []);
```
## Common Properties (All Materials)
```tsx
```
## Textures
### Loading Textures
```tsx
import { useTexture } from '@react-three/drei';
function TexturedMesh() {
const [colorMap, normalMap, roughnessMap] = useTexture([
'/textures/color.jpg',
'/textures/normal.jpg',
'/textures/roughness.jpg'
]);
return (
);
}
```
### Texture Settings
```tsx
import { useTexture } from '@react-three/drei';
import * as THREE from 'three';
const texture = useTexture('/texture.jpg', (tex) => {
tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
tex.repeat.set(4, 4);
tex.anisotropy = 16; // Sharper at angles
});
```
## ShaderMaterial
Full control via GLSL vertex and fragment shaders:
```tsx
import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import * as THREE from 'three';
const vertexShader = `
varying vec2 vUv;
varying vec3 vNormal;
void main() {
vUv = uv;
vNormal = normalize(normalMatrix * normal);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
const fragmentShader = `
uniform float uTime;
uniform vec3 uColor;
varying vec2 vUv;
varying vec3 vNormal;
void main() {
float pulse = sin(uTime * 2.0) * 0.5 + 0.5;
vec3 color = mix(uColor, vec3(1.0), pulse * 0.3);
// Simple rim lighting
float rim = 1.0 - dot(vNormal, vec3(0.0, 0.0, 1.0));
color += rim * 0.5;
gl_FragColor = vec4(color, 1.0);
}
`;
function CustomShaderMesh() {
const materialRef = useRef(null!);
useFrame(({ clock }) => {
materialRef.current.uniforms.uTime.value = clock.elapsedTime;
});
return (
);
}
```
## Uniforms
### Uniform Types
```tsx
uniforms={{
// Scalars
uFloat: { value: 1.0 },
uInt: { value: 1 },
uBool: { value: true },
// Vectors
uVec2: { value: new THREE.Vector2(1, 2) },
uVec3: { value: new THREE.Vector3(1, 2, 3) },
uVec4: { value: new THREE.Vector4(1, 2, 3, 4) },
uColor: { value: new THREE.Color('#ff0000') },
// Matrices
uMat3: { value: new THREE.Matrix3() },
uMat4: { value: new THREE.Matrix4() },
// Textures
uTexture: { value: texture },
uCubeTexture: { value: cubeTexture },
// Arrays
uFloatArray: { value: [1.0, 2.0, 3.0] },
uVec3Array: { value: [new THREE.Vector3(), new THREE.Vector3()] }
}}
```
### Animating Uniforms
```tsx
function AnimatedShader() {
const materialRef = useRef(null!);
useFrame(({ clock, mouse }) => {
const uniforms = materialRef.current.uniforms;
uniforms.uTime.value = clock.elapsedTime;
uniforms.uMouse.value.set(mouse.x, mouse.y);
uniforms.uResolution.value.set(window.innerWidth, window.innerHeight);
});
return (
);
}
```
### Shared Uniforms
```tsx
// Create shared uniform object
const globalUniforms = useMemo(() => ({
uTime: { value: 0 },
uGlobalColor: { value: new THREE.Color('#00ff00') }
}), []);
// Update in useFrame
useFrame(({ clock }) => {
globalUniforms.uTime.value = clock.elapsedTime;
});
// Use in multiple materials
```
## RawShaderMaterial
No built-in uniforms/attributes—full control:
```tsx
```
## Material Extensions
### Extend Existing Materials
```tsx
import { extend } from '@react-three/fiber';
import { shaderMaterial } from '@react-three/drei';
// Create extended material
const GradientMaterial = shaderMaterial(
// Uniforms
{ uColorA: new THREE.Color('#ff0000'), uColorB: new THREE.Color('#0000ff') },
// Vertex
`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
// Fragment
`
uniform vec3 uColorA;
uniform vec3 uColorB;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(mix(uColorA, uColorB, vUv.y), 1.0);
}
`
);
// Register with R3F
extend({ GradientMaterial });
// Use in JSX
function Gradient() {
return (
);
}
```
## Performance Tips
| Technique | When to Use |
|-----------|-------------|
| Share materials | Multiple meshes, same appearance |
| Use cheaper materials | Distant objects (Basic vs Standard) |
| Limit texture size | Mobile, large scene |
| Disable unneeded features | `fog={false}`, `toneMapped={false}` |
### Material Reuse
```tsx
// Define once
const sharedMaterial = useMemo(() => (
), []);
// Reuse (same GPU program)
{items.map((item, i) => (
{sharedMaterial}
))}
```
## File Structure
```
r3f-materials/
├── SKILL.md
├── references/
│ ├── pbr-properties.md # PBR material deep-dive
│ ├── uniform-types.md # Complete uniform reference
│ └── shader-templates.md # Common shader patterns
└── scripts/
├── materials/
│ ├── gradient.ts # Gradient shader material
│ ├── fresnel.ts # Fresnel/rim effect
│ └── dissolve.ts # Dissolve effect
└── utils/
└── uniform-helpers.ts # Uniform animation utilities
```
## Reference
- `references/pbr-properties.md` — Deep-dive into PBR material properties
- `references/uniform-types.md` — All uniform types and GLSL mappings
- `references/shader-templates.md` — Common shader effect patterns