Houdini 20 new texture mask paint node limitations?

   2797   18   3
User Avatar
Member
7 posts
Joined: Dec. 2018
Offline
After watching the Houdini 20 new features keynote video I was excited for the new texture mask paint node since it has the potential to avoid having to subdivide meshes just for the sake of attribute paint resolution. In the keynote I believe it is mentioned that they used this on the eagle feather grooming demo piece but I'm not seeing it in any of those texture nodes there after downloading the asset from the content library. I was hoping to see how they used it in that example.

My question is, once I have painted in that node and it now exists as 2d volume data, what good is it down the pipe other than to write it out as suggested in the help doc? One of the many strengths of the attribute paint method is that you can manipulate, combine, remap, blur etc that data after it is created. When its 2d volume data I'm theoretically able to blur it with "heightfield blur" or toss it into a "heightfield combine layers" but it is done in uv space and there for seems to be less useful be used directly to plug into a groom density mask or to drive a lerp in a wrangle etc.

TLDR, Im not seeing the usage for this node other than to save to disk as a texture and read back in.

Thanks!

-Matt

Attachments:
2dVol.png (70.3 KB)

User Avatar
Member
442 posts
Joined: Aug. 2019
Offline
(Disclaimer: I haven't tried it myself with H20, but iirc it was how it works in 19.5)

You can sample values from heightfield with volumesample [www.sidefx.com] VEX function. Then you store them in an attribute and manipulate them just as how you manipulate attributes.
User Avatar
Member
60 posts
Joined: Oct. 2018
Offline
The 2D volumes output by Texture Mask Paint are the same primitive type as Heightfields, and should be able to be operated on by all our Heightfield SOPs directly. One thing to keep in mind is that most of our Heightfield SOPs expect the primary incoming layer to named "Height", but you can just set the mask name to be that on the Texture Mask Paint node and everything should just work.

The 2D volumes are also, well, volumes, and so can be operated on by all our Volume SOPs as well, such as the Volume Wrangle or our Volume VOP, although many of these SOPs are geared more working with 3D volumes.

You can also plug the 2D volumes into the second input of an Attribute From Map SOP, which has been updated to support using a volume as the source. You can then work with all the data as regular geometry attributes and do all the things you would do with Attribute Paint's output.

I've attached a Hip file demonstrating some of these techniques. Please take a look and let me know if you have any further questions.

Attachments:
texture-mask-paint-output-examples.hip (2.2 MB)

User Avatar
Member
93 posts
Joined: Dec. 2019
Offline
Regarding the grooming part, existing grooming nodes have a "Volume" or "Skin VDB" input, where you can plug in the texture volume/primitive, and use it as an override option on parms that support this feature. You don't have to convert this Texture Volume into an attribute in this case, as these nodes support Texture Primitives already.

You can also find some examples on how to convert an attribute into a texture volume, and a texture volume into an attribute (Attribute from Map SOP is the easiest way, but there's an example with VEX).
Edited by ObeidaZakzak - Dec. 7, 2023 13:24:25

Attachments:
TexturePrimitivesAttribs.hiplc (2.8 MB)
TexturePrimitivesGroomingScatter.hiplc (9.0 MB)
TexturePrimitivesGroomingClumpFrizz.hiplc (12.9 MB)

Houdini Pipeline Supervisor @ TAT Studio
User Avatar
Member
7 posts
Joined: Dec. 2018
Offline
Sorry for the delay in my response. Thank you both for this information! I will dig into what both of you have mentioned and see if that helps. Thanks!
User Avatar
Member
7 posts
Joined: Dec. 2018
Offline
Ok, I was able to look over the examples you all sent. Thanks for taking the time to do that!

It makes sense overall, but I still feel the workflow is a bit limited in terms of procedurals being applied to meshes as opposed to the flat planes that typical heightfield workflows often use. When you go to apply a heightfield noise for example (see GIF), it is applying it to a plane which is then read onto the rubber toy mesh's uvs and therefore has seams as a result. This is not an issue when using the traditional attribute noise method since it is a world space effect and not tiled on uv (see other GIF).

Since one of the main advantages with using the texture mask paint workflow is that you do not have to subdivide the base mesh significantly just to get resolution, but to solve this problem in particular I would need to subdivide the mesh and run a attr noise on the subdivided rubber toy then transfer that to volume data and then combine with the other volume data in my project.

I totally see where this could be helpful if you are planning to paint 95% of your data in a project and not rely on a lot of procedural generation of data but if one has to combine the two it seems a little more cumbersome.
Edited by mleff - Dec. 12, 2023 14:43:34

Attachments:
heightNoise.gif (1.2 MB)
heightNoiseMesh.gif (1.5 MB)
attrNoiseMesh.gif (2.1 MB)

User Avatar
Member
442 posts
Joined: Aug. 2019
Offline
I'm not entirely sure what the issue exactly is. A 2D noise will have seam if you map it to some arbitrary 3D mesh's UV. It's the nature of 2D noise, and it has nothing to do with Texture Mask Paint node.

You need a 3D noise. If you want to blend between noise and hand-painting texture, then you need to sample from a 3D noise and the 2D painted texture separately then blend it yourself in vex or Attribute Composite. Or you need some specific mapping (like tri-planar). I don't think there is one-fit-all way to map 2D noise seamlessly to any mesh with its own UV.

Edit:

I guess I know what your question is about. You're asking if there is a simple way to back 3D noise via a mesh's UV space to a 2D texture, without subdiv the mesh or using COP?

That's a good question. The simplest way I know is subdiv then Lab Map Baker, but if you don't want a subdivn... I don't know how to do it either
Edited by raincole - Dec. 12, 2023 15:25:46
User Avatar
Member
7 posts
Joined: Dec. 2018
Offline
@raincole,

"I guess I know what your question is about. You're asking if there is a simple way to back 3D noise via a mesh's UV space to a 2D texture, without subdiv the mesh or using COP?"

Essentially yes.

In the keynote they spoke about this texture paint node workflow freeing up the need to subdivide meshes but as I dig further into production workflows with this method I'm still seeing the need to subdivide the mesh for some operations that the heightfield data wont solve, in which case I would probably just go with the subdivide and attr paint like I am used to as opposed to heightfield.

Hope this makes sense.
Edited by mleff - Dec. 12, 2023 16:36:14
User Avatar
Member
12 posts
Joined: Jan. 2017
Offline
One way to work around some of the limitations is to create a vector height field to store the coresponding world position using the uvsample function. If you use that as input for your noise it will have no seams.
User Avatar
Member
7 posts
Joined: Dec. 2018
Offline
@RiotPixels, I tried setting that up based on what you mentioned above but I guess Im not fully understanding its use in the overall pipe. I think I got the wrangle working but was not sure what to do with it after that. Here is a screen shot of the wrangle and the hip file as well incase it helps.

Attachments:
texture-mask-paint-output-examples_v002.hipnc (2.3 MB)
uvsample.png (325.4 KB)

User Avatar
Member
442 posts
Joined: Aug. 2019
Offline
I don't think Heightfield Noise has this feature. The second input is mask.

You will need to use Volume Wrangle to specify the noise's position... but at this point just subdiv the mesh might be more convenient.
User Avatar
Member
93 posts
Joined: Dec. 2019
Offline
Hello @mleff,

You need to sample the 3D position of the geo having the uv attrib.

In the texture primitive/volume, the voxel position is the uv position of the input geo.

So in the uvsample function, you will need to sample the P attrib of the geo in it's uv space, using the position of the voxel (also called P in volume wrangle).

Here's a hip file with an example.

Attachments:
TexturePrimitiveSample3dNoise.hiplc (2.3 MB)
texturesample3dnoise.png (1.6 MB)

Houdini Pipeline Supervisor @ TAT Studio
User Avatar
Member
7 posts
Joined: Dec. 2018
Offline
@ObeidaZakzak that is wild. I really dont know much about volume manipulation so I'll have to dig in a bit and see what I can do with this workflow. I am not able to visualize that @mask data on any other node than a texture mask paint node. What would I need to set a visualizer to to see that volume data on the geo itself?

Attachments:
txtVis.gif (3.2 MB)

User Avatar
Member
442 posts
Joined: Aug. 2019
Offline
https://www.sidefx.com/docs/houdini/nodes/sop/volumevisualization.html [www.sidefx.com]

Texture Mask Paint is more like a special node, not an entire workflow. I feel you're a bit too indulged to what SideFX said in Keynote. No matter how much we like SideFX, Keynote is just commercial. Don't take their words in literal sense just like you don't take TV commercials that seriously.

They might say workflow but Texture Mask Paint is just a node. It's not an overhaul of how Houdini processes volumes. Texture Mask Paint is special, and how it shows / handles the painted texture is hidden deep down in an undocumented python module (_texturepaint).
Edited by raincole - Dec. 14, 2023 02:12:35
User Avatar
Member
93 posts
Joined: Dec. 2019
Offline
Indeed, you will not be able to visualize the mask data from the geometry, as the texture data lives inside a 2D volume, not inside the geo.

You can add another Texture Mask Paint after modifications on the texture volume and enter the node state to visualize what happend.

However, I was playing around to find another way to visualize this volume, I found a way by importing texture volume into COPs, then coloring it with a ramp and sending it to a principaled shader, and assigning this shader to the geometry.

For some reason, any modification to the texture volume doesn't show on the shader interactively, to see modifications you should undisplay then display the texture_mask_shade node, or trigger a change in the color ramp.

Here's a hip file to see how to do it.

Attachments:
texturemaskshade.png (2.4 MB)
TexturePrimitiveShade.hiplc (1.3 MB)

Houdini Pipeline Supervisor @ TAT Studio
User Avatar
Member
7 posts
Joined: Dec. 2018
Offline
Thanks for all the replies. I know demos are a a bit black box in their usage and yes, perhaps I got too hyped. All good.
Cheers
User Avatar
Member
9 posts
Joined: May 2017
Offline
Great thread mleff.
Thanks for all the sample files ObeidaZakzak, learned so much from them. Very kind of you to take the time to upload these files.

Btw I think (based on your latest setup)there's a simple workaround to be able to view modification to the texture, which is using UVquickshade node reading from cops.

Cheers.
User Avatar
Member
93 posts
Joined: Dec. 2019
Offline
Hello @FoamFX

Glad to help ^^

FoamFX
Btw I think (based on your latest setup)there's a simple workaround to be able to view modification to the texture, which is using UVquickshade node reading from cops.

Indeed, quickshade node gives feedback on texture modifications. Thanks for pointing this out !
Houdini Pipeline Supervisor @ TAT Studio
User Avatar
Member
20 posts
Joined: May 2023
Online
@ObeidaZakzak nice idea in hip hanks.

COPS does not update the viewport natively sadly. However there is a little hack to force it to update.

A COP network node by default creates a mesh. Its at the origin. This does update when you change colours etc.
If you merge your geo in with this COP when you change the color/ramps etc. It will update. Win.

Cavet, which node should COPS display? In this COPs is a bit like CHOPs. You need to set the export flag (brown one) to the node you wish to visualise.

Last little tip, I found that leaving the COP at the default Mesh is a bit slower, changing this to Volume slice makes the update faster. Now you can update colours Ramps etc and it will update in the viewport.

With COPs Heightfields and SOPs, there is the basic structure of a texturing system there already. It needs some dev love to make it more stable and faster but Ive been relatively impressed with what you can get out of it as is. You can find some of my experiments and hints and tips over here.

https://www.youtube.com/@3D_GO
  • Quick Links