or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

abstractions.mdcameras.mdcontrols.mdgizmos.mdhooks.mdindex.mdloaders.mdmaterials.mdperformance.mdstaging.mdweb-integration.md

hooks.mddocs/

0

# Hooks

1

2

React hooks for animations, state management, and Three.js integration. These hooks provide seamless integration between React patterns and Three.js functionality, enabling declarative 3D programming.

3

4

## Capabilities

5

6

### useAnimations

7

8

Animation control hook for managing GLTF animations with play, pause, and crossfading capabilities.

9

10

```typescript { .api }

11

/**

12

* Animation control hook for GLTF animations

13

* @param clips - Animation clips from GLTF loader

14

* @param root - Target object for animations

15

* @returns Animation API with controls and state

16

*/

17

function useAnimations<T extends AnimationClip>(

18

clips: T[],

19

root?: React.RefObject<Object3D>

20

): Api<T>;

21

22

interface Api<T extends AnimationClip> {

23

/** Reference to the animated object */

24

ref: React.RefObject<Object3D | undefined | null>;

25

/** Animation clips array */

26

clips: AnimationClip[];

27

/** Three.js animation mixer */

28

mixer: AnimationMixer;

29

/** Animation clip names */

30

names: T['name'][];

31

/** Animation actions mapped by name */

32

actions: { [key in T['name']]: AnimationAction | null };

33

}

34

```

35

36

**Usage Examples:**

37

38

```typescript

39

import { useAnimations, useGLTF } from '@react-three/drei';

40

41

function AnimatedModel() {

42

const group = useRef();

43

const { nodes, materials, animations } = useGLTF('/model.glb');

44

const { actions, names } = useAnimations(animations, group);

45

46

// Play animation on mount

47

useEffect(() => {

48

actions['Walk']?.play();

49

}, [actions]);

50

51

// Control animations

52

const switchAnimation = (name) => {

53

// Crossfade between animations

54

actions[name]?.reset().fadeIn(0.5).play();

55

Object.keys(actions).forEach((key) => {

56

if (key !== name) {

57

actions[key]?.fadeOut(0.5);

58

}

59

});

60

};

61

62

return (

63

<group ref={group}>

64

<primitive object={nodes.Scene} />

65

{/* Animation controls */}

66

<Html>

67

{names.map((name) => (

68

<button key={name} onClick={() => switchAnimation(name)}>

69

{name}

70

</button>

71

))}

72

</Html>

73

</group>

74

);

75

}

76

```

77

78

### useGLTF

79

80

GLTF model loading hook with automatic disposal and type safety.

81

82

```typescript { .api }

83

/**

84

* GLTF model loading hook with automatic disposal

85

* @param path - Path to GLTF file

86

* @param useDraco - Use Draco compression, true

87

* @param useMeshOpt - Use MeshOpt compression, true

88

* @returns GLTF object with nodes, materials, and animations

89

*/

90

function useGLTF(path: string, useDraco?: boolean, useMeshOpt?: boolean): GLTF & ObjectMap;

91

92

interface GLTF {

93

animations: AnimationClip[];

94

scene: Group;

95

scenes: Group[];

96

cameras: Camera[];

97

asset: object;

98

}

99

100

interface ObjectMap {

101

nodes: { [name: string]: Object3D };

102

materials: { [name: string]: Material };

103

}

104

```

105

106

**Usage Examples:**

107

108

```typescript

109

import { useGLTF } from '@react-three/drei';

110

111

function Model({ path }) {

112

const { nodes, materials } = useGLTF(path);

113

114

return (

115

<group>

116

<mesh

117

geometry={nodes.Mesh.geometry}

118

material={materials.Material}

119

/>

120

</group>

121

);

122

}

123

124

// Preload models

125

useGLTF.preload('/model.glb');

126

```

127

128

### useTexture

129

130

Texture loading hook with multiple format support and automatic disposal.

131

132

```typescript { .api }

133

/**

134

* Texture loading hook with format support

135

* @param input - Texture path or array of paths

136

* @returns Texture or array of textures

137

*/

138

function useTexture(input: string | string[]): Texture | Texture[];

139

```

140

141

**Usage Examples:**

142

143

