or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation.mdcameras.mdgeometries.mdindex.mdlights.mdloaders.mdmaterials.mdmath.mdrenderers.mdscene-management.mdtsl.mdwebgpu.md

loaders.mddocs/

0

# Asset Loading

1

2

Three.js provides a comprehensive asset loading system for 3D models, textures, audio, and other media with progress tracking, error handling, and caching capabilities. The loading system supports various file formats and provides both callback-based and Promise-based APIs.

3

4

## Capabilities

5

6

### Loading Manager

7

8

Central coordination system for managing multiple asset loads with global progress tracking and error handling.

9

10

```javascript { .api }

11

/**

12

* Manages loading of multiple assets with progress tracking and coordination

13

*/

14

class LoadingManager {

15

/**

16

* Create loading manager with optional callbacks

17

* @param onLoad - Called when all items finish loading

18

* @param onProgress - Called when any item reports progress

19

* @param onError - Called when any item fails to load

20

*/

21

constructor(

22

onLoad?: () => void,

23

onProgress?: (url: string, itemsLoaded: number, itemsTotal: number) => void,

24

onError?: (url: string) => void

25

);

26

27

/** Callback when all items finish loading */

28

onLoad: (() => void) | undefined;

29

30

/** Callback for progress updates */

31

onProgress: ((url: string, itemsLoaded: number, itemsTotal: number) => void) | undefined;

32

33

/** Callback for loading errors */

34

onError: ((url: string) => void) | undefined;

35

36

/** Callback when loading starts */

37

onStart: ((url: string, itemsLoaded: number, itemsTotal: number) => void) | undefined;

38

39

/**

40

* Register item as loading

41

* @param url - URL being loaded

42

*/

43

itemStart(url: string): void;

44

45

/**

46

* Register item as completed loading

47

* @param url - URL that finished loading

48

*/

49

itemEnd(url: string): void;

50

51

/**

52

* Handle loading error for item

53

* @param url - URL that failed to load

54

*/

55

itemError(url: string): void;

56

57

/**

58

* Resolve URL using URL resolver function

59

* @param url - URL to resolve

60

* @returns Resolved URL

61

*/

62

resolveURL(url: string): string;

63

64

/**

65

* Set URL modifier function for rewriting URLs

66

* @param callback - Function to modify URLs before loading

67

*/

68

setURLModifier(callback?: (url: string) => string): LoadingManager;

69

70

/**

71

* Add regex handler for transforming URLs

72

* @param regex - Pattern to match URLs

73

* @param callback - Function to transform matching URLs

74

*/

75

addHandler(regex: RegExp, loader: Loader): LoadingManager;

76

77

/**

78

* Remove URL handler

79

* @param regex - Pattern to remove handler for

80

*/

81

removeHandler(regex: RegExp): LoadingManager;

82

83

/**

84

* Get appropriate loader for URL

85

* @param file - URL to find loader for

86

* @returns Loader instance or null

87

*/

88

getHandler(file: string): Loader | null;

89

}

90

91

/** Default global loading manager instance */

92

declare const DefaultLoadingManager: LoadingManager;

93

```

94

95

**Usage Example:**

96

97

```javascript

98

import { LoadingManager, TextureLoader, GLTFLoader } from 'three';

99

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

100

101

// Create manager with progress tracking

102

const manager = new LoadingManager(

103

() => console.log('All assets loaded!'),

104

(url, loaded, total) => console.log(`Loading: ${loaded}/${total} - ${url}`),

105

(url) => console.error(`Failed to load: ${url}`)

106

);

107

108

// Use manager with loaders

109

const textureLoader = new TextureLoader(manager);

110

const gltfLoader = new GLTFLoader(manager);

111

112

// Load multiple assets

113

const texture = textureLoader.load('texture.jpg');

114

gltfLoader.load('model.gltf', (gltf) => {

115

scene.add(gltf.scene);

116

});

117

```

118

119

### Base Loader

