I'm trying to create a shader that displays the normalized (0 to 1) camera Z-dpeth on top of the viewed object.

Yeah, I know I can easily do this in post with the normalize node if I render out the z depth pass, but I prefer to have this in a shader.

I tried to do this with an OSL script using the clamp function but it didn't really do what I wanted. See image below for clarification: Normalized Z Depth

You can see the desired result on the right (achieved with compositor nodes), and the existing result on the left (with shader nodes).

This is the OSL script that didn't quite get me where I wanted, but might be a good start (I intended to use it between the camera data and emission nodes, the same way I use the normalize node in the compositor):

shader normalize_value(
    float inputValue = 0.0,
    output float normalizedValue = 0.0
    normalizedValue = clamp(inputValue, 0, 1);

I'm of course open to any other method, for instance involving other shader nodes (I couldn't find a way to get the same result but hey who knows!).

  • $\begingroup$ Normalize and Clamp are different meanings to me. Have you tried to scale/multiple by a float number such as (.5)? When you examine the failed image (RGB Values) do you see subtle color variation or a single color? If you see variation then you can perform math ops to transform those values to be more detectable by humans. If you see no variation then may the clamped values come into the function at one extreme of the clamped range. Are you sure your clamp result is a floating point value? $\endgroup$ – atomicbezierslinger Sep 9 '15 at 16:11
  • $\begingroup$ OSL has normalize function, that either gets and returns vector, but it won't provide you with the same result as to what I tried (it'll be the same, without changes). So maybe there lacks something besides Normalize in this case $\endgroup$ – Mr Zak Sep 10 '15 at 13:00
  • $\begingroup$ I couldn't seem to get anywhere with OSL, even when I used a normalization algorithm of my own that takes the min and max values into account. Not sure why, but since the script above is my first OSL script, I probably just don't know what I'm doing... If only the normalize node from the compositor was ported into the shader nodes, that would have been really nice... $\endgroup$ – TLousky Sep 10 '15 at 13:02

If it's ok to put in some values manually, you can use a Cycles shader like this. You have to know the distance of your scene from the camera and the scene size along camera z. In this example the object starts 3 units away from the camera and has a size along camera z of 2 units.

Input the values into the two red value nodes.

enter image description here

| improve this answer | |
  • $\begingroup$ That's an interesting solution, I'll check it out and update here, thanks! I don't mind using "manual" values because I generate this shader dynamically in a script for every object, so it can use the correct values for the scene and object ever time. $\endgroup$ – TLousky Sep 9 '15 at 18:07
  • $\begingroup$ By the way there's an invert node under Color --> Invert :) $\endgroup$ – TLousky Sep 9 '15 at 18:10
  • 1
    $\begingroup$ But that's for a color triple. I prefer to use this math node for single values, as it directly maps [0...1] to [1...0]. Feels somehow cleaner to me :) $\endgroup$ – Sanne Sep 9 '15 at 18:12
  • $\begingroup$ OK that's close, but not quite it... I still need to tweak the values arbitrarily to get a result that better resembles the normalized image... $\endgroup$ – TLousky Sep 9 '15 at 18:55
  • 1
    $\begingroup$ I see the difference. Your setup is not entirely correct, though. The distance from the camera to the start of the model is about 6.72 instead of 7.27. The driver calculates the distance to Suzanne's object center, which is a bit behind the start of the geometry. But even with 6.72 as distance there's still a little difference to the compositor output. Why that is I don't know. Maybe somehow related to color space (linear vs sRGB). Just an idea, though. $\endgroup$ – Sanne Sep 9 '15 at 20:36

Try to scale (multiply) the values first followed by other math operations.

(original - min)/(max - min)

I am investigating clamping numbers to the same type ... float values clamp(inputValue, 0.0, 1.0);

Guessing example. For example ... (original * (.5)) + offset ..... Then clamp.

| improve this answer | |
  • $\begingroup$ Thanks. I did try various math operations, but I actually do want to normalize the output. I.e. map each value in the original z depth image (which is a low contrast image but not a single value) into a float between 0-1, depending on its relative value to the min and max values of the original image. $\endgroup$ – TLousky Sep 9 '15 at 17:04
  • $\begingroup$ Do you know the min and max values? Does some mechanism provide them? $\endgroup$ – atomicbezierslinger Sep 9 '15 at 17:06
  • $\begingroup$ do you think you could add more detail, maybe a few screenshots to this post? thanks- $\endgroup$ – Scalia Sep 9 '15 at 17:07
  • $\begingroup$ Might be math operations that get them from the image, will check when I get home. $\endgroup$ – TLousky Sep 9 '15 at 17:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.