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

Simplify transform hierarchy walk & computation #7025

Open
Wumpf opened this issue Jul 31, 2024 · 1 comment
Open

Simplify transform hierarchy walk & computation #7025

Wumpf opened this issue Jul 31, 2024 · 1 comment
Assignees
Labels
💬 discussion other Generated by the "Other" issue template project-many-entities-perf

Comments

@Wumpf
Copy link
Member

Wumpf commented Jul 31, 2024

Today, each space view has its own transform context which walks up and down the tree going from $origin in order to figure out transform from each entity/instance to the "reference space", i.e. the space whose origin is at the $origin entity.

So today the graphics pipeline conceptually does the following:

[instance -> entity -> origin-reference] -> camera -> projection

Where the TransformContext is providing [instance -> entity -> origin-reference]

Disregarding (do we have to?) any 2D->3D/3D->2D consideration we could do something much simpler:
First, resolve the transform tree starting at /, let's call this the world space. This leads to the following transform relationship:

[instance -> entity -> world] -> origin-reference -> camera -> projection

Note that now there is a global transform context providing [instance -> entity -> world]. From there on we can either infect re_renderer with this as well - or much simpler - go with this world space and bake [origin-reference ->camera] into the camera matrix we're setting.

-> We end up with a single transform tree pass and don't have to care about walking the tree upwards!

The main issue with doing this today is that 2D in 3D handling makes this complicated in some regards.
Also, there might be several independent 3D spaces that have no connection to the root!

Related, maybe even blocked by:

@Wumpf Wumpf added 💬 discussion other Generated by the "Other" issue template labels Jul 31, 2024
@Wumpf Wumpf changed the title Simplify transform hierachy walk & computation Simplify transform hierarchy walk & computation Jul 31, 2024
Wumpf added a commit that referenced this issue Sep 24, 2024
### What

Not super significant unfortunately, in one badly affected scene I went
from ~130ms to ~110ms. It's probably better in those that aren't using
any transforms at all.
We need to do some more general overhaul there and imho at that point we
might as well start thinking more seriously about range queries for
transforms. See among others:
* #7025
* #723

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using examples from latest `main` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/7456?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/7456?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG
* [x] If applicable, add a new check to the [release
checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)!
* [x] If have noted any breaking changes to the log API in
`CHANGELOG.md` and the migration guide
* [x] run checklists & samples to check if transforms still work fine

- [PR Build Summary](https://build.rerun.io/pr/7456)
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)

To run all checks from `main`, comment on the PR with `@rerun-bot
full-check`.
@Wumpf Wumpf self-assigned this Dec 6, 2024
@Wumpf
Copy link
Member Author

Wumpf commented Dec 6, 2024

Copying some notes we made on a notion page about on how to address this overall:

## TransformTree

- Store subscriber: Local transforms: Map<EntityPath, BTreeMap<TimeInt, Mat4x4>>
    - GC via minimum timestamp - *a lot* easier than dealing with chunk removals

→ Every frame global transforms are needed

- propagate once
- in every view (view context system): make that tree local to its origin by shiftting all matrices to have the origin as its origin
- every visualizer: look-up its view private thing

## Thoughts on transform tree ranges

- `/a`: `Transform` at `frame=#1`
- `/a/b`: `Transform` at `frame=#1`
- `/a/b/c`: `Transform` at `frame=#3`

- `/a`: [(#1, LocalTransform)]
- `/a/b`: [(#1, LocalTransform)]
- `/a/b/c`: [(#3, LocalTransform)]

Let’s go through a LatestAt(#5):

- You get 3 transforms, and you just multiply them.

Let’s go through a Range [#0, #5]:

- for every possible time, propagate a tree:
    - Tree at latest-at #1 […]
    - Tree at latest-at #3 […]  (note that this tree is an incremental change of the tree at #1)
- What to draw:
    - `/a` shows up once
    - `/a/b` shows up once
    - `/a/b/c` shows up **twice →** AS IF there was pose instancing (generously assuming we implemented that everywhere)

Second scenario:

- `/a`: `Transform` at `frame=#1`
- `/a/b`: `Transform` at `frame=#1`
- `/a/b/c`: `Transform` at `frame=#3`
- `/a/b/c`: `Position=2` (primary) at `frame=#2`

Let’s go through a Range [#0, #5]:

- for every possible time, propagate a tree:
    - Tree at latest-at #1 […]
    - Tree at latest-at #3 […] (note that this tree is an incremental change of the tree at #1)
- What to draw:
    - `/a` shows up once
    - `/a/b` shows up once
    - `/a/b/c` shows up **thrice**
        - transform at #1 with original position
        - transform at #2 with position=2
        - transform at #3 with position=2
    - conceptually: we have draw data for #1 and #2
        - Split those along transform time ranges → two slices, each 1 long
        - each of those slices is then instanced with all transforms that are valid in this range

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💬 discussion other Generated by the "Other" issue template project-many-entities-perf
Projects
None yet
Development

No branches or pull requests

1 participant