120

121

Abstract base class providing common functionality for all asset loaders.

122

123

```javascript { .api }

124

/**

125

* Base class for all Three.js asset loaders

126

*/

127

abstract class Loader<TData = any> {

128

/**

129

* Create loader with optional loading manager

130

* @param manager - Loading manager to coordinate with

131

*/

132

constructor(manager?: LoadingManager);

133

134

/** Loading manager coordinating this loader */

135

manager: LoadingManager;

136

137

/** Base path for resolving relative URLs */

138

path: string;

139

140

/** Base resource path for resolving relative URLs */

141

resourcePath: string;

142

143

/** Request headers to send with load requests */

144

requestHeader: { [header: string]: string };

145

146

/** Credentials mode for cross-origin requests */

147

crossOrigin: string;

148

149

/** Whether to include credentials in requests */

150

withCredentials: boolean;

151

152

/**

153

* Load asset from URL

154

* @param url - Asset URL to load

155

* @param onLoad - Success callback with loaded data

156

* @param onProgress - Progress callback

157

* @param onError - Error callback

158

* @returns Loaded data or loading placeholder

159

*/

160

abstract load(

161

url: string,

162

onLoad?: (data: TData) => void,

163

onProgress?: (event: ProgressEvent) => void,

164

onError?: (event: ErrorEvent) => void

165

): TData;

166

167

/**

168

* Load multiple assets in parallel

169

* @param urls - Array of URLs to load

170

* @param onLoad - Success callback with array of loaded data

171

* @param onProgress - Progress callback

172

* @param onError - Error callback

173

*/

174

loadAsync(url: string): Promise<TData>;

175

176

/**

177

* Set base path for resolving relative URLs

178

* @param path - Base path to use

179

* @returns This loader for chaining

180

*/

181

setPath(path: string): this;

182

183

/**

184

* Set resource path for resolving resource URLs

185

* @param resourcePath - Resource path to use

186

* @returns This loader for chaining

187

*/

188

setResourcePath(resourcePath: string): this;

189

190

/**

191

* Set request headers for HTTP requests

192

* @param requestHeader - Headers object

193

* @returns This loader for chaining

194

*/

195

setRequestHeader(requestHeader: { [header: string]: string }): this;

196

}

197

```

198

199

### Texture Loader

200

201

Specialized loader for image textures with support for various image formats and texture configuration.

202

203

```javascript { .api }

204

/**

205

* Loads images as Three.js textures with automatic format detection

206

*/

207

class TextureLoader extends Loader<Texture> {

208

/**

209

* Create texture loader

210

* @param manager - Optional loading manager

211

*/

212

constructor(manager?: LoadingManager);

213

214

/**

215

* Load texture from image URL

216

* @param url - Image URL to load

217

* @param onLoad - Success callback with loaded texture

218

* @param onProgress - Progress callback

219

* @param onError - Error callback

220

* @returns Texture object (loads asynchronously)

221

*/

222

load(

223

url: string,

224

onLoad?: (texture: Texture) => void,

225

onProgress?: (event: ProgressEvent) => void,

226

onError?: (event: ErrorEvent) => void

227

): Texture;

228

229

/**

230

* Load texture asynchronously with Promise

231

* @param url - Image URL to load

232

* @returns Promise resolving to loaded texture

233

*/

234

loadAsync(url: string): Promise<Texture>;

235

}

236

```

237

238

**Usage Example:**

239

240

```javascript

241

import { TextureLoader, MeshBasicMaterial, PlaneGeometry, Mesh } from 'three';

242

243

const loader = new TextureLoader();

244

245

// Load texture with callbacks

246

const texture = loader.load(

247

'path/to/texture.jpg',

248

(texture) => {

249

console.log('Texture loaded:', texture);

250

// Texture is ready to use

251

},

252

(progress) => {

253

console.log('Loading progress:', progress.loaded / progress.total);

254

},

255

(error) => {

256

console.error('Loading failed:', error);

257

}

258

);

259

260

// Use texture immediately (will appear when loaded)

261

const material = new MeshBasicMaterial({ map: texture });

262

const geometry = new PlaneGeometry(1, 1);

263

const mesh = new Mesh(geometry, material);

264

265

// Or load with async/await

266

async function loadTexture() {

267

try {

268

const texture = await loader.loadAsync('path/to/texture.jpg');

269

const material = new MeshBasicMaterial({ map: texture });

270

// Use material...

271

} catch (error) {

272

console.error('Failed to load texture:', error);

273

}

274

}

275

```

276

277

### Cube Texture Loader

278

279

Loader for cube textures used in environment mapping and skyboxes.

280

281

```javascript { .api }

282

/**

283

* Loads six images as cube texture for environment mapping

284

*/

285

class CubeTextureLoader extends Loader<CubeTexture> {

286

/**

287

* Create cube texture loader

288

* @param manager - Optional loading manager

289

*/

290

constructor(manager?: LoadingManager);

291

292

/**

293

* Load cube texture from six image URLs

294

* @param urls - Array of 6 image URLs [+X, -X, +Y, -Y, +Z, -Z]

295

* @param onLoad - Success callback with loaded cube texture

296

* @param onProgress - Progress callback

297

* @param onError - Error callback

298

* @returns CubeTexture object (loads asynchronously)

299

*/

300

load(

301

urls: string[],

302

onLoad?: (texture: CubeTexture) => void,

303

onProgress?: (event: ProgressEvent) => void,

304

onError?: (event: ErrorEvent) => void

305

): CubeTexture;

306

307

/**

308

* Load cube texture asynchronously with Promise

309

* @param urls - Array of 6 image URLs

310

* @returns Promise resolving to loaded cube texture

311

*/

312

loadAsync(urls: string[]): Promise<CubeTexture>;

313

}

314

```

315

316

### File Loader

317

318

Low-level loader for arbitrary file types with configurable response types.

319

320

```javascript { .api }

321

/**

322

* Generic file loader supporting various response types

323

*/

324

class FileLoader extends Loader<string | ArrayBuffer> {

325

/**

326

* Create file loader

327

* @param manager - Optional loading manager

328

*/

329

constructor(manager?: LoadingManager);

330

331

/** MIME type for requests */

332

mimeType: string | undefined;

333

334

/** Response type for XMLHttpRequest */

335

responseType: string | undefined;

336

337

/**

338

* Load file from URL

339

* @param url - File URL to load

340

* @param onLoad - Success callback with file data

341

* @param onProgress - Progress callback

342

* @param onError - Error callback

343

* @returns File data (string or ArrayBuffer based on responseType)

344

*/

345

load(

346

url: string,

347

onLoad?: (data: string | ArrayBuffer) => void,

348

onProgress?: (event: ProgressEvent) => void,

349

onError?: (event: ErrorEvent) => void

350

): string | ArrayBuffer;

351

352

/**

353

* Set MIME type for requests

354

* @param mimeType - MIME type string

355

* @returns This loader for chaining

356

*/

357

setMimeType(mimeType: string): this;

358

359

/**

360

* Set response type for XMLHttpRequest

361

* @param responseType - Response type ('text', 'arraybuffer', 'blob', 'document', 'json')

362

* @returns This loader for chaining

363

*/

364

setResponseType(responseType: string): this;

365

}

366

```

367

368

### Image Loaders

369

370

Specialized loaders for different image loading scenarios.

371

372

```javascript { .api }

373

/**

374

* Loads images as HTML Image elements

375

*/

376

class ImageLoader extends Loader<HTMLImageElement> {

377

/**

378

* Create image loader

379

* @param manager - Optional loading manager

380

*/

381

constructor(manager?: LoadingManager);

382

383

/**

384

* Load image from URL

385

* @param url - Image URL to load

386

* @param onLoad - Success callback with loaded image

387

* @param onProgress - Progress callback (may not be supported)

388

* @param onError - Error callback

389

* @returns HTMLImageElement (loads asynchronously)

390

*/

391

load(

392

url: string,

393

onLoad?: (image: HTMLImageElement) => void,

394

onProgress?: (event: ProgressEvent) => void,

395

onError?: (event: ErrorEvent) => void

396

): HTMLImageElement;

397

}

398

399

/**

400

* Loads images as ImageBitmap objects for high-performance usage

401

*/

402

class ImageBitmapLoader extends Loader<ImageBitmap> {

403

/**

404

* Create ImageBitmap loader

405

* @param manager - Optional loading manager

406

*/

407

constructor(manager?: LoadingManager);

408

409

/** Options for createImageBitmap */

410

options: ImageBitmapOptions | undefined;

411

412

/**

413

* Load image as ImageBitmap

414

* @param url - Image URL to load

415

* @param onLoad - Success callback with ImageBitmap

416

* @param onProgress - Progress callback

417

* @param onError - Error callback

418

* @returns Promise-like object for ImageBitmap

419

*/

420

load(

421

url: string,

422

onLoad?: (imageBitmap: ImageBitmap) => void,

423

onProgress?: (event: ProgressEvent) => void,

424

onError?: (event: ErrorEvent) => void

425

): any;

426

427

/**

428

* Set options for ImageBitmap creation

429

* @param options - ImageBitmap creation options

430

* @returns This loader for chaining

431

*/

432

setOptions(options: ImageBitmapOptions): this;

433

}

434

```

435

436

### Data Texture Loader

437

438

Loader for raw texture data and specialized texture formats.

439

440

```javascript { .api }

441

/**

442

* Loads raw data as DataTexture objects

443

*/

444

class DataTextureLoader extends Loader<DataTexture> {

445

/**

446

* Create data texture loader

447

* @param manager - Optional loading manager

448

*/

449

constructor(manager?: LoadingManager);

450

451

/**

452

* Load raw data as texture

453

* @param url - Data URL to load

454

* @param onLoad - Success callback with DataTexture

455

* @param onProgress - Progress callback

456

* @param onError - Error callback

457

* @returns DataTexture object

458

*/

459

load(

460

url: string,

461

onLoad?: (dataTexture: DataTexture) => void,

462

onProgress?: (event: ProgressEvent) => void,

463

onError?: (event: ErrorEvent) => void

464

): DataTexture;

465

}

466

```

467

468

### Compressed Texture Loader

469

470

Loader for GPU-compressed texture formats for optimized memory usage and performance.

471

472

```javascript { .api }

473

/**

474

* Loads compressed texture formats (DXT, ETC, ASTC, etc.)

475

*/

476

class CompressedTextureLoader extends Loader<CompressedTexture> {

477

/**

478

* Create compressed texture loader

479

* @param manager - Optional loading manager

480

*/

481

constructor(manager?: LoadingManager);

482

483

/**

484

* Load compressed texture data

485

* @param url - Compressed texture URL

486

* @param onLoad - Success callback with CompressedTexture

487

* @param onProgress - Progress callback

488

* @param onError - Error callback

489

* @returns CompressedTexture object

490

*/

491

load(

492

url: string,

493

onLoad?: (texture: CompressedTexture) => void,

494

onProgress?: (event: ProgressEvent) => void,

495

onError?: (event: ErrorEvent) => void

496

): CompressedTexture;

497

}

498

```

499

500

### Object and Material Loaders

501

502

Loaders for Three.js-specific object and material formats.

503

504

```javascript { .api }

505

/**

506

* Loads Three.js Object3D hierarchies from JSON format

507

*/

508

class ObjectLoader extends Loader<Group> {

509

/**

510

* Create object loader

511

* @param manager - Optional loading manager

512

*/

513

constructor(manager?: LoadingManager);

514

515

/**

516

* Load Object3D hierarchy from JSON

517

* @param url - JSON file URL

518

* @param onLoad - Success callback with loaded object

519

* @param onProgress - Progress callback

520

* @param onError - Error callback

521

* @returns Group object containing loaded hierarchy

522

*/

523

load(

524

url: string,

525

onLoad?: (object: Group) => void,

526

onProgress?: (event: ProgressEvent) => void,

527

onError?: (event: ErrorEvent) => void

528

): Group;

529

530

/**

531

* Parse JSON data into Object3D hierarchy

532

* @param json - JSON object data

533

* @param onLoad - Success callback

534

* @returns Parsed Object3D

535

*/

536

parse<T extends Object3D>(json: any, onLoad?: (object: T) => void): T;

537

538

/**

539

* Parse geometries from JSON data

540

* @param json - JSON geometry data

541

* @returns Map of geometry instances

542

*/

543

parseGeometries(json: any): { [key: string]: BufferGeometry };

544

545

/**

546

* Parse materials from JSON data

547

* @param json - JSON material data

548

* @param textures - Map of loaded textures

549

* @returns Map of material instances

550

*/

551

parseMaterials(json: any, textures: { [key: string]: Texture }): { [key: string]: Material };

552

553

/**

554

* Parse animations from JSON data

555

* @param json - JSON animation data

556

* @returns Array of animation clips

557

*/

558

parseAnimations(json: any): AnimationClip[];

559

560

/**

561

* Parse images from JSON data

562

* @param json - JSON image data

563

* @param onLoad - Callback when all images loaded

564

* @returns Map of loaded textures

565

*/

566

parseImages(json: any, onLoad: () => void): { [key: string]: Texture };

567

568

/**

569

* Parse textures from JSON data

570

* @param json - JSON texture data

571

* @param images - Map of loaded images

572

* @returns Map of texture instances

573

*/

574

parseTextures(json: any, images: { [key: string]: Texture }): { [key: string]: Texture };

575

576

/**

577

* Parse objects from JSON data

578

* @param json - JSON object data

579

* @param geometries - Map of geometries

580

* @param materials - Map of materials

581

* @param animations - Array of animations

582

* @returns Parsed Object3D

583

*/

584

parseObject<T extends Object3D>(

585

json: any,

586

geometries: { [key: string]: BufferGeometry },

587

materials: { [key: string]: Material },

588

animations: AnimationClip[]

589

): T;

590

}

591

592

/**

593

* Loads Three.js materials from JSON format

594

*/

595

class MaterialLoader extends Loader<Material> {

596

/**

597

* Create material loader

598

* @param manager - Optional loading manager

599

*/

600

constructor(manager?: LoadingManager);

601

602

/** Map of loaded textures for material creation */

603

textures: { [key: string]: Texture };

604

605

/**

606

* Load material from JSON

607

* @param url - JSON file URL

608

* @param onLoad - Success callback with loaded material

609

* @param onProgress - Progress callback

610

* @param onError - Error callback

611

* @returns Material object

612

*/

613

load(

614

url: string,

615

onLoad?: (material: Material) => void,

616

onProgress?: (event: ProgressEvent) => void,

617

onError?: (event: ErrorEvent) => void

618

): Material;

619

620

/**

621

* Parse JSON data into material

622

* @param json - JSON material data

623

* @returns Parsed material instance

624

*/

625

parse(json: any): Material;

626

627

/**

628

* Set textures map for material parsing

629

* @param textures - Map of texture instances

630

* @returns This loader for chaining

631

*/

632

setTextures(textures: { [key: string]: Texture }): this;

633

}

634

635

/**

636

* Loads BufferGeometry from JSON format

637

*/

638

class BufferGeometryLoader extends Loader<BufferGeometry> {

639

/**

640

* Create buffer geometry loader

641

* @param manager - Optional loading manager

642

*/

643

constructor(manager?: LoadingManager);

644

645

/**

646

* Load geometry from JSON

647

* @param url - JSON file URL

648

* @param onLoad - Success callback with loaded geometry

649

* @param onProgress - Progress callback

650

* @param onError - Error callback

651

* @returns BufferGeometry object

652

*/

653

load(

654

url: string,

655

onLoad?: (geometry: BufferGeometry) => void,

656

onProgress?: (event: ProgressEvent) => void,

657

onError?: (event: ErrorEvent) => void

658

): BufferGeometry;

659

660

/**

661

* Parse JSON data into BufferGeometry

662

* @param json - JSON geometry data

663

* @returns Parsed BufferGeometry instance

664

*/

665

parse(json: any): BufferGeometry;

666

}

667

```

