Reference

The VistaWASM API

One async loader, one engine object, and plain functions for export and import. Everything is typed: the TypeScript declarations ship with the package and document every option's default and range.

Everything on this page is a named export of @vista-wasm/vista-wasm, or a method of the VistaEngine that createVistaEngine() returns. Coordinates are in metres, with +Y up and the terrain centred on the origin.

Loading

import { createVistaEngine, detectVistaWasmSupport } from "@vista-wasm/vista-wasm";

if (!detectVistaWasmSupport().webGpu) {
  showFallback();
} else {
  const engine = await createVistaEngine(canvas, { render: { width: 1280, height: 720 } });
}
createVistaEngine(canvas, options?)
Create an engine for a canvas: loads the WASM once, requests a WebGPU device and configures the canvas. Resolves to a VistaEngine.
initialiseVistaWasm(options?)
Load the WASM module ahead of time, or from your own wasmUrl, moduleUrl or compiled wasmModule. Optional: createVistaEngine() calls it for you.
detectVistaWasmSupport()
Which of WebGPU, WebAssembly and ES modules this browser has, without throwing.

Terrain

Each call replaces the terrain and resolves to a TerrainHandle whose metadata gives the size, spacing and height range.

engine.generateFractal(options)
Generate a seeded world: a landform preset, noise, shaping, and GPU erosion. Reports each phase through "progress" events.
engine.loadDemFromUrl(url, options?)
Load real elevation from a GeoTIFF or raw heightmap at a URL.
engine.loadDemFromArrayBuffer(buffer, options?)
Load a GeoTIFF or raw heightmap you already hold.
engine.loadRawHeightmap(buffer, options)
Load raw heights from an ArrayBuffer, with their size, sample format and spacing.
engine.loadHeightmapImage(source, options)
Load a heightmap image: a PNG at 8 or 16 bits a channel, or any image the browser decodes.
loadTerrainFromImages(engine, images, options)
Load a heightmap image with painted biome, water and vegetation maps in one call.
loadBundle(engine, source, options?)
Load a bundle from exportBundle(): the heights, options and painted maps, exactly as they were.
fetchDemBytes(url, options?)
Fetch elevation bytes with your own headers, abort signal or maxBytes.

Rendering

engine.start()
Run the built-in render loop, paced to the display and the GPU.
engine.stop()
Stop the built-in loop.
engine.renderOnce()
Draw one frame from your own loop and return its RenderStats.
engine.resize(width, height, devicePixelRatio?)
Match the canvas's new size.
engine.setRenderQuality(options)
A quality preset, render and cloud distances, terrain detail, a frame-rate cap and dynamic resolution.
engine.setDebugView(view)
Show height, slope, normals, level of detail, flow, materials or biomes instead of the shaded view.
engine.dispose()
Release every GPU resource. Final: create a new engine to draw again.

Camera

const controls = attachFlyCameraControls(engine, canvas, {
  initialPosition: [0, 420, 1400],
  initialYawDegrees: 180,
  initialPitchDegrees: -14,
  onCameraChange: (camera) => console.log(camera.position)
});

// Later: controls.dispose();
engine.setCamera(camera)
Place the camera: a position, a target and a vertical field of view in degrees.
attachFlyCameraControls(engine, canvas, options?)
Mouse-look and WASD flight, with Space and Shift to rise and fall. Returns controls to move, aim and dispose of.
computeForwardVector(yaw, pitch)
The unit forward vector for a yaw and pitch in radians.
computeRightVector(yaw)
The unit rightward vector for a yaw in radians.
computeYawPitchTowards(from, to)
The yaw and pitch that look from one point towards another.

Sun, sky and weather

