GrabDuck

Label/Tag & Coverage passes – LabelExtractor | Sigillarium

:


This is an old article from the end of 2006. It’s partially outdated, but still contains interesting info. More than that, there’re a lot of links to it from other places, so, since I’m closing the site it was on ’till today, I’ve decided to add it as a backdated post here.


Chapter I. Basic methods of getting color masks
Chapter II. Basic methods of color masks usage
Chapter III. Label/tag & coverage passes in mentalray
Chapter IV. Usage of Label/tag & coverage passes
Chapter V. Macro LabelExtractor

– Download macro LabelExtractor –


Chapter I. Basic methods of getting color masks

A wish to correct an image rendered in 3D package without rerendering – in compositing application – is pretty often. Slightly change the color, blur shadows, intensify specularity and all that stuff. But if you need to do this for a speciefic object – it usually evolves into rotoscoping or mask painting. And if you need to correct all metallic elements in the scene or a character’s clothes? And if it’s animation – a car drives along tricky trajectory, character’s clothes deform and swing? Rotoscoping becomes a pain in the ass.

Well, for this purpose there’s old method – assign plain colors to your objects (or groups of objects by some kind of criteria) and you’ll get a rendered image with simple color regions, representing accurately objects (or groups of objects) in you scene. Then in the compositing software you can extract just the region you need and use it as a mask for further operations. For animation you’ll get a whole sequence of accurate masks. Obviously, this reduces time and work greatly.

This could be accomplished pretty simply – just assign special shader, that isn’t affected by illumination, shadows and other scene elements. In Maya the most obvious choice is Surface Shader.

There’re other ways to get the same result:

Simple black Lambert with colored Incandescence (and any other blinn, phong, anisotropic and others with the same settings):

The same thing with mentalray shaders – with standard shaders:

…or surfaceShader-like mentalray analog – constant shader (in this case – p_constant from p_shaders package):

For example, we decided to make all cubes red, all spheres blue and all toruses green:

Ready for rendering. But that way after each beauty render of the scene itself we need to render it once more to get masks pass. Though these shaders do render pretty quick, but there’s a natural desire to set up a scene, press render and get everything altogether. For this you can use special shaders for mentalray that while rendering the scene just once are able to write framebuffer’s in separate files – p_megaTk from p_shaders package or ctrl_buffers:

Anyway, we’ve got the same result – colored regions with anti-aliasing.


Chapter II. Basic methods of color masks usage

Since masks are ready, we need to figure out how to use them.

In the most cases we deal with RGB images. Obviously, it’s better to use these three colors for masks – that way their separation would be the easiest:

But three masks are often not enough – to get more, we need to render another rgb pass or to add secondary colors – CMY. Separation becomes somewhat more complicated and anti-aliasing – rougher, but now we have up to 6 masks (all nodes in the lower row are ColorX with following expressions in alpha channels):

Now, using extracted regions, we can handle necessary corrections of rendered image in compositing application.


Chapter III. Label/tag & coverage passes in mentalray

There’s two passes specially for this purpose in mentalray – label/tag & coverage. First one assigns a constant color to the object based on the value of a specific custom attribute – miLabel. Second one – separately stores anti-aliasing data, but only in those contours, where objects with different miLabel values occlude (or when object occludes emptiness). That means if two objects with the same miLabel value occludes one another – coverage doesn’t write aa-data in this place.

The technique in this case is like this:

1) create integer attribute miLabel for transform-node or for shape-node of the object:

2) set the value – from 1 to infinity (or almost infinity :)) as you need – objects with the same values will form a group

3) if you want to read attribute from shape-node – enable Pass Custom Label in mentalray globals. If from transform-node – it should be disabled:

4) and create passes for label/tag & coverage in the attributes of camera you’ll render your scene through:

Actually, it’s supposed that you render label/tag pass in ‘mentalray Tag (tt)’ format, and coverage – in ‘mentalray Alpha (st)’. But for some reasons accurately these two formats aren’t supported by Shake. But if you set another one – mentalray will try to adapt it’s data for channels of this format. For Shake the best ones I’ve found – iff (for label/tag) and zt (for coverage) – during the rendering there will be a warning, but everything will be ok as the result. Then you need only to plug your zt in reorder (code zzzz0, for example) and to use it.

