Hello everyone,
I’ve been going through the tutorials and learned how to randomize the texture of a single-texture material. However, I’m wondering if there’s a way to randomize multiple parameters like metallic, roughness, and diffuseColor for an already existing UsdPreviewSurface shading in the scene. Specifically, I’m interested in providing a list of paths for various roughness texture files, as well as for Metallic and diffuseColor.
If this is possible, could someone kindly guide me on how to do it? On the other hand, if it’s not feasible, I’d appreciate any suggestions on how to efficiently achieve randomization, without having to creating multiple materials, as binding them to the mesh is resource-intensive.
Lastly, I’m curious if using UsdPreviewSurface is the recommended approach to start with. I’m utilizing Substance Painter to generate materials with intricate details, and unfortunately, the results can’t be procedural.
Thank you all in advance for your assistance!
Hi @romichel2003 There’s two things here:
Firstly, using a single material, applied to many prims, with each prim material showing different things, such as color. This can be achieved with a custom primvar on the target mesh, and inside a custom material, you can access the primvar within the material graph.
Take a look at the scratches example on our github here:
Specifically:
with cubes:
rep.modify.attribute(
"primvars:random_color",
rep.distribution.uniform((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)),
attribute_type="float3",
)
Note that as of right now, only float, float3 values and the like can be used in the material graph, not asset paths like textures.
You can alter a material directly, for things like the textures. Here’s a randomizer that randomizes texture paths and assigns it to the texture attribute on the shader in the material:
prim_path = "/World/Looks/MyMaterial/texture_2d_const_02"
src_directory = "C:\YourTextures"
textures = glob.glob(src_directory + '/*.png')
def alter_attribute():
material = rep.get.prims(path_pattern = prim_path)
with material:
choice = rep.distribution.choice(textures)
rep.modify.attribute("inputs:tex", choice)
return material.node
rep.randomizer.register(alter_attribute)
1 Like
Hi @pcallender
Sorry it seems that I never replied to this message.
Thanks for you answer. I really needed to use texture files because substance painter was the only way to reach a certain level of detail.
The complexity is that I have a 4 maps (color, metallic, roughness, normal) per textures.
And the randomization needed to ensure that at each iteration, the maps used belong to the same textures, e.g. (color_file1, metallic_file1, roughness_file1, normal_file1), then (color_file4, metallic_file4, roughness_file4, normal_file4,), etc. I used the same random seed to achieve that. Something like
seed = 20
#randomize the textures
rep.modify.attribute(
"inputs:file",
rep.distribution.choice(color_files, seed=seed),
attribute_type="asset",
input_prims = color_shaders
)
rep.modify.attribute(
"inputs:file",
rep.distribution.choice(metallic_files, seed=seed),
attribute_type="asset",
input_prims = metallic_shaders
)
rep.modify.attribute(
"inputs:file",
rep.distribution.choice(roughness_files, seed=seed),
attribute_type="asset",
input_prims = roughness_shaders
)
rep.modify.attribute(
"inputs:file",
rep.distribution.choice(normal_files, seed=seed),
attribute_type="asset",
input_prims = normal_shaders
)
It worked, but may be there is a more efficient solution that exists
Best regards