Skip to content

GSOC 26: multi-material buildGeometry - #9063

Merged
davepagurek merged 9 commits into
processing:mainfrom
Nixxx19:buildgeometry-parts
Aug 11, 2026
Merged

GSOC 26: multi-material buildGeometry#9063
davepagurek merged 9 commits into
processing:mainfrom
Nixxx19:buildgeometry-parts

Conversation

@Nixxx19

@Nixxx19 Nixxx19 commented Aug 9, 2026

Copy link
Copy Markdown
Member

what

extends buildGeometry() so a model built in code can carry multiple materials, the same way a loaded multi-material obj has since #8879 and #8955.

right now buildGeometry() flattens everything into one geometry, so if you switch texture or material partway through the callback that change is lost. this makes a material change open a new part instead:

let m = buildGeometry(() => {
  texture(wood);
  box(50);      // part 0
  texture(metal);
  sphere(30);   // part 1
});
model(m);       // each part renders with its own material

how

GeometryBuilder snapshots the renderer's current per part material state (texture, specular, ambient, shininess) on each draw, using p5's own state names. when that snapshot changes between draws it opens a new p5.GeometryPart, so the result is a p5.Geometry made of parts exactly like the obj loader produces, and model() draws it per part with no renderer changes.

fill stays baked into vertexColors, so a plain fill() change never splits and per vertex colors keep working. the split only kicks in with 2+ materials, so single material builds are unchanged (zero regression). custom per vertex attributes aren't split per part yet, so those builds stay a single part for now.

this follows the community bonding design: always on splitting (no opt in flag), per field partState in p5's vocabulary, and format translation kept in the import layer.

testing

  • a texture change splits the build into 2 parts
  • a fill() change alone does not split (stays one part)
  • per part materials render the same as drawing them directly (pixel match)
  • instancing draws every part with the instance count, so model(geom, n) works per part
  • full unit suite green (2255 passing)

part of the gsoc multi-material .mtl work, follows #8879 and #8955.

this.renderer._pInst.pop();
// expose the material parts only when there really are multiple materials,
// and not while custom per-vertex attributes are in play (those aren't
// split per part yet). single-material builds keep the geometry as its own

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.

Does this mean we should make a follow-up issue to get custom vertex attributes to work with multi-part geometry?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yeah exactly, right now the per part split doesn't carry custom vertex attributes over (they would need to be reindexed per part), so this keeps the geometry whole when custom attributes are in play

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@davepagurek davepagurek 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.

Nice work, this looks good!

@davepagurek
davepagurek merged commit 1c0c39b into processing:main Aug 11, 2026
6 checks passed
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