Nothing Special   »   [go: up one dir, main page]

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

Proper handling of offset and scale in metadata picking #12237

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

javagl
Copy link
Contributor
@javagl javagl commented Oct 6, 2024

Description

Addresses #12236

The metadata picking did not take into account the offset/scale that may be defined in a class property or property texture property.

The solution is to ensure that the offset/scale (and normalization) are properly handled when converting the metadata values into values that are supposed to be written into the metadata picking frame buffer. For example, a normalized UINT8 property with offset=1.0 and scale=2.0 will be converted into 1.0 + 2.0 * ~0.5 = 2.0 by the standard metadata handling, But before writing this into the frame buffer, it has to be converted back into the [0, 1] range (reflecting the [0,255] range that can be stored in the frame buffer).

After reading the value from the frame buffer, it has to be converted back into the proper metadata value. These operations strongly resemble the MetadataComponentType.apply/unapplyValueTransform, but have additional caveats

  • Every value must be mapped to the [0, 1] range
  • This mapping is not done by "implementing it", but by generating shader code that implements it
  • An offset/scale that is defined by a 'class property' may actually be overridden by the 'property texture property'

The last point may make it necessary to store the "effective" offset/scale inside the PickedMetadataInfo. Right now, it only stores the MetadataClassProperty. But when the offset/scale have been defined in the PropertyTextureProperty or a PropertyAttributeProperty (!), then these offset/scale values have to be used for the conversions.

Issue number and link

#12236

Testing plan

Details TBD - started creating specs

Author checklist

  • I have submitted a Contributor License Agreement
  • I have added my name to CONTRIBUTORS.md
  • I have updated CHANGES.md with a short summary of my change
  • I have added or updated unit tests to ensure consistent code coverage
  • I have updated the inline documentation, and included code examples where relevant
  • I have performed a self-review of my code

Copy link
github-actions bot commented Oct 6, 2024

Thank you for the pull request, @javagl!

✅ We can confirm we have a CLA on file for you.

@javagl
Copy link
Contributor Author
javagl commented Oct 8, 2024

It's never as easy as it looks...

The last point may make it necessary to store the "effective" offset/scale inside the PickedMetadataInfo.

This is not possible. At the point where the actual value is obtained (namely, inside the shader), it is not longer possible to know where any offset/scale came from to begin with. So it's possible to "undo" the value transform in the shader (with some quirks). And it is possible to write that value in [0,1] into the color (ending up as [0, 255] in the frame buffer). But it is not possible to convert this back to the right value after reading it from the frame buffer, because at that point, we don't know whether the "value transform" that was applied came from a 'class property' or from the 'property texture/attribute property'.

There might be solutions to that, but all approaches that I can think of right now are ... complicated, to say the least. We certainly don't want to replicate the whole logic of value transforms (and things like KHR_texture_transform) inside the metadata picking shader function ... 🤔

@javagl
Copy link
Contributor Author
javagl commented Oct 9, 2024

The solution to the previous point turned out to be not toooo complicated.

When the picking starts, it will obtain the StructuralMetadata from the object, and then either obtain the PropertyTextureProperty or the PropertyAttributeProperty that corresponds to the picked metadata. (This may require some more thought - e.g. could there be an attribute and a texture that describe the same property...? Just thinking about corner cases and limitations here...).

This object always offers the offset/scale, in its final form - i.e. even when no offset/scale have been defined, this will be filled with default values, but also handle possible overrides from the class property. This object is then put into the PickedMetadataInfo, and used

  1. for creating the shader code that maps the metadata values to [0, 1] for the picking
  2. for converting the value in [0,255] from the frame buffer back into its original range

I started adding the corresponding tests. In that process I stumbled over an issue where the shader compilation bails out for normalized UINT8 array properties in property textures with offset/scale being defined in the class property, and it looks like this is independent of the picking (and therefore may have to be moved into a dedicated issue), but I have to verify that.

I'd also like to do more tests with property attributes (because these are currently not covered at all). Since the picking only relies on the metadata, and this does not even "know where it comes from" (attribute or texture), this might just work transparently. But now there is some code that explicitly has to handle both textures and attributes, so that should be covered by specs as well.

@javagl javagl mentioned this pull request Oct 10, 2024
6 tasks
@javagl
Copy link
Contributor Author
javagl commented Oct 11, 2024

So, I did try out some of this with property attributes. Or rather tried to try it. There are more issues with that, and see the handling of property attributes for metadata picking as a part of #12225 , likely to be spun out into a dedicated issue. (Handling of arbitrary types being moved through the frame buffer does raise quite a few questions).

So I'll consider this as ready for review, given that it contains several spec test cases, and I tried it out with the data from #12232 (where this originally came up), and there, the current state seems to work as expected.

I did have to re-run some CI steps a few times. We do have some flaky tests there...

@javagl javagl marked this pull request as ready for review October 11, 2024 15:56
@javagl
Copy link
Contributor Author
javagl commented Oct 12, 2024

A small update: As mentioned above, pricking arbitrary property attributes is not supported until now. It is not entirely clear what the expected behavior should be when someone tries to pick property attributes. But in the previous state, it could happen that this caused an error to be thrown (specifically, when the property attribute type was one of the types that could not trivially be transported through the picking frame buffer, like a FLOAT32 or ENUM).

The last commit handles this: The function that determines the "picked metadata property" now only looks for property texture properties (and no longer for property attribute properties), and bails out early if no property texture property is found. A // Note... was added to the function, pointing to #12225 , which keeps track of this.

@javagl javagl requested a review from ggetz October 18, 2024 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant