I’ve been wanting scenes with more complexity for a while but there were a few stumbling blocks to overcome first.

Prefabs

A prefab packages up a set of asset components, such as mesh + material + script, so instead of entities repeating the same mesh and material block, it can reference a prefab and only override what it needs to.

Asset Packages

Until now the scene description described everything directly, the geometry paths, material descriptions, scripts, and component data all dumped inside the JSON file.

This worked well for my small demo scenes but as scenes grow in complexity it quickly becomes untenable.

Now the scene description supports the loading of asset packages. An asset package is a JSON manifest that groups related assets together so instead of referencing a material or model inline every time, the scene can reference an asset by name.

Typically an asset package would contain a number of assets. Using todays example scene, there is a single asset package that contains 240 meshes, 7 materials and 240 prefabs that combines the correct mesh and material together.

This not only simplifies the scene description, but also makes assets easily sharable between scenes.

Imports And Namespaces

The mechanism for this is fairly simple, an asset package is added to the imports map in the scene description, and its key is used as a namespace to reference assets within it.

{
    "name": "My Scene",
    "imports": {
        "local": "/path/to/package.json",
        "remote": "http://www.myserver.com/package.json"
    },
    "entities": [
        {
            "name": "A Cube",
            "prefab": "local:Cube",
            "components": {
                "transform": {
                    "position": [10, 10, 10]
                }
            }
        },
        {
            "name": "Remote Object",
            "prefab": "remote:SomeAsset",
            "components": {
                "transform": {
                    "rotation": [0, 45, 0]
                }
            }
        }
    ]
}

This keeps references explicit and avoids collisions when multiple packages define assets with similar names. The scene can reference any asset within an asset package. This means you don’t just have access to prefabs, but also the components that they reference too. You could reference a mesh from one asset package and assign a material from another.

Direct from Me to You

Now that resources are packaged nicely and I can load them from anywhere, it was time to put work into how StaticRectangle is deployed. I was using render.com which has excellent GitHub integration, but is ultimately overkill for what I need right now. Using the free instance also meant time waiting to check out, build, and start the service on demand.

Now I am using vite to bundle StaticRectangle into a static build that I can serve directly from my web host.

Synty Sci-Fi City

  • ~ opens the terminal
  • Mouse look with left/right mouse buttons
  • w, a, s, d to move

This is the demo scene provided by Synty as part of the POLYGON Sci-Fi City asset pack I bought a few years ago.

Helpfully for me, the demo was a Maya scene so with a bit of cleanup and a lot of scripting I was able to group meshes into instances of the same model, export the geometry, write out an asset package and a scene description that StaticRectangle could then load.

Before I Go

While orders of magnitude more interesting than the usual cubes, the scene is pretty flat and lifeless. It’s being lit entirely by IBL, no direct lights which would make it more interesting and no movement yet that would make it more lively.

My current plan is to continue to iterate on this scene for a bit, it’s this iteration that helps move the engine, core assets, renderer and scene description forward.

I still need to do some optimisations, but I’m not quite ready for that yet. I need to reintroduce render stats as an overlay which means researching text rendering, which like everything else, is not as simple as you’d think it would be.