engine.setWeather({ enabled: true, state: "storm" });
engine.on("weatherChanged", (kind) => console.log("Now:", kind));
engine.setSun(sun)
The sun's azimuth, elevation and intensity.
engine.setAtmosphere(atmosphere)
Sky scattering, haze distance, exposure and sky tint.
engine.setClouds(clouds)
Volumetric clouds: coverage, height, speed, density, towering and sheet clouds, the mid-level layer, cirrus and cloud shadows.
engine.setMist(mist)
Drifting mist: density, height, wind and colour.
engine.setWeather(weather)
Weather presets from clear to blizzard, custom presets, automatic cycling and regional weather cells.
engine.getWeather()
The current blended weather, or undefined when the weather is off.
engine.getWeatherPresets()
Every resolved preset, built in and custom, by name.
engine.weatherAt(x, z)
The weather at a world position, for gameplay and audio.
engine.advanceWeather(seconds)
Run the weather forward by up to a day at once.
engine.setTimeOfDay(options)
A clock that moves the sun, from the hour, day length, latitude and day of the year.
engine.getTimeOfDay()
The time of day and where it puts the sun.
engine.setShadows(shadows)
Terrain, tree and cloud shadows: strength, softness, reach and resolution.

Land and life

engine.setBiomes(biomes)
The climate behind the nineteen biomes: temperature, moisture, volcanism, beach height and snow line.
engine.biomeAt(x, z)
The biome at a world position.
engine.temperatureAt(x, z)
The mean annual temperature in °C at a world position.
engine.setFlora(flora)
Tree density, tree line, species mix per biome, quality and wind.
engine.setGrass(grass)
Grass density, style and view distance, and the forest floor.
engine.setSurface(surface)
Procedural textures, detail normals, material tints, rockiness and boulders.
engine.setTreeModel(species, model)
Replace one species' model with your own mesh.
engine.resetTreeModel(species)
Restore one species' procedural model.
engine.setTreeInstances(trees)
Place your own trees, or pass undefined for procedural placement.
engine.replaceTexture(target, layer, rgba)
Replace one 512 × 512 texture layer.
engine.resetTextures()
Restore every procedural texture.
imageToRgba(source, size?)
Draw an image into a texture layer for replaceTexture().

Water

engine.setWater(water)
Sea level, waves, currents, colour, clarity, foam, reflections, and rivers, lakes and waterfalls.
engine.getWaterfalls()
Every waterfall on the terrain, with its height, width and flow.
engine.getInflows()
The rivers flowing in from beyond the map.
engine.getWaterSounds(x, y, z)
The loudest river, waterfall, lake shore and surf near a point, for your own audio.

Painted maps

engine.setWaterMask(mask)
Paint rivers and lakes, carved and drawn like the engine's own, or clear them with null.
engine.setBiomeMap(map)
Paint biomes onto the terrain, or clear them with null.
engine.setVegetationMasks(masks)
Scale where trees and grass grow.
engine.getPaintedMaps()
The painted maps in effect.
biomeMapFromImage(image, options?)
Read a biome map from an image, by legend colour.
waterMaskFromImage(image, options?)
Read a water mask from an image.
densityMaskFromImage(image, options?)
Read a tree or grass density mask from an image.

Export

const heights = readHeightmapFloats(engine.exportHeightmap());
const { width, height, metresPerSample } = terrain.metadata;

await downloadBundle(engine, "my-world.zip");
engine.exportHeightmap()
The heights as little-endian float32 bytes, row by row.
readHeightmapFloats(bytes)
Read those bytes into a Float32Array.
engine.exportMap(kind, options?)
One of fifteen maps: height, biome, water, flow, materials, slope, normals, temperature, tree density and more.
engine.exportTrees(options?)
Every tree on the map, or in a region: species, position, size and rotation.
engine.exportSnapshot(options?)
A screenshot of the view as an image Blob.
engine.getOptionsSnapshot()
The options in effect, as plain JSON, to rebuild the same scene.
exportBundle(engine, options?)
Every map, the trees and the options in one zip that loadBundle() reads back.
downloadBundle(engine, filename, options?)
Export a bundle and download it.
encodePng(map, options?) / encodeRaw(map, options?)
Encode an exported map as PNG files or raw samples.
treesToCsv(trees) / treesToJson(trees)
Trees as CSV or JSON.
exportTerrainObj(metadata, bytes, options?)
A Wavefront OBJ mesh of the terrain.
exportHeightmapImage(metadata, bytes, options?)
A shaded or grayscale heightmap image.
renderHeightmapToCanvas(canvas, metadata, bytes)
Draw a top-down map onto a canvas, as the demo's minimap does.
downloadRawHeightmap / downloadBlob / downloadText
Save heights, blobs or text as downloads.
decodePng(bytes)
Decode any PNG in full, with bounded memory.
imageSize(bytes)
A PNG, JPEG or WebP's size from its header, before decoding it.