```typescript

144

import { useTexture } from '@react-three/drei';

145

146

function TexturedMesh() {

147

const texture = useTexture('/texture.jpg');

148

149

return (

150

<mesh>

151

<planeGeometry />

152

<meshStandardMaterial map={texture} />

153

</mesh>

154

);

155

}

156

157

// Multiple textures

158

function MultiTexturedMesh() {

159

const [colorMap, normalMap, roughnessMap] = useTexture([

160

'/color.jpg',

161

'/normal.jpg',

162

'/roughness.jpg'

163

]);

164

165

return (

166

<mesh>

167

<sphereGeometry />

168

<meshStandardMaterial

169

map={colorMap}

170

normalMap={normalMap}

171

roughnessMap={roughnessMap}

172

/>

173

</mesh>

174

);

175

}

176

177

// Preload textures

178

useTexture.preload('/texture.jpg');

179

```

180

181

### useFont

182

183

Font loading hook for text rendering with caching support.

184

185

```typescript { .api }

186

/**

187

* Font loading hook for text rendering

188

* @param path - Path to font JSON file

189

* @returns Font data object

190

*/

191

function useFont(path: string): FontData;

192

193

interface FontData {

194

data: any;

195

glyphs: { [key: string]: Glyph };

196

}

197

198

interface Glyph {

199

x: number;

200

y: number;

201

width: number;

202

height: number;

203

xAdvance?: number;

204

xOffset?: number;

205

yOffset?: number;

206

}

207

```

208

209

**Usage Examples:**

210

211

```typescript

212

import { useFont, Text3D } from '@react-three/drei';

213

214

function StyledText() {

215

const font = useFont('/fonts/helvetiker_regular.json');

216

217

return (

218

<Text3D font={font} size={1} height={0.2}>

219

3D Text

220

<meshNormalMaterial />

221

</Text3D>

222

);

223

}

224

225

// Preload fonts

226

useFont.preload('/fonts/helvetiker_regular.json');

227

```

228

229

### useEnvironment

230

231

Environment texture loading hook with preset support and HDRI loading.

232

233

```typescript { .api }

234

/**

235

* Environment texture loading hook with presets

236

* @param props - Environment loader configuration

237

* @returns Environment texture

238

*/

239

function useEnvironment(props: EnvironmentLoaderProps): Texture;

240

241

interface EnvironmentLoaderProps {

242

/** Environment preset name */

243

preset?: PresetsType;

244

/** Custom environment files */

245

files?: string | string[];

246

/** Environment path */

247

path?: string;

248

/** Texture encoding */

249

encoding?: TextureEncoding;

250

}

251

```

252

253

**Usage Examples:**

254

255

```typescript

256

import { useEnvironment } from '@react-three/drei';

257

258

function ReflectiveSphere() {

259

const envMap = useEnvironment({ preset: 'sunset' });

260

261

return (

262

<mesh>

263

<sphereGeometry />

264

<meshStandardMaterial

265

envMap={envMap}

266

metalness={1}

267

roughness={0}

268

/>

269

</mesh>

270

);

271

}

272

273

// Custom HDRI environment

274

function CustomEnvironment() {

275

const envMap = useEnvironment({

276

files: '/hdri/studio.hdr',

277

encoding: RGBEEncoding

278

});

279

280

return (

281

<mesh>

282

<torusGeometry />

283

<meshStandardMaterial envMap={envMap} />

284

</mesh>

285

);

286

}

287

```

288

289

### useAspect

290

291

Aspect ratio calculation hook for responsive design and viewport adaptation.

292

293

```typescript { .api }

294

/**

295

* Aspect ratio calculation hook for responsive design

296

* @param width - Target width

297

* @param height - Target height

298

* @param factor - Scale factor, 1

299

* @returns Scaled dimensions [width, height, 1]

300

*/

301

function useAspect(width: number, height: number, factor?: number): [number, number, number];

302

```

303

304

**Usage Examples:**

305

306

