Skip to content
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

Adds Random Float and Random Color nodes #1330

Merged

Conversation

crydalch
Copy link
Contributor

@crydalch crydalch commented Apr 17, 2023

Adds Random Float and Random Color nodes, to simplify generating randomized signals in a material.

@Cinifreak suggested a very similar node on ASWF, so we'll collaborate on this PR.

Adds Random Float and Random Color nodes, to simplify generating randomized signals in a material.
@jstone-lucasfilm
Copy link
Member

Thanks for these contributions, @crydalch, and these are clearly fundamental nodes that are worthwhile to add. I'll just highlight the validation warnings generated in testing, which are minor but valuable to fix:

  Document is invalid: [D:\a\MaterialX\MaterialX\build\bin\resources\Materials\
  Examples\UsdPreviewSurface\usd_preview_surface_plastic.mtlx] Invalid value:
  <input name="in" type="color3" uiname="Input" value="0">
  Invalid value: <input name="in" type="vector3" uiname="Input" value="0">
  Invalid value: <input name="in" type="vector2" uiname="Input" value="0">
  Invalid value: <input name="in" type="color3" uiname="Input" uisoftmin="0"
  uisoftmax="10" value="0">
  Invalid value: <input name="in" type="vector3" uiname="Input" uisoftmin="0"
  uisoftmax="10" value="0">
  Invalid value: <input name="in" type="vector2" uiname="Input" uisoftmin="0"
  uisoftmax="10" value="0">

@kwokcb
Copy link
Contributor

kwokcb commented Apr 19, 2023

I'm wondering would it make sense to use one category name like random (or rand if it behaves like rand) instead of randomcolor and randomfloat? If you add in other variants like randomvector then there is till only 1 "random" node category so may make it easier for users especially if a node editor supports typeless nodes.

@jstone-lucasfilm
Copy link
Member

@kwokcb I think that's a good suggestion, to define a single random node with type overloads, allowing us to transparently extend the concept to vectors and other data types in the future. As you note, this will also work more smoothly in future node editors that support dynamic node typing, where the artist can place an untyped random node in the graph and its type will be inferred upon its first connection.

@crydalch
Copy link
Contributor Author

@jstone-lucasfilm and @kwokcb I'm not sure we should merge all of them together into a single .

We can provide a much better experience if users select which type of randomization they want up-front. No matter what the input type is, the users knows what the output will be. Overloading a single node will result in a large matrix of input and output signature combinations (which will only get worse as more types are added). We've been guilty of this ourselves; VEX's Random node is overloaded - and it has a menu of 61 combinations of input/output signatures! Even when you narrow down the items based on the input type, it's still a really long menu for users to parse.

I'd also suggest that random is not one of those cases where you will need that flexibility anyway. In the middle of an existing shading network, and <random_float> probably isn't going to work if you just change to <random_color>. The graph was build with the float output in-mind, so you're going to have to do a bunch of re-wiring anyway.

In general I'm all-for reducing nodes, but in this case I think letting users decide up-front makes for much better UX.

@kwokcb
Copy link
Contributor

kwokcb commented May 10, 2023

Hi @crydalch,

I can see your point about overloading the same node category too much, and about trying to switch to a different variant after the fact -- though I think any polymorphic node runs into this issue of remapping to something that still is sensible?

The "key" seems to be that randomfloat and randomcolor actually have different input signatures. There was some renaming for the combine node a little while back due to issues with the same category with the same output signature but differing input signature causing ambiguity -- though this can be handled now.

So maybe one "guiding principle" is to use the same category if the "input signature" matches, but otherwise it's a new category ? Alternatively perhaps an attribute hint can be used to "partition" the variants into groups, like uifolder on a nodedef ?

I'm "wobbling" on the fence for this one but still leaning towards one "logical" category for random number generation.

BTW, Amazing you could create 61 variations of random :).

@jstone-lucasfilm
Copy link
Member

@crydalch I wonder if the distinction that we want to make is between randomvalue and randomcolor, where the former is an n-dimensional random lookup with an m-dimensional seed, and the latter is an artistically-motivated random color generator like the one that you've proposed.

Here are a few industry examples of the randomvalue pattern we can consider:

https://docs.blender.org/manual/en/latest/modeling/geometry_nodes/utilities/random_value.html
https://www.sidefx.com/docs/houdini/vex/functions/random.html
https://substance3d.adobe.com/documentation/sddoc/random-float-215286567.html
https://docs.unity3d.com/Packages/com.unity.shadergraph@6.9/manual/Random-Range-Node.html

And here are a few links that suggest the need for a randomcolor node, though I believe Chris's current PR is better defined and more general-purpose than these examples:

https://help.maxon.net/r3d/katana/en-us/Content/html/Hair+Random+Color.html
https://blenderdaily.xyz/tips/random-color-for-each-face-of-an-object
https://www.sidefx.com/forum/topic/73410/

@jstone-lucasfilm
Copy link
Member

@crydalch Looking at the current UI for MaterialX graphs in Houdini 19.5, for example, I could see the idea of a randomvalue node working well with the "Signature" dropdown box in Solaris. The user could then place a randomvalue node through the UI and freely change its signature based on the needs of the graph, with the set of input names remaining consistent regardless of the signature that they choose.

@crydalch
Copy link
Contributor Author

crydalch commented May 11, 2023

@jstone-lucasfilm indeed, that's how it works in Houdini. My hesitation is not that the inputs might be different, or that tools won't have a menu to choose the signature. I hesitate because I've had to use nodes with lots of combinations of input and output signatures - and that menu gets rather long. Even when Houdini filters it based on connected inputs, there's still more thinking/deciding/clicking a user must go through.

