BufferPrimitiveCollection: Add 3D renderers#13213
Conversation
|
Thank you for the pull request, @donmccurdy! ✅ We can confirm we have a CLA on file for you. |
7559040 to
6773154
Compare
e665b09 to
a4bf666
Compare
d3bce7c to
f3706de
Compare
a4bf666 to
e274227
Compare
| - name: format code | ||
| run: npm run prettier-check | ||
| - name: build | ||
| run: npm run build |
There was a problem hiding this comment.
We have to build before running npm run tsc so the type checker can see built outputs from *.glsl files.
| * @param {number} vertexOffset | ||
| * @param {number} vertexCount | ||
| */ | ||
| VertexArray.prototype.copyAttributeFromRange = function ( |
There was a problem hiding this comment.
These methods could be moved somewhere else, but seemed like they might be generally helpful? The use case here is to hold an array of the same size as the buffer in memory, and to re-upload only the dirty range after updates.
Avoids memory allocation (and potential GC stalls) during rendering. This would be harder to guarantee if the array were created dynamically in the render loop, or sized to only include the updated range of elements.
f3706de to
f530c58
Compare
bb865d4 to
2a2eebe
Compare
0bc2cbe to
af8a62d
Compare
2a2eebe to
48874f5
Compare
56da7cf to
496f6eb
Compare
a410541 to
04babfd
Compare
@danielzhong in earlier versions I'd declared |
|
I'm considering changing the styling API from this pattern... collection.get(i, point);
point.pixelSize = 6;
point.setColor(Color.WHITE);
point.outlineWidth = 2;
point.setOutlineColor(Color.RED);... to something like this ... collection.get(i, point);
const material = new BufferPointOutlineMaterial({
pixelSize: 6,
color: Color.WHITE,
outlineWidth: 2,
outlineColor: Color.RED
});
point.setMaterial(material);All primitives in a collection must share the same material type, but each primitive may have different material properties without affecting batching. Calls to Reasoning:
I don't think (2) fits our short-term delivery timelines... it's not obvious how to batch effectively with existing materials using distinct uniforms, and existing materials don't appear to cover all primitive types (points, lines, polygons). So we'll likely need separate classes e.g. |
…vert styling API, add DrawCommand cache
|
Updates:
@danielzhong @lilleyse I think this PR should be ready for review when you have the chance! There's still a bit missing here: certain styling features are implemented in shaders but readonly in JS, blending and polygon offset aren't exposed, modelMatrix and culling could use more testing. But I think this might be a good scope to merge next, then it's easier to continue with these next steps in parallel:
|
|
@danielzhong @lilleyse Ready for review when either of you have the chance, thanks!
|
| // @ts-expect-error Requires https://github.com/CesiumGS/cesium/pull/13203. | ||
| usage: BufferUsage.STATIC_DRAW, | ||
| // @ts-expect-error Requires https://github.com/CesiumGS/cesium/pull/13203. | ||
| indexDatatype: IndexDatatype.UNSIGNED_INT, |
There was a problem hiding this comment.
Would it be possible to use a smaller indexDatatype depending on vertex count?
There was a problem hiding this comment.
So probably not exposing a separate indexDatatype option but just choosing based on the max vertex count allocated? That works yes, done! ✅
Aside: In-memory hole and triangle indices are (currently) offsets relative to each polygon's own vertices. So technically we could use 'byte' index types if no single polygon has >255 vertices. But (1) the collection doesn't currently know the per-polygon max vertex count, just the per-collection max vertex count, and (2) I can imagine we might make these offsets absolute within the collection later, depending on the vector tile format and loading process.
|
Sandcastles: |
|
The latest changes look good. And thanks for sending over the sandcastles, the GeoJSON one is super fast! |
Description
Highlights
Implements default renderers on top of the data model proposed in #13212: BufferPointCollection, BufferPolylineCollection, and BufferPolygonCollection. Styling is limited right now, and does not include clamping to terrain or height reference offsets.
Implementation
Each of the three (point/line/polygon) renderers follows exactly the same rendering process:
Because BufferPrimitiveCollections have a fixed capacity, it's very efficient to allocate GPU resources for that capacity on first render, and then to add or update primitives incrementally, repeating steps 2–5 above. On my laptop, for example, it's certainly feasible to update position and color of 20,000 small polylines each frame at 60 FPS. More detailed benchmarks in #13156 (comment).
Notes
I expect we'll want to add more features to these renderers over time, however ... an important design goal for this PR and #13212 is that the data models for each primitive type can be reused for multiple renderers. Draping polylines and polygons on terrain will require a distinct renderer.
I have mixed feelings about putting appearance-related properties directly on the BufferPrimitive subclasses, as I've done here with methods like(reverted)polyline.setOutlineColor(color). If these APIs support multiple renderers, it might be nice to have some way to extend styling features without extending the core data model, like:This would require that (1) all primitives in a collection share the same material type, but not the same material uniforms, and (2) that the collection be able to serialize the material into the buffer similarly to other per-primitive properties. I've left that as a potential future improvement for now.Aside - I've also been wondering about putting
.showOffset/.showCountproperties on each collection, which would enable scrubbing through a collection (sorted by time) at basically zero performance cost. But I'm not sure how/if that pattern would work in clamped renderers, so it's not included here yet.Issue number and link
Testing plan
Added unit tests for rendering all topologies. Shared sandcastles in comments below.
Author checklist
CONTRIBUTORS.mdCHANGES.mdwith a short summary of my changePR Dependency Tree
This tree was auto-generated by Charcoal