Technology · @orbitalfoundation/orbital-volume
Volume
A declarative shim over three.js, and the worked example of a bus listener. Agents declare state. Volume observes entities that carry a volume component and draws them.
The point of the arrangement is separation of concerns. A simulation agent never imports a renderer. It publishes an entity with a volume component describing what its three-dimensional representation should be, and the renderer, if one is present, reacts. The same manifest runs on a server with no renderer at all.
const camera001 = {
volume: {
geometry: 'camera',
cameraMin: 1,
cameraMax: 100,
pose: {
position: [0, 1.5, 4],
love: [0, 1.5, 0],
}
}
}
What it renders
- Scenes, cameras and lights, with sky, fog, hemisphere light, a shadow-casting sun and exposure as options on the scene.
- Loaded models, and rigged, animated human avatars with facial visemes from Ready Player Me, VRM and Reallusion pipelines.
- Real-world terrain streamed as a heightfield from public tile services, elevation from AWS Terrarium tiles with a satellite drape, fetched by latitude and longitude bounds. After building, the handler publishes a ground-height sampler back onto the component so other systems can plant things on the surface.
- Whole fields of stalk-form vegetation, bamboo, reeds, saplings, rendered as two instanced draw calls with GPU wind and shadow casting. Thousands of animated plants cost roughly the same as two meshes.
- Polylines in world space, shadow-casting lights, and static entities that are built once and skipped on later ticks.
Demos
Both demos are build-free ES modules served from the repository.
- Scene demo: scene, camera, lights and models declared as entities.
- Terrain demo: a satellite-draped Grand Canyon heightfield planted with a few thousand growing, swaying bamboo culms.
Open questions
A declarative renderer on a message bus leaves some things unresolved.
- Identity. Objects want stable identifiers, global and collision-free across a network. Whether the bus should inject them is open.
- Client and server. The renderer is a client concern, but parts of the service are needed on the server, and each file currently has to detect where it is running.
- Queries and spatial indexing. Observing all traffic lets Volume build a database of scene objects for later queries, but a separate spatial index service might be the better shape.
- Binding and authority. Volume writes position and orientation back into passed objects, as if they were the canonical instance of state. A message-passing scheme has no built-in notion of an authoritative instance, so which datagram wins is a design decision still to make.
- Performance. Whether volume objects should receive direct messages, and how that squares with thread isolation.
Volume grew out of three earlier efforts, blox, blox2 and blox3. Version 2.2.0 is on npm, MIT licensed. Source: orbitalfoundation/orbital-volume.