```typescript

307

import { useAspect } from '@react-three/drei';

308

309

function ResponsivePlane() {

310

const scale = useAspect(1920, 1080, 0.5);

311

312

return (

313

<mesh scale={scale}>

314

<planeGeometry />

315

<meshBasicMaterial />

316

</mesh>

317

);

318

}

319

320

// Dynamic aspect ratio

321

function DynamicAspect() {

322

const { viewport } = useThree();

323

const scale = useAspect(viewport.width, viewport.height, 0.8);

324

325

return (

326

<mesh scale={scale}>

327

<planeGeometry />

328

<meshBasicMaterial />

329

</mesh>

330

);

331

}

332

```

333

334

### useCamera

335

336

Camera access hook for getting the current scene camera.

337

338

```typescript { .api }

339

/**

340

* Camera access hook for getting current camera

341

* @returns Current camera object

342

*/

343

function useCamera(): Camera;

344

```

345

346

**Usage Examples:**

347

348

```typescript

349

import { useCamera } from '@react-three/drei';

350

351

function CameraInfo() {

352

const camera = useCamera();

353

354

useFrame(() => {

355

console.log('Camera position:', camera.position);

356

console.log('Camera rotation:', camera.rotation);

357

});

358

359

return null;

360

}

361

```

362

363

### useIntersect

364

365

Intersection detection hook for visibility and hover effects.

366

367

```typescript { .api }

368

/**

369

* Intersection detection hook for visibility effects

370

* @param onChange - Callback when visibility changes

371

* @returns Ref to attach to target object

372

*/

373

function useIntersect<T extends Object3D>(

374

onChange: (visible: boolean) => void

375

): React.RefObject<T>;

376

```

377

378

**Usage Examples:**

379

380

```typescript

381

import { useIntersect } from '@react-three/drei';

382

383

function VisibilityDetector() {

384

const [visible, setVisible] = useState(false);

385

const ref = useIntersect((isVisible) => setVisible(isVisible));

386

387

return (

388

<mesh ref={ref}>

389

<boxGeometry />

390

<meshStandardMaterial

391

color={visible ? 'green' : 'red'}

392

emissive={visible ? 'darkgreen' : 'darkred'}

393

/>

394

</mesh>

395

);

396

}

397

```

398

399

### useDepthBuffer

400

401

Depth buffer hook for accessing scene depth information.

402

403

```typescript { .api }

404

/**

405

* Depth buffer hook for accessing depth information

406

* @param options - Depth buffer configuration

407

* @returns Depth buffer texture and controls

408

*/

409

function useDepthBuffer(options?: {

410

size?: number;

411

frames?: number;

412

}): {

413

buffer: WebGLRenderTarget;

414

camera: Camera;

415

}

416

```

417

418

### useContextBridge

419

420

Context bridging hook for sharing React context across R3F boundaries.

421

422

```typescript { .api }

423

/**

424

* Context bridging hook for sharing React context

425

* @param contexts - Array of React contexts to bridge

426

* @returns Bridge component

427

*/

428

function useContextBridge(...contexts: React.Context<any>[]): React.ComponentType<{ children: React.ReactNode }>;

429

```

430

431

**Usage Examples:**

432

433

```typescript

434

import { useContextBridge } from '@react-three/drei';

435

436

const ThemeContext = React.createContext();

437

const UserContext = React.createContext();

438

439

function Scene() {

440

const ContextBridge = useContextBridge(ThemeContext, UserContext);

441

442

return (

443

<ContextBridge>

444

<mesh>

445

<ThemedMaterial />

446

</mesh>

447

</ContextBridge>

448

);

449

}

450

```

451

452

### useBoxProjectedEnv

453

454

Box-projected environment mapping hook for realistic interior reflections.

455

456

```typescript { .api }

457

/**

458

* Box-projected environment mapping hook

459

* @param envMap - Environment map texture

460

* @param position - Box position

461

* @param size - Box size

462

* @returns Box-projected environment uniforms

463

*/

464

function useBoxProjectedEnv(

465

envMap: Texture,

466

position: [number, number, number],

467

size: [number, number, number]

468

): {

469

envMap: Texture;

470

cubeMapSize: Vector3;

471

cubeMapPos: Vector3;

472

};

473

```

474

475

## Integration Patterns

476

477

### Animation Sequencing

478

479

