Level of detail - Streaming

Published on
Last changed on

This post is the segue to the , and tries to present how Ad lumens applies LOD in the context of streaming data over websockets.

Server- and client-side level of detail areas

The drawing below is a flattened 2D illustration of the 3D navigator "LOD bubbles":

  • In black, at the center, is the position of the observer
  • The darker blue disc is the area where passive LOD is maximal
  • The lighter blue disc is the area where passive LOD is minimal.

Each 2D grid element represents a cube. For more about cubes, please see this post. The "center cube" is the one containing the observer's current position - it does not matter where in the cube as long as it is inside.

  • Level of detail ranges

The X and Y distances can be chosen depending on hardware, both client- and server-side:

Distance (in cubes)Passive LODExplanation
From 0 to XMaximal: LOD_STARDetails about: systems, stars
From X to YMinimal: LOD_SYSTEMDetails about systems only

The above table is applicable for passive LOD, so for visual immersion. This means that these "LOD bubbles" follow the observer wherever it goes:

  • Nearby cubes visually indicate the color of stars
  • Faraway cubes only visually indicate the presence of stars
  • At all times, many many cube surround the observer; only a relatively small fraction contains actual star visual information, as summed up in the table below.
Passive LOD rangeCubes with star dataCubes with system data onlyTotal number of cubesGeneration time
47250257~2ms
83320762109~8ms
1212370307153~25ms
162571682017077~55ms

In summary: the more data, the more CPU time, the more bandwidth to push over websockets, the more CPU/GPU time on the client!

Generation times measured on an Intel(R) Xeon(R) D-2141I CPU @ 2.20GHz (hardly a super high-end CPU) and with rust's rayon crate.

Movement and level of detail

When the observer moves in the virtual world, either via smooth camera displacement (like in the upcoming 3d explorer) or abrupt loading such as on initial load or sudden unit focus, the point of view moves as well.

Again, this means the LOD bubbles move alongside the observer. But there is a problem: should we reload eveything around the new POV each time it changes? Even though it is perfectly doable and should be reasonably fast, maybe a cleverer strategy can be played to avoid:

  • Unneeded server-side computations
  • Useless bandwidth usage (not from a price perspective, but simply: we want to send only what's necessary to the client)
  • Potentially some client-side jitters and flashing in and out of stars or other objects (let's call that the FUC. Harr harr harr).

Let's imagine a scenario where an observer starts at position A, then moves to position B, then to position C. The LOD bubbles around it, respectively blue, teal and green, move as well to follow it.

  • Level of detail and movement

The first thing we see on this image is overlapping areas, especially between A and B, and B and C. And where there is overlap, there is repetition we should try and get rid of. It represents redundant computation, redundant data sent over the wire, and redundant data handled by the client.

These are the server- and client-side steps to achieve this:

  • When a position change implies movement into a different cube, the server computes the coordinates of the cubes inside the LOD bubbles around that new cube. Note that an initial load is considered as an arrival in a new cube - the cube position changes from nothing to something.
  • The server compares the previous list of cube coordinates and the new one, and determines the delta between the two, on a LOD basis: one delta for LOD_SYSTEM and another for LOD_STAR.
  • The server then knows what the client should get rid of, what it should change and what it should add.
  • That "reversed"delta is sent to the client in a appropriate way:
    • list of cubes to completely remove
    • list of cubes downgraded from LOD_STAR to LOD_SYSTEM
    • list of cubes upgraded from LOD_SYSTEM to LOD_STAR, along with the relevant data
    • list of new LOD_STAR cubes
    • list of new LOD_SYSTEM cubes
  • The client receives that data and updates meshes, particles systems, etc, accordingly.

If these circles look like Venn diagrams, it's because they are just that. Computing the difference, union, and intersection values over times involve set operations, facilitated by rust's FxHashSet.

Intra-cube movement

The previous sections are about movement between cubes. But what happens when the observer gets close enough to a star?

Star proximity threshold

When the observer is known, server-side, to be close enough to a star - say at a maximum of 1 light year, it sends some extra information: the information about planets, satellites, etc. The raw data of it is similar to what can be found in the data explorer, of course formatted in a way that's appropriate for 3D rendering.

This results in orbits, planets and all to be displayed, which correspond to the LOD_SATELLITE level of detail.

when the same observer moves far away away from the star, the server notifies the client to remove all data and assets related to planets and other smaller entities.

Planet proximity threshold

Is to a planet what the star proximity threshold is to a star. The exact same logic applies and in this case, the LOD_SUBSATELLITE level of detail is applied.

Please signin to add your comment.