Context: Ultimately, I would really like to have the path part of my PolylineGraphics change color as it progresses. Before I can coherently discuss how that might happen I want to understand how and where polyline geometry gets created and rendered.
Here's my current understanding of how and where polyline geometry gets managed and rendered. I would like to ask for a quick sanity check including where I'm wrong and especially pointers to important things I've missed.
- PolylineGeometry has its geometry created in Primitive.createCommands(). The user supplies the geometry directly, including (optionally) an array of Colors to be used to color the vertices or line segments. I don't know whether the GL layer does the interpolation itself or whether this happens in a fragment shader. PolylinePipeline can finesse the geometry however it wants, of course, but the positions and colors arrays are the starting point.
- PolylineGraphics takes one of two paths depending on whether the geometry is static or dynamic.
* Static geometry: PolylineGeometryUpdater.createFillGeometryInstance() creates a PolylineGeometry that then gets used in a GeometryInstance. Since the color is passed in as a ColorGeometryInstanceAttribute, this path only supports a single solid color.
* Dynamic geometry: The DynamicGeometryUpdater defined in PolylineGeometryUpdater.js instantiates a PolylineCollection for each Scene. Each PolylineGraphics in a scene gets an item (a Polyline) in that PolylineCollection. That uses the material set on the PolylineGraphics, which looks like it could do time-varying color via SampledProperty(Color) but apparently has no way to do per-vertex color.
Is this correct? There's lots more to discuss but I want to make sure I'm on solid ground before I dive into what the future may hold.
I spent a while today looking at how color is handled in materials. It looks like per-vertex color is only available in two Primitives (PointGeometry and PolylineGeometry), which makes sense on the basis that those are the only primitives where the user is required to supply all the vertices. Compare to something parametric like SphereGeometry where the user doesn't even know how many vertices there are.
As a result I'm thinking along two different lines. The first is to change PolylineCollection to support per-vertex color. I know this has implications for command batching so that's what I'm going to study next. The second approach is to start looking into time-varying color for materials. I'm thinking about having the geometry updater sample colors the same way it calls SampledPositionProperty to sample positions.
I am explicitly not considering ways to do per-vertex color on parametric primitives likes spheres, cylinders and cones. I've got some vague thoughts on what it might take to do that and I've decided that it's firmly out of scope.
I intend to contribute back (or at least offer) whatever I implement. I've started a conversation with my organization's legal department about the contributor agreement.
Meanwhile, I've got a conundrum. Where do per-vertex colors actually belong in the split between Geometry and Material? Strictly speaking, color is an appearance property instead of a geometric property: you can change the colors (or normals, or texture coordinates, or tangent vectors...) without affecting the underlying geometry. On the other hand, per-vertex attributes have to be specified for each vertex in the object by definition, so maybe they're most cleanly stored along with the geometry.
Since Material is decoupled from the underlying mesh I don't see a graceful way to do per-vertex color there.
(If you haven’t seen it already, we have a number of development examples that show how to use lower level primitives. You can access these if you clone our repository from GitHub and run sandcastle locally)