```typescript

480

function AnimationSequence() {

481

const group = useRef();

482

const { actions } = useAnimations(animations, group);

483

const [currentAnimation, setCurrentAnimation] = useState('idle');

484

485

const playSequence = async () => {

486

await playAnimation('walk', 2000);

487

await playAnimation('run', 3000);

488

await playAnimation('idle', 1000);

489

};

490

491

const playAnimation = (name, duration) => {

492

return new Promise((resolve) => {

493

actions[name]?.reset().play();

494

setTimeout(resolve, duration);

495

});

496

};

497

498

return (

499

<group ref={group}>

500

<primitive object={scene} />

501

</group>

502

);

503

}

504

```

505

506

### Responsive Textures

507

508

```typescript

509

function ResponsiveTexture() {

510

const { viewport } = useThree();

511

const isMobile = viewport.width < 768;

512

513

const texture = useTexture(

514

isMobile ? '/textures/low-res.jpg' : '/textures/high-res.jpg'

515

);

516

517

return (

518

<mesh>

519

<planeGeometry />

520

<meshStandardMaterial map={texture} />

521

</mesh>

522

);

523

}

524

```

525

526

### Dynamic Environment Loading

527

528

```typescript

529

function DynamicEnvironment() {

530

const [preset, setPreset] = useState('sunset');

531

const envMap = useEnvironment({ preset });

532

533

useEffect(() => {

534

const handleTimeChange = () => {

535

const hour = new Date().getHours();

536

if (hour < 6) setPreset('night');

537

else if (hour < 12) setPreset('dawn');

538

else if (hour < 18) setPreset('city');

539

else setPreset('sunset');

540

};

541

542

handleTimeChange();

543

const interval = setInterval(handleTimeChange, 60000);

544

return () => clearInterval(interval);

545

}, []);

546

547

return (

548

<mesh>

549

<sphereGeometry />

550

<meshStandardMaterial envMap={envMap} />

551

</mesh>

552

);

553

}

554

```

555

556

### Performance Optimization

557

558

```typescript

559

// Preload assets for better performance

560

const preloadAssets = () => {

561

useGLTF.preload('/models/character.glb');

562

useTexture.preload(['/textures/diffuse.jpg', '/textures/normal.jpg']);

563

useFont.preload('/fonts/roboto.json');

564

};

565

566

// Call during app initialization

567

useEffect(preloadAssets, []);

568

569

// Automatic cleanup

570

function Model({ url }) {

571

const gltf = useGLTF(url);

572

573

// Automatic disposal on unmount

574

useEffect(() => {

575

return () => gltf.dispose?.();

576

}, [gltf]);

577

578

return <primitive object={gltf.scene} />;

579

}

580

```

581

582

### useDepthBuffer

583

584

Hook for creating and managing depth buffer textures.

585

586

```typescript { .api }

587

/**

588

* Creates and manages depth buffer textures for depth-based effects

589

* @param config - Depth buffer configuration

590

* @returns Depth texture

591

*/

592

function useDepthBuffer(config?: DepthBufferConfig): DepthTexture;

593

594

interface DepthBufferConfig {

595

/** Buffer size, 256 */

596

size?: number;

597

/** Update frames, Infinity */

598

frames?: number;

599

}

600

```

601

602

### useContextBridge

603

604

Hook for bridging React contexts across portals and different render trees.

605

606

```typescript { .api }

607

/**

608

* Bridges React contexts across portals and render trees

609

* @param contexts - React contexts to bridge

610

* @returns Context bridge component

611

*/

612

function useContextBridge(...contexts: Array<React.Context<any>>): React.ComponentType<{children: React.ReactNode}>;

613

```

614

615

### useBoxProjectedEnv

616

617

Hook for box-projected environment mapping on materials.

618

619

```typescript { .api }

620

/**

621

* Applies box-projected environment mapping to materials

622

* @param envMap - Environment map texture

623

* @param config - Box projection configuration

624

* @returns Box projection utilities

625

*/

626

function useBoxProjectedEnv(

627

envMap: Texture,

628

config: BoxProjectedEnvConfig

629

): BoxProjectedEnvResult;

630

631

interface BoxProjectedEnvConfig {

632

/** Environment map size */

633

envMapSize: [number, number, number];

634

/** Environment map position */

635

envMapPosition: [number, number, number];

636

}

637

638

interface BoxProjectedEnvResult {

639

/** Apply to material */

640

apply: (material: Material) => void;

641

}

642

```