When an artist types "random" into the Tab menu (or equivalent in their DCC) and they see randomfloat, randomdirection,randomvector" and randomcolor", what happens next? They easily decide/select an option, without any further clicking, typing, or reading of menus. They aren't required to additionally find which random value they'd like to use within a menu. And they don't have to worry about output types changing out from under them, because an input type changed, and the tool re-filtered the signatures and picked one you need to deal with. (I put in randomvector and randomdirection as examples of other ideas that could be useful, and I can think of how each would potentially have unique parameters). The fixed output, lets the input type can change however automatically, without cascading changes down the shading graph that they have to be aware of or potentially undo/work-around. It feels similar in some ways, to trying to combine all of the 2d and 3d noises/patterns that share similarly-named inputs, into one node; while you could do it, I'm not sure it would help users much.

I know a lot of UX is dependent on DCCs and artist tools, but why not make the available options clear for everyone using MaterialX? I don't think reducing the various "randomvalue" options down into 1 node is an optimization that helps the user. Maybe there are advantages for codegen, to having an overloaded "randomvalue" node? I'm also concerned that future developers will just happily overload the random node, because it's there... and eventually that menu's going to be long.

Asking users to spend time selecting from signature menus more than just a few options, for the sake of reducing a handful of random nodes into one, doesn't feel like it's worthwhile for users...

@dbsmythe
Copy link
Contributor

To me, the question of "should this node and that node really be just one kind of node with different signatures" boils down to one easily-answered question: do the nodes do basically the exact same thing, other than the types they operate on. In this case, the answer is clearly "no": has two inputs ("in" and "seed") and computes a random value using cellnoise2d and those two input values, while generates 3 separate 's internally then uses that to compute a random HSV color. It's a lot bigger of a change than just input signatures- it's a different function.

Separate note: it looks like the nodegraph for randomcolor_float is generating three different seeds for hue, saturation and value (good), but they look like they'd all be the same because all three are adding "0" to "seed", and that "0" isn't exposed as an interface input? I think it'd be fine to just choose different non-zero "random-looking" values for the 2nd and 3rd seed offsets and not complicate the interface with additional seed or seed_offset inputs.

@jstone-lucasfilm
Copy link
Member

@dbsmythe Just to clarify, the latest suggestion is not that we merge randomfloat and randomcolor, and the reasons that you outline here are a large part of why I wouldn't suggest this.

The suggestion is instead that we provide randomvalue and randomcolor as separate nodes, where the former handles the float, vector2, vector3, and vector4 types in a consistent way (as both Houdini and Blender currently do), and the latter is an artistically-focused color generator with HSV controls (as in Chris's post).

@crydalch What are your thoughts on that proposal? This is similar to what you suggest above, with the main difference being that we wouldn't need to support separate randomfloat, randomvector2, randomvector3, and randomvector4 nodes, and they would instead be unified into a single randomvalue. To my mind, this strikes a good balance between user clarity and consistency, but I'm definitely open to alternative suggestions based on your own experience with Houdini artists.

@dbsmythe
Copy link
Contributor

Ah I get it: what was proposed as would instead be called . That makes sense to a point, but I would expect there should also be color3 and color4 variants of (in addition to float and the 3 vector types), that would simply be 3 or 4 random floats combined into a color3 or color4 output type. This then makes the name "randomcolor" a bit confusing; I would suggest calling the "return a random color between two HSV values" node instead, to emphasize the HSV nature of the randomly-chosen color.

@crydalch
Copy link
Contributor Author

@jstone-lucasfilm I don't think we need to have a random node for every type possible, but my opinion (which I've clearly not communicated well, my apologies) is that nodes with long signature menus aren't good UX. Obviously they are necessary in many/most cases - I just don't agree that an overloaded randomvalue is the right way to go.

I'd suggest these nodes:

  • randomcolor
    • mostly as-is; I don't think users get confused that it does HSV-style color randomization? The other randomcolor-like nodes do this.
    • Or maybe there is a toggle, that would randomize RGB independently, as an alternative to the default HSV-style randomization?
    • We can add a color4 output signature, thanks @dbsmythe
  • randomfloat
    • min/max parameters
    • if convert supported float-->int, maybe randomvalue makes sense here, as it would support float or int outputs? I tried looking at the <convert> node, but I think someone else needs to tackle that.
  • randomvector
    • min/max parameters, but additionally support adding to an existing vector (for jittering normals), and have a toggle for normalizing the output vector
    • would have a longer signature menu, with the various vector output types (vec2, vec3, vec4)

Maybe that's a better balance? Users will have some clear options from their tool menu when typing "random", each node has some unique controls/behaviors, and it avoids a single node with extremely long signature menu.

How does that sound?

@jstone-lucasfilm
Copy link
Member

I like that latest design proposal, @crydalch, and you make good points above, @dbsmythe. The idea of a randomvector node with optional normalization sounds very appealing, and using the name randomfloat for the scalar version seems reasonable to me.

Copy link
Member

@jstone-lucasfilm jstone-lucasfilm left a comment

Choose a reason for hiding this comment

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

I just had a chance to test this in the Graph Editor, and the new random nodes look fantastic, with artistically meaningful behavior for both integer and float variants. Thanks so much for following through on this important contribution, @crydalch!

@jstone-lucasfilm jstone-lucasfilm merged commit 9aa9b3a into AcademySoftwareFoundation:main Jun 17, 2023
13 checks passed
Michaelredaa pushed a commit to Michaelredaa/MaterialX that referenced this pull request Oct 21, 2023
Add Random Float and Random Color nodes, to simplify generating randomized signals in a material.
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.

None yet

4 participants