-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
GSOC 26: render multi-material models per part #8955
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
bfec2d4
e812dae
962112d
b086d81
1234024
0101168
40d520a
ef33f8e
c9c0cc4
c7db707
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -589,7 +589,28 @@ export class Renderer3D extends Renderer { | |
| geometry.vertices.length >= 3 && | ||
| ![constants.LINES, constants.POINTS].includes(mode) | ||
| ) { | ||
| this._drawFills(geometry, { mode, count }); | ||
| // draw every part. a part with no material state draws straight (no | ||
| // push/pop); a single-material geometry is its own part, so that case is | ||
| // exactly the old single draw. multi-material parts each apply their own | ||
| // material around the draw. | ||
| const parts = geometry.parts && geometry.parts.length | ||
| ? geometry.parts | ||
| : [geometry]; | ||
| for (const part of parts) { | ||
| const state = part.partState; | ||
| const hasMaterial = state && ( | ||
| state.fill || state.texture || state.ambientColor || | ||
| state.specularColor || state.shininess != null | ||
| ); | ||
| if (hasMaterial) { | ||
| this.push(); | ||
| this._applyPartState(state); | ||
| this._drawFills(part, { mode, count }); | ||
| this.pop(); | ||
| } else { | ||
| this._drawFills(part, { mode, count }); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (this.states.strokeColor && geometry.lineVertices.length >= 1) { | ||
|
|
@@ -628,6 +649,31 @@ export class Renderer3D extends Renderer { | |
| shader.unbindShader(); | ||
| } | ||
|
|
||
| // apply a part's material to the renderer before it's drawn. only non-null | ||
| // fields are set, so an empty part state leaves the uniforms untouched. | ||
| _applyPartState(partState) { | ||
| if (!partState) return; | ||
| if (partState.fill) { | ||
| const c = partState.fill; | ||
| this.states.setValue('curFillColor', [c[0], c[1], c[2], 1]); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason why it's not possible for a part to have alpha in the fill? Although the obj/mtl spec puts transparency into its own command, in p5 fills can have alpha (e.g. geometry that comes from |
||
| } | ||
| if (partState.texture) { | ||
| this.states.setValue('_tex', partState.texture); | ||
| this.states.setValue('drawMode', constants.TEXTURE); | ||
| } | ||
| if (partState.ambientColor) { | ||
| this.states.setValue('curAmbientColor', partState.ambientColor); | ||
| this.states.setValue('_hasSetAmbient', true); | ||
| } | ||
| if (partState.specularColor) { | ||
| this.states.setValue('curSpecularColor', partState.specularColor); | ||
| this.states.setValue('_useSpecularMaterial', true); | ||
| } | ||
| if (partState.shininess != null) { | ||
| this.states.setValue('_useShininess', partState.shininess); | ||
| } | ||
| } | ||
|
|
||
| _drawStrokes(geometry, { count } = {}) { | ||
|
|
||
| this._useLineColor = geometry.vertexStrokeColors.length > 0; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's a scenario where we'd end up with no parts?