Houdini 20 new texture mask paint node limitations?
4697 18 4- mleff
- 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
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
- raincole
- Member
- 539 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.
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.
- michaelb_
- 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.
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.
- ObeidaZakzak
- Member
- 123 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).
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
Houdini Pipeline Supervisor @ TAT Studio
- mleff
- Member
- 7 posts
- Joined: Dec. 2018
- Offline
- mleff
- 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.
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
- raincole
- Member
- 539 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
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
- mleff
- 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.
"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
- RiotPixels
- Member
- 12 posts
- Joined: Jan. 2017
- Offline
- mleff
- Member
- 7 posts
- Joined: Dec. 2018
- Offline
- raincole
- Member
- 539 posts
- Joined: Aug. 2019
- Offline
- ObeidaZakzak
- Member
- 123 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.
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.
Houdini Pipeline Supervisor @ TAT Studio
- mleff
- 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?
- raincole
- Member
- 539 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).
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
- ObeidaZakzak
- Member
- 123 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.
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.
Houdini Pipeline Supervisor @ TAT Studio
- mleff
- Member
- 7 posts
- Joined: Dec. 2018
- Offline
- FoamFX
- Member
- 10 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.
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.
- ObeidaZakzak
- Member
- 123 posts
- Joined: Dec. 2019
- Offline
Hello @FoamFX
Glad to help ^^
Indeed, quickshade node gives feedback on texture modifications. Thanks for pointing this out !
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
- ctrl
- Member
- 68 posts
- Joined: May 2023
- Offline
@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
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