KhronosGroup / ANARI-Docs

ANARI Documentation
Other
31 stars 8 forks source link

The ANARI_KHR_GEOMETRY_GLYPH extension for glyphs/oriented shapes #109

Open kvankooten opened 1 year ago

kvankooten commented 1 year ago

Usecase is visualization of a set of (typically unconnected) points with arbitrary shapes of arbitrary non-uniform scale (typicaly called glyphs).

Problem with the current spec is: line-segment representation for cylinders/cones whereas spheres are point-based, constant conversion for user (and arbitrary interpolation of data for all arrays) if they only want to change shape of the representing glyphs around point samples. Need for a point-based representation that allows for orientations (quaternions) and non-uniform scaling, so the various attribute arrays and shapes can be provided/changed/removed orthogonally from eachother without the need for the app to re-process any existing data - ie. a natural glyph interface.

A new geometry type is preferable to amending the sphere geometry type, as this allows for points to be represented in a form fully optimized for points only (think of a custom point splatting/neural representation).

The proposal is as follows:

...

The extension introduces geometry type glyph/orientedShape, with the same parameters (and definitions) as the sphere geometry, except:

Parameter shapeTypesupports types up to sphere/cylinder/cone if ANARI_KHR_GEOMETRY_SPHERE/CYLINDER/CONE are supported, whereas shapeGeometrysupports up to triangle/quad if ANARI_KHR_GEOMETRY_TRIANGLE/QUAD are supported. For further shape types, extensions ANARI_KHR_GEOMETRY_GLYPH_SHAPETYPE_<TYPE> and ANARI_KHR_GEOMETRY_GLYPH_SHAPEGEOMETRY_<TYPE> will have to be introduced.

If both shapeTypeand shapeGeometryare set, the shapeGeometryis used over the shapeType. If none are set, a sphere is chosen as default shape. In case of shapeTypebeing set to cylinder/cone, a (vertex.)cap parameter is supported, to denote cap information similar to the cylinder and cone geometry types.

In absence of a scale and shapeTransform parameter, the bounds of a shapeTypeare always of length 2 in every dimension, centered around the origin, so [min,max]=[-1.0, 1.0]. A shapeGeometryretains its bounds as the extent of the geometry. The scale multiplies these bounds in every dimension (thereby being equivalent to the radius parameter, but over multiple dimensions). The shapeTransform is applied before the scale.

In absence of an orientation and shapeTransform parameter, cones and cylinders are aligned along the Z-axis, with the apex of the cone on the positive side. The shapeTransform is applied before the orientation.

Arrays of the shapeGeometryset for a particular attribute parameter take precendence over those set for that same parameter on the glyph geometry.

Name of the extension is either ANARI_KHR_GEOMETRY_GLYPHor ANARI_KHR_GEOMETRY_ORIENTED_SHAPE.

...

Open questions:

kvankooten commented 1 year ago

An example extensions json is provided by the usd device, which already implements the extension: https://github.com/NVIDIA-Omniverse/AnariUsdDevice/blob/main/khr_geometry_glyph.json

The repo also provides tests under https://github.com/NVIDIA-Omniverse/AnariUsdDevice/blob/main/examples/anariTutorial_usd.c#L437C6-L437C6

johguenther commented 6 months ago

I wonder whether the discussed array instance sub-type will cover this glyph usecase well, while being more generic.

kvankooten commented 5 months ago

The glyph proposal is created especially because something like the array instance subtype is too generic: it's critical that the various aspects of the transform are separated, and the fixed shape transform is separated from the per-instance transform parameters as well - otherwise it is not a natural glyph interface.

It is critical for the USD device to not have this information flattened into a single matrix, and it dramatically simplifies ANARI's integration into apps like ParaView in general, where glyphs are front and center. Bugs due to mistakes in the transform logic already exist even without the flattening and simply switching back and forth between certain different shapes should not result in dramatically different codepaths being executed, which would be the case if you would compare using a sphere geometry with an instance array of arrows.

I wouldn't be principally opposed to having the glyph construct exists elsewhere in the ANARI object hierarchy since there are some drawbacks/ambiguities of the current approach, namely essentially introducing two-level transforms - in the instance, and then again in the shapeTransform param. But it is definitely most similar to a mesh object in its interface, so I'm not sure where it should then move.