668

669

### Animation Loader

670

671

Loader for animation data in Three.js JSON format.

672

673

```javascript { .api }

674

/**

675

* Loads animation clips from JSON format

676

*/

677

class AnimationLoader extends Loader<AnimationClip[]> {

678

/**

679

* Create animation loader

680

* @param manager - Optional loading manager

681

*/

682

constructor(manager?: LoadingManager);

683

684

/**

685

* Load animations from JSON

686

* @param url - JSON file URL containing animation data

687

* @param onLoad - Success callback with loaded animation clips

688

* @param onProgress - Progress callback

689

* @param onError - Error callback

690

* @returns Array of AnimationClip objects

691

*/

692

load(

693

url: string,

694

onLoad?: (animations: AnimationClip[]) => void,

695

onProgress?: (event: ProgressEvent) => void,

696

onError?: (event: ErrorEvent) => void

697

): AnimationClip[];

698

699

/**

700

* Parse JSON data into animation clips

701

* @param json - JSON animation data

702

* @returns Array of parsed AnimationClip instances

703

*/

704

parse(json: any): AnimationClip[];

705

}

706

```

707

708

### Audio Loader

709

710

Loader for audio files with support for various audio formats.

711

712

```javascript { .api }

713

/**

714

* Loads audio files as AudioBuffer objects for use with Web Audio API

715

*/

716

class AudioLoader extends Loader<AudioBuffer> {

717

/**

718

* Create audio loader

719

* @param manager - Optional loading manager

720

*/

721

constructor(manager?: LoadingManager);

722

723

/**

724

* Load audio file

725

* @param url - Audio file URL

726

* @param onLoad - Success callback with decoded AudioBuffer

727

* @param onProgress - Progress callback

728

* @param onError - Error callback

729

* @returns AudioBuffer object (decoded asynchronously)

730

*/

731

load(

732

url: string,

733

onLoad?: (audioBuffer: AudioBuffer) => void,

734

onProgress?: (event: ProgressEvent) => void,

735

onError?: (event: ErrorEvent) => void

736

): AudioBuffer;

737

}

738

```

739

740

### Cache System

741

742

Global caching system for loaded assets to prevent duplicate requests and improve performance.

743

744

```javascript { .api }

745

/**

746

* Global cache for loaded assets to prevent duplicate requests

747

*/

748

class Cache {

749

/** Whether caching is enabled */

750

static enabled: boolean;

751

752

/** Map of cached files */

753

static files: { [key: string]: any };

754

755

/**

756

* Add item to cache

757

* @param key - Cache key (usually URL)

758

* @param file - Data to cache

759

*/

760

static add(key: string, file: any): void;

761

762

/**

763

* Get item from cache

764

* @param key - Cache key to retrieve

765

* @returns Cached data or undefined

766

*/

767

static get(key: string): any;

768

769

/**

770

* Remove item from cache

771

* @param key - Cache key to remove

772

*/

773

static remove(key: string): void;

774

775

/**

776

* Clear all cached items

777

*/

778

static clear(): void;

779

}

780

```

781

782

### Loader Utils

783

784

Utility functions for working with loaded data and extracting information.

785

786

