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

[FEATURE] Support arbitrary vertex attributes #7

Open
nicopap opened this issue May 19, 2023 · 6 comments
Open

[FEATURE] Support arbitrary vertex attributes #7

nicopap opened this issue May 19, 2023 · 6 comments
Labels
enhancement New feature or request

Comments

@nicopap
Copy link
Contributor

nicopap commented May 19, 2023

TMF looks super cool!

But I'd not only want to store normal, positions and uvs data. Formats like glTF also store other attributes per vertex, such as: color, tangent, secondary uvs, skeletal animation bone weights.

Game engines do use more than normal position and uvs, and it seems reasonable to expect from a mesh serialization format that it supports additional attributes.

Implementation

I'm conscious this is not a trivial task, because each attribute can have an arbitrary representation. And it probably makes it hard to apply some useful heuristics. So I'm not adventuring to propose an implementation. But the most basic API I'd like is a method on TMFMesh that does:

fn set_attribute<T: VertexAttribute>(&mut self, attribute_id: usize, buffer: &[T]) {}
fn get_attribute<T: VertexAttribte>(&self, attribute_id: usize) -> Option<&[T]> {}

(this is an extremely primitive API that can fairly trivially be improved, not a template for a final API)

A method on VertexAttribute could provide to TMFMesh informations so that it can apply good compression heuristics, and specifically allow erasing the type (so that it could be internally stored as a Box<[u8]> and cast when accessed)

What is this for?

I'm maintaining the bevy_fbx crate and bevy is landing a new asset loader with a post-processing step. The FBX format suuuuucks and is wasteful when it comes to game assets (it even leaks private information), using an intermediary representation *that is fast to write and read from is a necessity tbh.

My fbx loader currently only supports normal positions and uvs, so I already can use TMF! However, storing tangents in the backed meshes would be super useful, it would allow not having to compute tangents at runtime, which can be fairly expensive.

@nicopap nicopap added the enhancement New feature or request label May 19, 2023
@FractalFir
Copy link
Owner

Supporting arbitrary vertex attributes would not be hard, but those attributes would receive little to no size reduction due to the compression algorithm requiring a lot of insight into data stored. Since knowing what is stored accounts for most of the savings (normals being unit vectors, uvs being in the range 0.0-1.0), a lot of savings comes from code which differs for each attribute. So custom vertex attributes would be mostly compression-less. The compression-less variant could be added in a couple of work hours.

A much better approach would be to have dedicated format segments for those attributes. Knowing their properties could allow for them to be compressed. Would you mind opening issues for each kind of data your use case requires?

@FractalFir
Copy link
Owner

d9a5be3 adds some groundwork for supporting custom mesh data. API will be a bit more involved than the one proposed (many kinds of CustomData), but all custom data will be compressed.

Planned supported data kinds:

  1. CustomIndex
  2. CustomFloat
  3. CustomVetor2
  4. CustomVector3
  5. CustomVector4
  6. CustomColor(Vector4 with components of between 0.0 and 1.0)
  7. CustomUnit2(Vector2 of length 1)
  8. CustomUnit3(Vector3 of length 1)

This data may reuse some of the compression architecture and would be compressed to comparable levels as other mesh data.
Each custom segment should have a unique name of between 1 and 255 characters.

@nicopap
Copy link
Contributor Author

nicopap commented May 20, 2023

Awesome. This is way beyond any expectation. It's definitively not a deal breaker to not have access to extra attributes, but it's very handy. I'll open a feature request for tangents.

@FractalFir
Copy link
Owner

d38894d adds support for saving/reading custom indices with a name of up to 255 characters. All the groundwork for saving other data types is there, only thing left to implement is the glue code to decode the data in other types of custom segments.

@FractalFir
Copy link
Owner

Support for custom float attributes added in a164eb2.

@FractalFir
Copy link
Owner

Support for RGBA colors added in 6f7598a.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants