Skip to content

Assets

Web Engine Dev provides a multi-layered asset system: a runtime loader for glTF models, a build-time pipeline for asset processing, and texture management utilities for GPU upload.

glTF Loading

The primary 3D asset format is glTF 2.0 (GL Transmission Format). The @web-engine-dev/gltf package loads .gltf and .glb files and converts them into engine-ready meshes, materials, and animations.

Basic Loading

typescript
import { GLTFLoader } from '@web-engine-dev/gltf';
import { createDevice } from '@web-engine-dev/renderer';

const { device } = await createDevice({
  canvas,
  preferredBackend: 'auto',
});

const loader = new GLTFLoader(device);
const result = await loader.load('/models/character.glb');

Load Result

The loader returns a structured result containing all parsed data:

typescript
// Meshes -- geometry data ready for GPU rendering
const mesh = result.meshes.get('CharacterMesh');

// Materials -- PBR materials with textures
const material = result.materials.get('Skin');

// Animations -- keyframe animation clips
const walkAnim = result.animations.get('Walk');

// Skeletons -- joint hierarchies for skeletal animation
const skeleton = result.skeletons.get('Armature');

// Scenes -- scene definitions with root nodes
const mainScene = result.scenes[0];

// Nodes -- all nodes with transforms and hierarchy
const nodes = result.nodes;

ECS Integration

Spawn loaded glTF scenes directly into the ECS world:

typescript
import { spawnGLTFScene } from '@web-engine-dev/gltf';

const spawnResult = spawnGLTFScene(world, result);

// Access spawned entities
for (const entity of spawnResult.entities) {
  // Each node becomes an entity with Transform3D,
  // MeshHandle, and material components
}

Vertex Layouts

Loaded meshes use standard engine vertex layouts:

LayoutSizeContents
Position12 bytesPosition only
PositionNormal24 bytesPosition + normals
PositionNormalUV32 bytesPosition + normals + UVs
PositionNormalTangentUV48 bytesFull PBR (tangents for normal mapping)

Additional vertex data (not in the main vertex buffer) is stored on the GLTFPrimitive:

  • Vertex colors (COLOR_0) -- Normalized to RGBA float
  • Joint indices and weights (JOINTS_0, WEIGHTS_0) -- For skeletal animation
  • Second UV set (TEXCOORD_1) -- For lightmaps or detail textures
  • Morph target deltas -- Position, normal, and tangent deltas per blend shape

Extension Support

The loader supports common glTF compression extensions:

ExtensionDescription
KHR_draco_mesh_compressionDraco mesh compression
EXT_meshopt_compressionMeshopt compression
KHR_texture_basisuKTX2/Basis Universal textures

Extensions are enabled by default. Disable specific extensions for strict core-only loading:

typescript
const loader = new GLTFLoader(device, {
  extensions: ['KHR_draco_mesh_compression'], // Only enable Draco
});

Cleanup

Dispose loaded resources when no longer needed:

typescript
loader.dispose(result); // Disposes all meshes, materials, and textures

Texture Loading

The renderer handles texture creation and GPU upload. Textures loaded from glTF use the industry-standard direct GPU upload path:

  • createImageBitmap() with premultiplyAlpha: 'none' and colorSpaceConversion: 'none' (glTF 2.0 spec requires ignoring ICC profiles)
  • Direct copyExternalImageToTexture() for zero-copy GPU upload
  • Automatic mipmap generation

Straight Alpha

The engine always preserves straight (non-premultiplied) alpha during texture loading. Never use Canvas 2D drawImage + getImageData to extract pixel data from images that need alpha preservation, as Canvas 2D unconditionally premultiplies alpha, destroying RGB values where alpha is zero.

Asset Pipeline

The build-time asset pipeline (@web-engine-dev/asset-pipeline) transforms raw assets into optimized, game-ready formats.

Pipeline Stages

Raw Asset → Import → Process → Output
  1. Import -- Parse raw files into an intermediate format (e.g., read PNG as pixel data)
  2. Process -- Transform, optimize, and compress (e.g., resize textures, generate mipmaps, compress audio)
  3. Output -- Write processed files to the distribution directory with metadata

Importers

Importers handle specific file types:

typescript
interface Importer {
  extensions: string[];
  import(path: string): Promise<AssetData>;
}

Built-in importers cover common asset types: textures (PNG, JPG, WebP), audio files, 3D models (glTF/GLB), and more.

Processors

Processors transform imported data:

typescript
interface Processor {
  type: string;
  process(asset: AssetData, options: ProcessorOptions): Promise<ProcessedAsset>;
}

Example processing operations:

  • Resize textures to maximum dimensions
  • Generate texture mipmaps
  • Compress textures to GPU-native formats (ASTC, ETC2, S3TC, BC)
  • Convert audio to compressed formats (OGG, WebM)
  • Optimize mesh data

Configuration

Configure the pipeline in your project:

typescript
// asset-pipeline.config.js
export default {
  inputDir: './assets',
  outputDir: './dist/assets',
  processors: {
    texture: { maxSize: 2048, compress: true },
    audio: { format: 'ogg', quality: 0.7 },
  },
};

Incremental Builds

The pipeline supports incremental builds through:

  • Hash-based change detection -- Only reprocess assets whose content has changed
  • Dependency tracking -- When a texture changes, materials referencing it are reprocessed
  • Cache invalidation -- Configuration changes trigger full rebuilds of affected assets

Texture Formats

The renderer supports multiple texture formats on WebGPU, constrained by adapter capabilities:

FormatWebGPUNotes
RGBA8YesStandard 8-bit per channel
RGBA16FYesHDR half-float
RGBA32FAdapter-dependentFull-float workflows depend on device support
Depth24Stencil8YesDepth + stencil
Depth32FYesHigh-precision depth
BC (S3TC)Adapter-dependentsupportsTextureCompressionBC
ETC2Adapter-dependentsupportsTextureCompressionETC2
ASTCAdapter-dependentsupportsTextureCompressionASTC

Next Steps

  • Rendering -- See how meshes and materials are rendered
  • Scenes -- Save loaded assets as part of scene data
  • ECS -- Understand the component system assets integrate into

Proprietary software. All rights reserved.