```javascript { .api }

787

/**

788

* Utility functions for asset loading operations

789

*/

790

class LoaderUtils {

791

/**

792

* Extract URL base path for resolving relative URLs

793

* @param url - Full URL to extract base from

794

* @returns Base path portion of URL

795

*/

796

static extractUrlBase(url: string): string;

797

798

/**

799

* Decode text from array buffer with encoding detection

800

* @param array - Array buffer containing text data

801

* @returns Decoded text string

802

*/

803

static decodeText(array: Uint8Array): string;

804

}

805

```

806

807

## Types

808

809

```javascript { .api }

810

// Loading-related type definitions

811

interface ProgressEvent {

812

lengthComputable: boolean;

813

loaded: number;

814

total: number;

815

target?: any;

816

}

817

818

interface ErrorEvent {

819

message: string;

820

target?: any;

821

}

822

823

// ImageBitmap creation options

824

interface ImageBitmapOptions {

825

imageOrientation?: 'none' | 'flipY';

826

premultiplyAlpha?: 'none' | 'premultiply' | 'default';

827

colorSpaceConversion?: 'none' | 'default';

828

resizeWidth?: number;

829

resizeHeight?: number;

830

resizeQuality?: 'pixelated' | 'low' | 'medium' | 'high';

831

}

832

```

833

834

## Usage Examples

835

836

**Complete Asset Loading Pipeline:**

837

838

```javascript

839

import * as THREE from 'three';

840

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

841

import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';

842

843

// Create loading manager with progress tracking

844

const loadingManager = new THREE.LoadingManager();

845

loadingManager.onStart = (url, itemsLoaded, itemsTotal) => {

846

console.log(`Started loading: ${url}`);

847

};

848

loadingManager.onProgress = (url, itemsLoaded, itemsTotal) => {

849

const progress = itemsLoaded / itemsTotal * 100;

850

console.log(`Loading progress: ${progress.toFixed(1)}%`);

851

updateProgressBar(progress);

852

};

853

loadingManager.onLoad = () => {

854

console.log('All assets loaded!');

855

hideLoadingScreen();

856

};

857

loadingManager.onError = (url) => {

858

console.error(`Failed to load: ${url}`);

859

};

860

861

// Set up loaders with manager

862

const textureLoader = new THREE.TextureLoader(loadingManager);

863

const gltfLoader = new GLTFLoader(loadingManager);

864

865

// Set up DRACO compression support

866

const dracoLoader = new DRACOLoader();

867

dracoLoader.setDecoderPath('/examples/js/libs/draco/');

868

gltfLoader.setDRACOLoader(dracoLoader);

869

870

// Load multiple assets

871

Promise.all([

872

textureLoader.loadAsync('textures/ground.jpg'),

873

textureLoader.loadAsync('textures/sky.jpg'),

874

gltfLoader.loadAsync('models/character.gltf')

875

]).then(([groundTexture, skyTexture, gltf]) => {

876

// All assets loaded, set up scene

877

groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;

878

groundTexture.repeat.set(10, 10);

879

880

const groundMaterial = new THREE.MeshLambertMaterial({ map: groundTexture });

881

const groundGeometry = new THREE.PlaneGeometry(50, 50);

882

const ground = new THREE.Mesh(groundGeometry, groundMaterial);

883

ground.rotation.x = -Math.PI / 2;

884

scene.add(ground);

885

886

scene.background = skyTexture;

887

scene.add(gltf.scene);

888

889

// Start animation if present

890

if (gltf.animations.length > 0) {

891

const mixer = new THREE.AnimationMixer(gltf.scene);

892

const action = mixer.clipAction(gltf.animations[0]);

893

action.play();

894

895

// Update mixer in render loop

896

const clock = new THREE.Clock();

897

function animate() {

898

const deltaTime = clock.getDelta();

899

mixer.update(deltaTime);

900

renderer.render(scene, camera);

901

requestAnimationFrame(animate);

902

}

903

animate();

904

}

905

}).catch((error) => {

906

console.error('Loading failed:', error);

907

});

908

```