Jump to content

material id render


Recommended Posts

Hi all!

I've searched the forum today for quite some time (I think I remember seeing a post/example from Macha...) but was unable to find what I was looking for...

Anyway, what I want to be able to do is to render a pass (deep raster image) with a material/shader ID... what I've been doing before was apply by hand a constant shader with different colours to the different parts of an object. But this is not very practical ;)

So, I want to be able to do this: material_id.jpg

Any help or suggestions are welcomed!

Cheers!

Link to comment
Share on other sites

I would try creating a SHOP shader asset that took the full SHOP path to the shader that contains it, then generate a unique int32 ID from that path and write it out to a custom pass.

Sounds like a good idea for an xTool :)

Link to comment
Share on other sites

Can I make a LIKE already and get it? ;) ahaha...

I think I know what you're saying, now is a question of being able to do it or not... I know that there is a way for Houdini to give different values to objects on the scene that you can later on "filter" in Nuke... but I would really like to be able to use the different colours to do that!

I'll try tomorrow to see if I can do something like you suggested and will post my problems along the way!

Cheers Hop Bin!

Link to comment
Share on other sites

I haven't seen that yet... I'll try the suggestions tomorrow since today my Houdini decided to take some vacations of me... :(

But by HopBin9 statement I presume that is the render that gives you a white image but with different alpha values (far above 1) and then you clamp in Nuke or other comp app to get the object...

That I know, but thanks anyway! ;)

edit -> just saw the side effects post... I think it is the same method I used once... but no white image :huh: ... but you get the idea... you have to clamp/isolate an object instead of the shader...

Edited by J.Santos
Link to comment
Share on other sites

I'm not exactly sure how something like this will work. You can't output different solid colors for each material, because it will be very difficult to separate them (red and pink for example). You could just to RGB but that would limit you to 3 material IDs only.

Is it possible to do something like this, but also support aliasing around the edges of overlapping objects?

Edited by hopbin9
Link to comment
Share on other sites

Well... I'm no expert in Nuke but the thing is that you can always transform your colourspace to LAB (that's the "commom" example I saw being used) and then, you can use a clamp node with minimum and maximum values according to the value of that colour... this was done, in the mentioned example, on the Alpha channel of the object, because each colour will get a slightly different alpha value...

In the past, Like I mentioned before, I did this by hand and I used both approaches... one was only RGB colours and I ended up making 3 or 4 takes of the same subject... then is nodefest in Nuke to manage all 12 different masks...

I also did the opposite, just one pass all with different colours, but I didn't knew the LAB - alpha - clamp trick so I ended up using keyers and a bit of masking to get the correct alhpa out...

By aliasing around the edges I supposed you're saying that the edge shouldn't "bleed" into the overlapping object? I have no idea, but maybe that can be achieved...

Link to comment
Share on other sites

Just found 2 different approaches at sideFx forum...

In this linkyou create an attribute called id (vector attrb), assign it a value and than you use that value on the shader level to export a parameter called ID...

It is a way, but it makes you have to create an extra attribute per object (or group, I suppose, if you want to make it per different shader... you would have to create groups to assign different shaders, anyway...) and then export it as a deep raster.

The second approach (sorry, can't seem to find the link...) is a variation of the above... in this case you don't create an extra attribute, you just create an extra parameter at the shader level called id and you promote it so you can later on colour it and render it out... seems faster since it cuts one step of the process, but again, you'll need to "run around" your shaders, creating this extra parameter and then at an upper level you'll have to manually attribute a different colour to every one...

Back in Max days, this would be handled by using a simple button to attribute an unique ID to each shader and then you would just render out... maybe something like this can be achieved... an Uber ID that could be feed into each shader and randomly (assuming that colours aren't important/don't need to be RGB) assign a colour value!

I-ll keep looking and will test out ideas...

Link to comment
Share on other sites

I worked on this for a while yesterday, but struggled to get it to work. My idea was to have an asset that would convert the top level parent's name into a unique ID, because I thought all shader names are unique (for a given network).

It didn't work out very well. I'm still giving this some thought as to what the best approach should be.

Link to comment
Share on other sites

untested... but this should return a unique color based on object name

def randomColorId (object):
    objectHue = hash(object.name())%360
    r = hou.hscriptExpression("rgb("+objectHue+", 1, 1, 'r')")
    g = hou.hscriptExpression("rgb("+objectHue+", 1, 1, 'g')")
    b = hou.hscriptExpression("rgb("+objectHue+", 1, 1, 'b')")
    return hou.Color([r,g,b])

Edited by AdamJ
Link to comment
Share on other sites

Both object ID and material name are available during rendering in VEX:

int id;
string mat;
float sx, sy;
vector rgb;
renderstate("object:id", id);
renderstate("object:surface", mat);

you could generate random hue from them, straight with id:

id = random(id*100.123);
rgb = hsvtorgb(id, 1, 1);

or by converting material name into a float. This is little exhausting, as I don't have any ideas other than computing hash with characters array or extending VEX with UT_Spline.hash().

You could even make random colors stratified, although I haven't found it much useful.

nexesample(id, sx, sy, "mode", "qstart");
rgb = hsvtorgb(sx, sy, 1);

It can be saved as a Fog Shader with a "rgb" AOV export, so you don't have to modify any materials, but add Atmosphere shader to the scene to export material id pass.

Finally you may find it's actually better to generate the set of nice random-stratified colors, save it in a header as vectors array[] and peak up from there with id.

  • Like 1
Link to comment
Share on other sites

All good suggestions, but I think the problem is not so much how to generate a "unique color" (however that's defined) per material, but how to decompose the result after the fact.

Here's some interesting reading[1] on this topic (and much more).

He uses principal component analysis (PCA) in various color spaces (finally landing in Lab/Luv IIRC), along with some "fuzzy" algebra to get very impressive results. But, you know, not exactly "simple" this.

The obvious problem scenario that springs to mind is: What happens when one of your materials is semi-transparent/translucent? And what if it *is* translucent and 15 other materials are partially showing through it? Can you recover any one of them from the resulting color soup?

[1] Arash Abadpour, Master Thesis, COLOR IMAGE PROCESSING USING PRINCIPAL COMPONENT ANALYSIS, 2005

Link to comment
Share on other sites

Hi guys!

AdamJ -> I'll try to check it as soon as possible! Thanks for your time and suggestion!

SYmek -> ah.... I understand the code but... I never did any VEX so I have no idea where and how to use it :( But thanks for your time!

Mario -> That's a big paper... ;) About your points, they are all very good but kind of solvable! (even if by a gimmick ...) First, the translucent material (or semi-translucent), as far as I can remember, in Max it was treated like any other material, so it would get a constant colour. Because, in the end, what you want is a usable mask so you can isolate it in a Post Processing application and then grade/apply effect/whatever with a BIG degree of freedom!

About the shapes behind a translucent material... this is a problem but... you can solve it using takes (i know I know... this is to be by hand but...) and making the object (translucent) non-renderable... I don't know if this can be done, for example, in the same object, saying that the group with material X is not to be rendered... but any way, you could probably use a Visibility SOP or something.

Thanks for all your ideas so far! I'll start testing them all next week, that's a promise (I'm stuck at some cloudy stuff...)

Link to comment
Share on other sites

J.Santos I work at an archviz company and wile i'm more of an animator/previz guy i'm quite sure we don't use max's MatID or ObjectIDS for anything other that stills, we use VrayOBJ_IDS and in other cases some custom masks. VrayOBJ_ids separates in simple RGB using the correct renderer antialiasing, and makes-it simple to separate the objects, by channel, even at the blured edges. We just use for example, one rgb image plane for 3 diferent trees, another for the cars, 3d char and props, and so on. The time you gain not having to select by color but simply separating the channel makes up for the extra disk space and the negligible if any render time hit.

Plus, i'd have to ask the compositor but I think it's plain impossible to separate the object using max matids in animated sequences, because of the antialiasing and the odd colours at the edges if you have lets say a purple object over a yelow one

Link to comment
Share on other sites

Obrigado David pela explicação e pela questão da animação!

Translated (and extended version ;) )

Thanks David for the explanation and for mentioning the animation question... What I did in the past was exactly that... 3 colours (RGB) for 3 objects or 3 different shaders, then rinse and repeat... that solution I know it works, even in animated sequences... and, of course, that one generates a lot more files and extra nodes/layers at comp... however, better safe than sorry, so I might follow that path!

Anyway, I'll plan to start sometime this week some render tests and if something arises I'll post back!

Cheers!

Link to comment
Share on other sites

  • 4 weeks later...

hello

I have a similar problem

did you know how to get the material ID from the loaded geometry?

in my case it is necessary to get the ID from the file created in 3ds max, parts of which have different IDs for different textures

in VEX Builder I found "Get Primitive ID" node, but it gives not the same value of the ID that was in 3ds max, unless of course it gives that same ID...

thanks

Link to comment
Share on other sites

  • 1 year later...

Both object ID and material name are available during rendering in VEX:

 

int id;
string mat;
float sx, sy;
vector rgb;
renderstate("object:id", id);
renderstate("object:surface", mat);
you could generate random hue from them, straight with id:

id = random(id*100.123);
rgb = hsvtorgb(id, 1, 1);
or by converting material name into a float. This is little exhausting, as I don't have any ideas other than computing hash with characters array or extending VEX with UT_Spline.hash().

You could even make random colors stratified, although I haven't found it much useful.

nexesample(id, sx, sy, "mode", "qstart");
rgb = hsvtorgb(sx, sy, 1);
It can be saved as a Fog Shader with a "rgb" AOV export, so you don't have to modify any materials, but add Atmosphere shader to the scene to export material id pass.

Finally you may find it's actually better to generate the set of nice random-stratified colors, save it in a header as vectors array[] and peak up from there with id.

 

 

 

works like a charm! I;m using the first example you posted, using renderstate().

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...