As I’ve already said, any value for miLabel will do. But it’s just more convenient to start from 1 and move incrementely. If there’re a lot of objects in the scene and you don’t want to prepare each one by hand, you can use this script (source it and just use one of two precedures – script will create miLabel with increment values for each object):

//-----------------------------------------------------------------------------
//miLABEL ALL SHAPES

global proc sag_tagShapes() {

select -cl;
select -adn;
int $i=1;
string $objShapes[] = `ls -sl -type geometryShape`;

for ($curObjShape in $objShapes) {
	string $objType = `objectType $curObjShape`;

	if ($objType == "mesh" || $objType == "nurbsSurface" ||
							$objType == "subdiv") {
		addAttr -ln miLabel -at long -k 1 $curObjShape;
		setAttr ($curObjShape+".miLabel") $i;
		$i++;
	}
}
}

//-----------------------------------------------------------------------------
//miLABEL ALL TRANSFORMS

global proc sag_tagTransforms() {

select -cl;
select -adn;
int $i=1;
string $objShapes[] = `ls -sl -type geometryShape`;

for ($curObjShape in $objShapes) {
	string $objType = `objectType $curObjShape`;

	if ($objType == "mesh" || $objType == "nurbsSurface" ||
							$objType == "subdiv") {
		string $curObjParent = `firstParentOf($curObjShape)`;
		addAttr -ln miLabel -at long -k 1 $curObjParent;
		setAttr ($curObjParent+".miLabel") $i;
		$i++;
	}
}
}
//-----------------------------------------------------------------------------

If you use mentalray standalone, you can render label/tag & coverage (and all native mentalray passes) much more easily with m2mr script.


Chapter IV. Usage of Label/tag & coverage passes

For example here’s a frame from my recent project. That’s a beauty pass right out of the render.

Corresponding label/tag pass where I grouped under same labels similar objects (in the end I had about 30 different colors):

and coverage pass with anti-aliasing data:

Now I can change things for specific objects (of course I can modify not only beauty pass, but anything – specularity of bottles, for example, masking 32-bit specular pass). But we need to extract only specific color regions. It could be done via different keying tools or via ColorX with an expression, that sends pixels of specified color into alpha channel. For example:

floor(r*256)==64&&floor(g*256)==0&&floor(b*256)==128?1:0

It’ll extract all blue bowls on the table (by default values of channels aren’t very clean, so I’m making a conversion in familiar 8-bit values and round down each channel – floor(r*256) and so on) Now we need only to crop our mask with coverage (for example, Inside or IMult) and we can use it.

This is the final composite (well, not of the frame shown above, but very similar anyway :)) – using these methods I blured shadows, made a slight tint to apples, something like DOF for a back wall, separation of the flower bud for RBlur and a number of other things (that I just don’t remember already).


Chapter V. Macro LabelExtractor

Well, after explaining all these things, I can describe the usage of my macro LabelExtractor at last 🙂 It simplifies the process of separation of color regions mentioned above. And gives the ability to extract them by numbers, specified in miLabel attribute in Maya.

It could be done in one of two ways – by this label number (corresponding to miLabel in Maya) or by just clicking on the actual region in the viewer.

If useColor is active – calculations use color of pickColor. If it’s inactive (by default) – labelNum is used.

If you want to click in the viewer – activate useColor, click on pickColor swatch (yellow border should appear) and click on the region you want to extract – you’ll get it separated into labelExtractor’s alpha channel.

I had a list of objects’ labels in Maya, consistent through several shots. So I just entered them into labelNum and didn’t bother about clicking 🙂 That’s why labelNum is default method. The problem is – I couldn’t figure out a universal formula which mentalray uses to convert miLabel integer value into fixed color values – I’ve made only limited to 1-63 label numbers expression. Anyway, ’till now I had maximum of 30-35 labels in one scene, so that’s not a big problem really. pickColor works with any label numbers – no limits.

Test files are included in the archive:

– Download macro LabelExtractor –