Skip to content

Add cap prop to ColumnLayer for dome and cone top geometry#10038

Draft
Copilot wants to merge 2 commits intomasterfrom
copilot/add-variable-radius-to-columns
Draft

Add cap prop to ColumnLayer for dome and cone top geometry#10038
Copilot wants to merge 2 commits intomasterfrom
copilot/add-variable-radius-to-columns

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 25, 2026

Adds a geometry-only cap prop to ColumnLayer that shapes the top of each column. No per-instance attributes — zero rendering overhead on instances.

Change List

  • ColumnGeometry: Added cap?: 'flat' | 'dome' | 'cone' to ColumnGeometryProps. When cap is not 'flat' and extruded: true, replaces the flat top tessellation with a cap built from interleaved ring triangle strips:

    • 'cone' — 1 ring sweep to a single apex; degenerate apex vertices produce clean cone faces
    • 'dome'max(2, round(diskResolution / 4)) rings along a quarter-circle arc; smooth normals transition from outward at the base to (0,0,1) at the apex
    • Cap height equals the column radius; side geometry and wireframe indices are unchanged
  • ColumnLayer: Added cap prop (default 'flat') to _ColumnLayerProps and defaultProps; forwarded through getGeometryColumnGeometry; wired into updateState geometry-regeneration check

  • Tests: Added ColumnGeometry#cap spec covering vertex counts, apex position, side geometry preservation, and height=0 passthrough

  • Docs: Added cap entry to column-layer.md

new ColumnLayer({
  data,
  getPosition: d => d.coords,
  getElevation: d => d.height,
  cap: 'dome',   // or 'cone' | 'flat' (default)
  extruded: true
})
Original prompt

This section details on the original issue you should resolve

<issue_title>[RFC] Trees</issue_title>
<issue_description>### Target Use Case

We started simply: in Leaflet, a CircleMarker was enough to show where each tree was. As we began extracting more structure—height, canopy area, density, fruit count, leaf color, and other derived metrics—we needed to communicate more than just location. We moved to deck.gl and adopted ColumnLayer, mapping height to a selected metric to give farmers an at-a-glance 3D view of their fields.

But a tree is more than a single scalar. It has a trunk and a canopy, a footprint and a volume, and a set of physical and biological traits that could all be visually encoded. I initially only wanted to add a dome-like bevel to the “gaps” in the field (viable row space with no tree), but while iterating on the bevel logic it became clear that there is no way today to vary the radius per column. Without per-instance radius, it’s hard to represent organic structure—canopy vs. trunk size, domed ground patches, tapered forms—and in practice the cap shape and the column radius need to be controlled together.

V0 (2020-2023) V1 (2023-2026) Proposed V2 (2026+)
V0 V1 V2

Proposal

I have #9933 as a functional prototype.

Yet, for discussion, I propose two opt-in accessors:

  • getRadius: per-instance base radius of the column

  • getBevel: per-instance cap profile (flat, dome, cone, or custom bevel parameters).

The existing radius, which I propose be renamed to radiusScale - consistent with the ScatterplotLayer - remains as a global multiplier applied on top of getRadius.

The effective radius becomes:

effectiveRadius = getRadius(d) * radiusScale(d)

For backwards compatibility and zero-cost default behavior:

If getRadius is not provided, the layer follows the current ColumnLayer path:

  • getRadius(d) = 1

  • radiusScale = 1000

If getRadius is provided, the layer switches to an opt-in shader/attribute path that uses the supplied base radius and applies radiusScale as a multiplier.

column-layer.ts

getShaders() {
  const defines: Record<string, any> = {};

  const {flatShading, getRadius} = this.props;

  if (flatShading) {
    defines.FLAT_SHADING = 1;
  }

  if (getRadius) {
    defines.HAS_RADIUS = 1;
  }

  return super.getShaders({
    vs,
    fs,
    defines,
    modules: [project32, flatShading ? phongMaterial : gouraudMaterial, picking, columnUniforms]
  });
}

column-layer-vertex.glsl.ts

#if HAS_RADIUS
in float instanceRadii;
#endif

This Gemini creation should help portray the bevel concept:

Image

Finally, I want to thank @felixpalmer for challenging me to think thoroughly though this proposal. I understand its a big change, and these things have gotten easy to do with agentic yes-men, but I know true learning happens in discussions like this, with real human feedback and disagreement.

As a little plus, it would answer this 2020 discussion question: #4324</issue_description>

<agent_instructions>Take the original idea I made in #9933 and Felix's feedback for a simple cap shape modifier on the columnlayer and make that simple addition rather than making the complex tree shape - just a column cap.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@felixpalmer For your use case, could you not use `ScenegraphLayer` with a custom tree model and then vary the radius using `getScale`?

My view on this proposal is that we should not add any new accessors - the ColumnLayer is used by other layers for rendering and often many columns are drawn. Adding accessors would slow this down even if people we not to use the feature.

I think the scope should be limited to adding a dome or cap purely by modifying the geometry as this will not impact performance but will give users a way to apply a different style to the columns.

@chrisgervang @Pessimistress @ibgreen for comment</comment_new>...


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Co-authored-by: charlieforward9 <62311337+charlieforward9@users.noreply.github.com>
Copilot AI changed the title [WIP] Add variable radius feature to columns in tree visualization Add cap prop to ColumnLayer for dome and cone top geometry Feb 25, 2026
@ibgreen
Copy link
Copy Markdown
Collaborator

ibgreen commented Mar 1, 2026

Code looks reasonable at first blush...

Something that could help motivate this:

  • Any examples/screenshots of visualizations with this enabled, and/or an argument for why this is a good addition?
  • Additions to generic layers should have a fairly wide applicability / generic interest.

@charlieforward9
Copy link
Copy Markdown
Collaborator

@ibgreen This has been a evolving feature ive worked on across various branches and both this and the community repo - i decided to split it into the TreeLayer as per @felixpalmer feedback and keep the cap idea in the ColumnLayer

References
RFC - #9942
original PR with example - #9933

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.

[RFC] Trees

3 participants