Events

engine.on(name, listener) subscribes and returns a function that unsubscribes.

EventWhen
"ready"Once, when the engine has been created.
"progress"As terrain generates or a bundle loads: { phase, progress }, from 0 to 1 within each phase.
"terrainLoaded"After every new terrain, with its TerrainHandle.
"warning"For each warning a call raised, such as erosion falling back to the CPU, or an unknown option key that was ignored.
"stats"After every drawn frame, with its RenderStats: triangles, trees, grass and GPU time per pass.
"weatherChanged"When the dominant weather changes.
"deviceLost"When the browser takes the GPU device away. Dispose of the engine and create a new one.
"fatalError"Once, when the engine stops for good after an internal error, from whichever call met it, or when the built-in loop stops on an error.
"gpuError"For each GPU validation or out-of-memory error the engine did not catch itself, or that a terrain upload raised. The engine keeps running.

Errors

Engine failures reject with a VistaWasmError, whose code never changes between versions. Arguments of the wrong type throw a TypeError first, and values out of range throw OPTIONS_INVALID with the valid range in the message.

try {
  await engine.generateFractal(options);
} catch (error) {
  if (error instanceof VistaWasmError && error.code === "OPTIONS_INVALID") {
    showMessage(error.message);
  }
}
CodeMeaning
WEBGPU_UNAVAILABLEThe browser has no WebGPU.
WEBGPU_DEVICE_REQUEST_FAILEDWebGPU exists, but the browser refused a device.
WEBGPU_DEVICE_LOSTThe device was lost after start-up.
WASM_LOAD_FAILEDThe WASM or its glue could not load. Check that .wasm is served as application/wasm.
CANVAS_INVALIDThe canvas is missing or unusable.
OPTIONS_INVALIDAn option is out of range; the message says which and what is allowed.
TERRAIN_GENERATION_FAILEDTerrain generation failed.
DEM_FETCH_FAILEDElevation data could not be fetched.
DEM_FORMAT_UNSUPPORTED, DEM_METADATA_MISSING, INVALID_DEMThe elevation file is not one VistaWASM reads, or lacks what it needs.
GPU_LIMIT_EXCEEDEDThe request needs more than this GPU allows.
GPU_ERRORThe GPU reported a validation or out-of-memory error while the engine was created or eroded a terrain.
ENGINE_DISPOSEDThe engine was used after dispose(), or after an internal error stopped it.
INTERNAL_ERRORSomething unexpected; please report it.

Option groups

createVistaEngine() takes every group at once, and each engine setter replaces one group. Unset fields keep their defaults.

GroupSetterControls
renderresize()Canvas size and device pixel ratio
camerasetCamera()Position, target, field of view, near and far
sunsetSun()Direction and intensity
atmospheresetAtmosphere()Sky scattering, haze and exposure
watersetWater()Sea, waves, currents, rivers, lakes and waterfalls
florasetFlora()Trees, species and wind
grasssetGrass()Grass cover
cloudssetClouds()Cloud layers
mistsetMist()Drifting mist
qualitysetRenderQuality()Distances, detail and frame rate
biomessetBiomes()Climate and biome rules
weathersetWeather()Presets and cycling
shadowssetShadows()Shadow casters and reach
surfacesetSurface()Textures, rock and boulders

The options reference lists every field, its default and its valid range. The documentation index has a guide for each feature.