Skip to content

feat: Add triangular patches to @typegpu/geometry - #3014

Open
reczkok wants to merge 5 commits into
feat/geometry-meshesfrom
feat/geometry-patches
Open

reczkok wants to merge 5 commits into
feat/geometry-meshesfrom
feat/geometry-patches

Conversation

@reczkok

@reczkok reczkok commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Adds triangular patch surfaces to meshes, with subdivision separate from surface sampling

  • icosphere, capsule and rounded box primitives
  • tessellate into indexed geometry or sample patches directly in vertex shaders
  • shared index buffer across subdivision levels, so detail can change without rebuilding buffers
  • spherical interpolation helpers + an interactive patch tessellation example

Tessellation and spherical interpolation ideas yoinked from @deluksic’s de/geometry-spheres branch, shared in the original PR comment

Stacks on #2997

@github-actions

github-actions Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

pkg.pr.new

packages
Ready to be installed by your favorite package manager ⬇️

https://pkg.pr.new/software-mansion/TypeGPU/typegpu@b83da478cd244cca83dd5415ca70c313a5f44a19
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/react@b83da478cd244cca83dd5415ca70c313a5f44a19

benchmark
view benchmark

commit
view commit

@github-actions

github-actions Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Bundle size comparison (import * as ... in PR vs import * as ... in target):

🟢 Decreased ➖ Unchanged 🔴 Increased ❔ Unknown
0 355 0 0

No notable changes.

If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.

@github-actions

github-actions Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Resolution Time Benchmark

---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [1.07, 2.25, 5.11, 7.41, 8.52, 14.04, 29.81, 26.50]
  line [1.08, 2.25, 4.36, 7.36, 8.99, 13.79, 28.37, 29.98]
  line [1.05, 2.17, 4.49, 7.40, 9.34, 12.71, 28.21, 26.68]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.36, 0.55, 0.78, 0.90, 1.24, 1.36, 1.56, 1.76]
  line [0.37, 0.62, 0.75, 0.89, 1.20, 1.30, 1.57, 1.74]
  line [0.33, 0.56, 0.81, 0.95, 1.22, 1.31, 1.61, 1.73]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.87, 2.31, 4.48, 8.31, 15.77, 28.55, 61.53, 124.73]
  line [0.90, 2.47, 4.24, 7.97, 14.31, 28.59, 61.96, 124.66]
  line [0.95, 2.46, 4.79, 8.38, 15.97, 27.83, 60.18, 124.10]
Loading

@reczkok
reczkok force-pushed the feat/geometry-patches branch from 4513b17 to 177de99 Compare October 6, 2026 15:11
@reczkok
reczkok force-pushed the feat/geometry-patches branch from 177de99 to 73218eb Compare October 16, 2026 18:56
@reczkok
reczkok force-pushed the feat/geometry-patches branch 2 times, most recently from f58678c to 4e3132a Compare October 22, 2026 12:22
@reczkok
reczkok force-pushed the feat/geometry-patches branch from 4e3132a to 36cdb51 Compare October 22, 2026 12:44
@reczkok
reczkok marked this pull request as ready for review October 22, 2026 13:00
Copilot AI balanced review requested due to automatic review settings October 22, 2026 13:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Rounded-box radius handling can invert faces for thin dimensions, while fully rounded boxes retain unnecessary collapsed geometry.

2 open issues
What changed in this PR

Adds triangular patch surfaces to the meshes API, separating surface sampling from subdivision. This supports both indexed geometry and direct vertex-shader evaluation.

Changes:

  • Adds icosphere, capsule, and rounded-box patches with tessellated convenience constructors.
  • Introduces triangle subdivision utilities, reusable index prefixes, and spherical interpolation helpers.
  • Adds an interactive example and tests for topology, surface sampling, and shader resolution.
