View Full Version : RSL - separated passes for 3 types of Z-depth

12 December 2011, 09:07 PM
While rendering with Mental Ray I've been using puppet's shader pack called shaders_p ( .
Now, I'm trying to become renderman user, so I need to write my own universal shader.
What was great in puppet's shader pack is that it has an awesome feature - ability to output a pass with 3 separated z-Depth channels ( One for directly visible objects, one for objects in reflections and one for objects in refractions.

How can I implement the same thing in RSL?

1. Calculate the length of a ray from back side of object with refractions to the objects visible in this refractions.
2. The same thing with reflections. Calculate the length of a ray from the point where some object is reflected to the point which is reflected.
3. Multiply primary Z channel with transparency so that transparent areas of an object won't affect color of something that's behind it. Like it's shown here (
4. Also, is there a way to measure the length of a ray inside refracting object? It would be nice to be able to create kind of volumetric coloring inside dielectrics without actually using volume shader.

01 January 2012, 03:46 AM
check out gather

It lets you message pass output variables from surfaces hit by a ray. Eg, you can return ST/P/N from a surface hit by a ray, and you could probably return ray length. Might be handy.

01 January 2012, 12:37 PM
Thank you a lot.
Looks like gather construct with "ray:length" parameter (in "illuminance" category) could help.

But there are still a few things I can't understand:
After "gather" construct itself, there's code block (and probably one more code block after "else" keyword). What is it for and when does it get executed?
It's not clear how to get a ray length for Nth ray trace. For example, to get "reflection z-depth", we need to measure the length of a ray outgoing from 1st trace point (after it hit 1st reflecting surface and been reflected)to next hit.
The same thing with ray tracing type. The only solution I see for this and previous problem is to reflect/refract a ray manually to get a ray of Nth trace. Is there more elegant solution?
I still don't get how to create primary depth channel with transparency. So that objects behind transparent and semi-transparent areas of current surface contribute into the Z-depth channel.

It would be awesome if you make this clear, too.
But anyway, thank you for help you already provided.

01 January 2012, 02:35 AM
1. The code block is executed for each ray

Have you done much rsl coding?

Btw, how useful is the pass? What effect are you trying to get in comp?

01 January 2012, 11:21 AM
1. The code block is executed for each ray
Em... And in which case "else" block is executed? Still don't get the purpose of these two blocks. Why don't we simply execute some code after "gather" construct? We can then use any if/else statements we want.
Have you done much rsl coding?
No, I'm just learning to. That's why my questions may look so "lamer-like". I usually learn something by reading it's official docs. But in official docs for RSL there's not enough info about some language constructs, like gather.
When I was learning MEL there was no questions because everything ( was explained clear enough and each language construct has detailed description ( of it's purpose, usage and the way of functioning.
Btw, how useful is the pass? What effect are you trying to get in comp?
All three passes are extremely useful.
Separated z-depth pass allows to create fake fog which will look much more realistic because of it's presence in reflections and refractions, too.
And though you get only z-depth for 1st level of reflections/refractions it's not noticeable because higher levels just don't bring too much to the picture.
simple z-depth with object transparency pass is just much more natural then default z-depth. Because, obviously, if you have a transparent area of an object then it shouldn't block anything behind it.
You normally use either z-depth with transparency or refracted component of separated z-depth. Because they both do the same thing: allows you to get z-depth for objects that are visible behind the current object.
ray length inside refracting objects pass allows to modify light absorption in compose. Puppet's shader pack didn't have this pass, but that's what I've been wanted for a long time. And since now I'm writing my own shader it's good time to add it.

I know that I'm asking too much. But I just don't know where else I can get this info since even in official docs it isn't explained clear enough.

P.S.: when I say "pass" I mean AOV, of course.
P.P.S.: sorry for my english if it's bad. It's not my native language.

01 January 2012, 10:43 AM
More specifically the gather() operator is a loop which calls the code block for each ray hit. the else block is for each ray miss. If you are using it for reflections, the else block is where you would look up an environment map when you miss geometry.

Also when you are counting shot rays you need to count them in both blocks! (especially if the renderer uses adaptive sampling, so the number of samples you specify may not be the same as the number of times gather is actually called).

Note that renderman doesn't differentiate reflective and refractive rays so you would need to do this yourself by setting the gather "label" parameter then querying it using rayinfo("label"). This is also how you find out what type of ray it is using rayinfo("type") (camera, diffuse, specular, transmission). You can also use rayinfo("depth") to get the trace depth.

It's probably worth having opacity multiplied and non-multiplied passes - both have their uses.


01 January 2012, 11:45 AM
Thank you very much.
You really explained everything I was confused with. :thumbsup:
Thanks to you I can now continue my RSL learning and shader writing.

CGTalk Moderation
01 January 2012, 11:45 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.