Jump to content

Random Textures


RickWork

Recommended Posts

Hi guys,

This might be a trivial question but I don't seem to be getting my head around this one.

I have an .obj file that I imported from Maya, I used the CopySOP and made about 30 copies of this object. I would like to randomly assign shaders with texture maps to each of these copies.

Is there a clever way of doing so without loading every single texure into COPs or SHOPs via vex super material? Some fancy expression I need to read up on?

The way I have done this in the past in other applications like Maya/XSI is with a script that randomly imports the texture, builds the shader tree and finally assgins it to my selection of objects.

OR

In massive we create a varible called "head_map" with a value of 1-100. My textures are named head1.tex to head100.tex. In the shader I just use a simple expression for the file path. head[head_map].tex, and massive automatically assigns random texture to every instance of my head mesh.

Maybe we can do this setup already in houdini?

Cheers,

Rick

Link to comment
Share on other sites

You can vary the texturemap name per-primitive if you want to using a primitive string attribute on the geometry where the attribute name matches the map parameter name in your shader. Be careful, it must be a primitive attribute as opposed to a point attribute. (Point attributes are interpolated in the dicing phase when rendering, and of course there is no way to interpolate a string. So this might get a little heavy RAM-wise depending on your geometry resolution though. Having a long string for every primitive can be weighty.

Do you know about $OBJ in shops? $OBJ is replaced with the name of the object to which the shader is bound on the fly.

For example, you can have a single shadow shader assigned to many lights and you can put the following in the depth map field in the shadow shader to grab the unique map name from the light to which the shader is applied.

`chs("/obj/$OBJ/depthmap")`

Hope some of this helps,

Jason

Link to comment
Share on other sites

regarding random textures within a single object -- is it possible to select say 100 polygons and have a random 20% of them assigned a different shader to the rest? would a switch sop be the way to approach it? thats all i can think of.

Link to comment
Share on other sites

a question about the original post and Jason's solution... which i now need to do after edwards solution :)

i have a digital asset which includes reference to a shader, "window1". inside the window1 shader the texture file contains:

'chs("/obj/$OBJ/map1")'

i made a parameter for the DA called "map1", of type image file, which is populated with "default.pic".

whenever i render the DA the object with "window1" assigned is always white.

i think ive followed the logic but clearly something is wrong...

any ideas please?

i thought maybe the path should be different because the actual object is inside the digital asset, but the parameter is at the digital asset level, not inside (i.e. /obj/$OBJ/../map1).. but i tried that also i tried literal path but that didnt work either.

Link to comment
Share on other sites

  • 10 months later...

I found this topic and have more questions to it.

I seek for the ability to assign different textures to each primitive or each set of polygons sharing same attribute or a group of primitives.

I have an expression (thanks to Jason and sibarrick:the very thread) which returns random file from a specified directory:

string k_getfiles(string dir,float rand_base)
{
string files = run("uls -p" + $dir);
float nargs = argc(files);
float rand_file = round(fit(rand(rand_base),0,1,1,nargs));
string rand_name = arg(files,rand_file);
return dir+"/"+rand_name;
}

The random is based on a number so to return a per poly texture it would be ideal to use $PR:).

Unfortunately I can get no access to $PR or $PT from many places.

I have an attribute with different values for each prim, but still, to get to it I need to use prim expression which claims for $PT.

I tried to use eval(chsraw()) but with no luck.

Probably it is very easy and I have a mindblock on, but I'm pretty stuck with it.

Link to comment
Share on other sites

It sounds like you're going down the right path; (i haven't looked at the file attached) so I'll just guess that you're varying the texturemap name per primitive. So two things come to mind:

*/ make sure that the attribute is a Primitive attribute; not a point attribute. A primitive attribute doesn't vary across the face of the polygon, like the point attributes do. And how would you sensibly interpolate a string anyway?

*/ Make sure your attribute name matches the exact parameter name for the texturemap - (e.g. "map")

For example, in an AttribCreate SOP, make a primitive string attribute called "map":

butterfly`floor(rand($PR)*2.999)+1`.pic

...this will choose between butterfly1.pic, butterfly2.pic and butterfly3.pic randomly per primitive. Check it's doing it right in the Geometry Spreadsheet before rendering.

Link to comment
Share on other sites

I completely forgot about string attributes:)

Thank you very much, I now have random texture on a per poly basis.

Had some expression troubles but fixed them.

The correct version of the expression is :

string k_getfiles(string dir,float rand_base)
{
string files = run("uls -p" + dir);
float nargs = argc(files);
float rand_file = round(fit(rand(rand_base),0,1,0,nargs-1));
string rand_name = arg(files,rand_file);
return dir+"/"+rand_name;
}

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...