Why doesn't babylonjs use (Rendering Relative to Eye) to solve the loss of precision?

Why doesn’t babylonjs use (Rendering Relative to Eye) to solve the loss of precision?

Here are good examples

Hey! can you elaborate a bit more?

I believe he is referring to a trick used to render very big scenes, called floating-origin.

The idea of floating-origin is to keep the camera fixed at world’s origin (0, 0, 0) and instead of moving the camera, move all the objects around the camera.

That trick makes floating-point imprecision to happen far from the camera, that is, far from the observer, mitigating the problem.

That is not hard to implement, although it causes some extra efforts regarding physics simulation etc.

I have implemented floating-origin in Javascript, on one of my old homebrew webgl engines. By coincidence I am porting the main parts of that to Babylon.js, hopefully will have something to show in two weeks or so.

5 Likes

Great that your description here is my problem. Looking forward to babylonjs with related support.
I think it may involve modification of “light”, “shadow” and other related programs

Here are good examples

I’m eager to see that. Pls, Let us know when ready :yum:

The required change to make floating-origin global into the engine is very simple.

When updating any object’s matrix – at that final update just before rendering – it is just a matter of subtracting the current camera position from the object’s position, and then setting this offset to the view matrix. The camera position must not be directly in the view matrix anymore, it’s just used to calculate that offset, and the offset itself goes into the object’s view matrix. The effect is that the camera is always at (0, 0, 0) and only the objects float around the origin.

That simple trick removes huge numbers from the GPU, when objects are close to the camera.

As an example:

Camera at (10000000, 0, 0)
Object at (10000500, 0, 0)

object.position - camera.position (that is, the view offset) = (500, 0, 0)

That is, even at huge coordinates, there is no floating-point imprecision at all! Now, if the object is too far from the camera, then there will be imprecision, but as it is very far, we won’t see!

In C++ we would use doubles for all coordinates, but in Javascript that is not even needed, as Javascript already uses doubles by default.

There are then two alternatives here:

One is to simply create an Entity class which does that calculation every time it’s called. That requires a separate loop in the game to iterate through all objects updating that offset. This works, but is not the best because we add an extra loop to update the offsets.

The other would be to implement that directly into the engine, in the loop which updates all object’s matrices. This is the best, as we remove the need of a second loop.

As an additional note, this all also works best with logarithmic zbuffer, which as I see is already implemented.

Maybe someone from the dev team could spend “a few hours” and implement a switch for that?

Edit: saying is always easier than doing – disclaimer here is that atm I don’t know enough about the internal Babylon.js details to state that this would not have some weird collateral effects, so, I was just saying anyway. When I did that, I did from the start, and although it did work nicely, the engine was much smaller than BJS.

1 Like

The first one could be easy to do with a few lines like:

scene.onBeforeActiveMeshesEvaluationObservable.add(() => {
     scene.meshes.forEach(m =>m.position....);
});
2 Likes

Are there any new developments that I can see from babylonjs?

There is a workaround:

1 Like