Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for feedback: double-precision accurate translation #1665

Closed
wants to merge 4 commits into from

Conversation

pixelflinger
Copy link
Collaborator

Filament does all its calculations for rendering in view-space,
which means it's able to handle very large scenes.
However, the position of objects (and camera) in the scene is still
limited to float precision.

A related issue is that our TransformManager is only able to store
float matrices.

This PR is an attempt to address these issues efficiently.
The first thing to notice is that we only need a high precision on the translation component of matrices, this is because most of our objects are simply rotated and translated, and rarely scaled by very-large amounts.

Here me augment the TransformManager so it can maintain the 4th column as
double precision; we accomplish this by storing an extra float3 per matrix.
It's calculated as doubleTranslation - float3{doubleTranslation}.

We also add methods to set and get a transform as mat4, internally only
the 4th column is kept as double precision.

Finally when we calculate the worldTransform, we take this extra data into
account, but only for calculating the new 4th column, so the extra work
is small. This makes assumption that the 4th row is [0 0 0 x], but even
if it's not, the result wouldn't be worse than it is now.

Filament could them make use of this to maintain the precision of
the position when converting everything to viewspace.

Copy link
Contributor

@prideout prideout left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really cool idea. It does not introduce any complexity and the changes are limited to TransformManager. ECS for the win!

I could also imagine allowing users to use a hypothetical TransformManager<double> which simply stores the entire 4x4 as double, potentially giving us better precision parity with JavaScript engines like ThreeJS.


const math::mat4f& getTransform(Instance ci) const noexcept {
return mManager[ci].local;
}

math::mat4 getAccurateTransform(Instance ci) const noexcept {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be worth documenting these two new functions.

filament/src/components/TransformManager.h Outdated Show resolved Hide resolved
Augment the TransformManager so it can maintain the 4th column as
double precision; we accomplish this by storing an extra float3 per matrix.
It's calculated as `doubleTranslation - float3{doubleTranslation}`.

We also add methods to set and get a transform as mat4, internally only
the 4th column is kept as double precision.

Finally when we calculate the worldTransform, we take this extra data into
account, but only for calculating the new 4th column, so the extra work
is small.
@romainguy
Copy link
Collaborator

Closing PR, keeping the branch open

@romainguy romainguy closed this Feb 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants