FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GSOC 26: document multi-material and texture map support by Nixxx19 · Pull Request #9068 · processing/p5.js · GitHub

GSOC 26: document multi-material and texture map support - #9068

Merged
davepagurek merged 7 commits into
processing:mainfrom
Nixxx19:mtl-docs
Aug 16, 2026
Merged

GSOC 26: document multi-material and texture map support#9068
davepagurek merged 7 commits into
processing:mainfrom
Nixxx19:mtl-docs

Conversation

Nixxx19 commented Aug 10, 2026

Copy link
Copy Markdown
Member

what

phase 7 docs. updates the jsdoc for loadModel(), model(), and buildGeometry() so the reference explains multi-material and texture-map support, which the docs didn't mention before.

  • loadModel(): expands the mtl note to say multi-material models are drawn per part, lists the texture maps a material can use (map_Kd, map_Ks, map_Ka, map_Ns, map_Bump), and documents the graceful fallback when a texture fails to load
  • model(): notes that the call is identical whether a model has one material or many, so a blender/sketchfab model shows up looking the way it was made
  • buildGeometry(): notes that switching texture/material mid-callback splits the result into parts, matching how a loaded multi-material model behaves, while a plain fill() change does not split

notes

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

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Thanks, these examples are looking good!

Comment thread src/webgl/3d_primitives.js Outdated
* once to create the new 3D shape.
* Note: `buildGeometry()` can only be used in WebGL mode.
*
* Changing the material partway through the callback splits the result into

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

It's probably OK to omit this paragraph, as it's more of an implementation detail -- people can switch textures and it Just Works 🙂

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

good call, dropped it. switching textures just works so theres no reason to explain the internals here

Comment thread src/webgl/loading.js Outdated
* `.mtl` file alongside it.
* Note: When a `.obj` file references materials stored in a `.mtl` file,
* p5.js loads and applies them. A model with several materials is drawn one
* part per material, so it appears the way it was exported instead of as a

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Similar here, we maybe don't need to mention the existence of internal parts, but mentioning the different things it might load still makes sense here.

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

trimmed the parts mention, kept the list of texture maps it can load since that part is useful to know

Comment thread src/webgl/3d_primitives.js Outdated
* Note: `buildGeometry()` can only be used in WebGL mode.
*
* Changing the material partway through the callback splits the result into
* parts. For example, calling <a href="#/p5/texture">texture()</a> with one

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

When we mention references to code, even if it's in a link, we should put it within backticks to render it in a monospace font. (There are a number of instances that need this below in the diff that we should update.)

Suggested change
* parts. For example, calling <a href="#/p5/texture">texture()</a> with one
* parts. For example, calling <a href="#/p5/texture">`texture()`</a> with one

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

done, and swept the rest of the diff for the same thing, all the code references inside links are backticked now

Comment thread src/webgl/material.js
* function draw() {
* background(0);
* pointLight(255, 255, 255, -50, -50, 100);
*

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Thoughts on adding:

  orbitControl();
  rotateY(sin(millis() * 0.002) * PI * 0.1);

...so we can see the effect more strongly?

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

added, good suggestion. the rocking makes the surface detail much easier to read. did the same on the other examples

Comment thread src/webgl/material.js
*
* function draw() {
* background(0);
*

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Similar to before, let's add orbitControl and some slight rotation here

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

done here too

Comment thread src/webgl/material.js
* }
*
* function draw() {
* background(0);

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Let's also add orbitControl here. I notice there's a seam in the texture, any idea what's up with that?

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

added orbitControl here too.

on the seam: it's the sphere's uv seam rather than anything in the normal map code. sphere() wraps u from 0 back around to 1 in one column, and the tangent frame normal mapping uses is derived from the uvs, so right at that column the tangent goes degenerate and the lighting flips with it.

i checked by drawing the same image two ways, once with texture() and once with normalTexture(). the plain textured sphere shows only a faint line in that spot, while the normal mapped one shows the strong seam, so the uv wrap is the source and normal mapping is amplifying it.

worth noting it isn't specific to this example, any normal mapped sphere() will show it. if we want it gone the fix would be in computeTangents(), unwrapping the uv delta when a face straddles the seam (du > 0.5) so the tangent doesn't flip. happy to do that as a follow up if you'd like, it felt out of scope for a docs pr.

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yeah worth addressing in a follow-up PR. But I think no face actually goes across the seam? Worth double-checking, but I think the faces line up such that one face goes from e.g. 0.9 to 1 where the 1 side has the same vertex locations as the 0 to (e.g.) 0.1 faces. So that would mean that to seamlessly tile, the rightmost column of pixels should exactly equal the leftmost. Possibly we could also try turning on the REPEAT texture mode for textures used as maps so that sampling u=1 does the same thing as sampling u=0.

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

That would mean a slightly different interpretation compared to the uv map though -- e.g. on a plane, we don't want u=0 to be the same as u=1. So to be shape agnostic, it maybe makes sense to instead repeat a column of pixels for intentionally tiling textures to avoid having to introduce another parameter for whether texture maps should tile?

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

you're right and i was wrong, no face straddles the seam. sphere() builds its columns with for (let j = 0; j <= detailX; j++) and u = j / detailX, so there are detailX + 1 columns and the j=0 and j=detailX ones sit at the same place with u=0 and u=1. duplicated seam vertices, no wrap, so my computeTangents() theory was off.

so it's the texture not tiling, exactly like you said. i tested it: making the pattern repeat a whole number of times across the image removes the seam on the normal mapped sphere completely.

the bump map needed one more thing. because it reads neighbouring texels to get the slope, the neighbour at u=1 runs off the edge and clamps, so the slope goes flat right at the seam even when the image tiles. textureWrap(REPEAT) fixes that, since the neighbour then wraps to the other side. with tiling + REPEAT both examples are clean.

and agreed on staying shape agnostic, forcing REPEAT on all maps would be wrong for a plane. leaving it to the texture (tile it, and turn on REPEAT when you want it to wrap) avoids a new parameter. both examples in #9089 now do that.

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

opened #9091 for the follow up, covers documenting that maps need to tile to wrap cleanly, and whether the bump map gradient lookup should wrap on its own instead of relying on textureWrap(REPEAT).

davepagurek merged commit c48cca7 into processing:main Aug 16, 2026
6 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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


Back | FazBrowse Home | New Git URL