File Description
packages/​typegpu-geometry/​tests/​patches.test.ts Tests subdivision, watertightness, and interpolation specialization.
packages/​typegpu-geometry/​tests/​mesh.test.ts Extends primitive and degenerate-triangle checks.
packages/​typegpu-geometry/​src/​mesh/​triangles.ts Defines patch surfaces and subdivision utilities.
packages/​typegpu-geometry/​src/​mesh/​patchPrimitives.ts Adds tessellated primitive constructors.
packages/​typegpu-geometry/​src/​mesh/​patches/​spherical.ts Implements spherical interpolation helpers.
packages/​typegpu-geometry/​src/​mesh/​patches/​rounded.ts Implements capsule and rounded-box patches.
packages/​typegpu-geometry/​src/​mesh/​patches/​index.ts Exports patch constructors and interpolation helpers.
packages/​typegpu-geometry/​src/​mesh/​patches/​icosphere.ts Implements icosphere patches.
packages/​typegpu-geometry/​src/​mesh/​index.ts Exposes the new mesh APIs.
apps/​typegpu-docs/​tests/​individual-example-tests/​mesh-patches.test.ts Checks example pipeline shader resolution.
apps/​typegpu-docs/​src/​examples/​rendering/​mesh-patches/​meta.json Registers the example metadata.
apps/​typegpu-docs/​src/​examples/​rendering/​mesh-patches/​index.ts Demonstrates adjustable subdivision with shared indices.
apps/​typegpu-docs/​src/​examples/​rendering/​mesh-patches/​index.html Provides the example canvas.

Review effort: Balanced

Comment thread packages/typegpu-geometry/src/mesh/patches/rounded.ts
Comment thread packages/typegpu-geometry/src/mesh/patches/rounded.ts

@pullfrog pullfrog Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

roundedBox silently produces inside-out geometry when radius exceeds half the smallest box dimension, and a majority-degenerate, non-manifold mesh at exactly half. inset = halfSize - radius is never clamped or validated.

( ◦°^°◦) 🏴‍☠️

Ahoy! I plundered the diff o' PR #3014, ran the geometry tests, typecheck and linters, and keelhauled one leaky roundedBox radius that flips the hull inside-out when it be past half the smallest beam. One warnin' be posted below, savvy?

Reviewed changes

  • Patch surfaces — adds icosphere, capsule and roundedBox as shader-evaluated PatchSurface objects under src/mesh/patches/, with spherical interpolation helpers (linear, uniformArea, arc, warp).
  • Triangle tessellation — triangles.ts adds the CPU helpers triangleVertexCount/triangleIndexCount/triangleIndices and the GPU helpers triangleBarycentrics/triangleIndexAt, plus tessellate mapping a linear vertex index onto a triangular grid.
  • Shared index buffer — triangleIndexAt is segment-independent, so one max-segment index buffer works as a prefix at every lower subdivision; the new docs example drives detail from a single buffer while the vertex shader recomputes barycentrics.
  • Patch primitives + example — patchPrimitives.ts tessellates the three shapes with a segments option, plus a new mesh-patches docs example and jsdom example test.

I verified the geometry tests (44 passing), typecheck, lint and formatting locally, and independently checked that the index-prefix property holds for every segment value in [1..32] and that capsule/icosphere stay watertight and correctly wound across the probed parameter ranges. The only issue found is the unclamped radius below.

Comment thread packages/typegpu-geometry/src/mesh/patches/rounded.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

( ◦°^°◦) 🏴‍☠️

Ahoy! I boarded the new commit on PR #3014 and found the leak I'd flagged last voyage already plugged — the roundedBox radius be clamped to half the smallest beam, so no more inside-out hulls. Batten down the tests and let her sail.

Reviewed changes

  • Clamped the rounded-box radius — roundedBox now resolves radius as Math.min(maxRadius, halfSize.x, halfSize.y, halfSize.z) (patches/rounded.ts:92) and documents it as "Clamped to half of the smallest dimension". This removes the negative inset that previously mirrored face/edge patches and wound ~55% of triangles inside-out once radius exceeded half the smallest dimension.
  • Added a thin-box winding case — mesh.test.ts gains ['thin rounded box', meshes.roundedBox({ height: 0.05 })], exercising the newly clamped path where inset reaches zero on the smallest axis.

I re-ran the geometry suite (45 passing) and package typecheck, and independently probed five configurations (radius well above min/2, exactly min/2, thin boxes, and a normal case): none produce inside-out triangles anymore. The residual trade-off — collapsing to exactly min/2 leaves zero-area face/edge patches on the smallest axis (e.g. radius: 0.5 on a unit cube yields 576/704 degenerate triangles) — is wasted geometry rather than a rendering defect, and matches the clamp semantics the author chose. Prior review's inline thread is resolved on GitHub.

Pullfrog  | Fix it ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

This branch has not been deployed

No deployments
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.

2 participants