# Surface-Based Depth Map in Shader Mixer

Posts: 3,513
edited April 2013

Since the current depth-related stuff in Shader Mixer is camera-only, here's a snippet of code as a custom brick which allows a surface-based depth shader. Maps the scene from white (close) to black (far) based on min and max variables.

ShareCG link including custom bricks for the depth map functionality itself and the basic raw 'distance between viewer and surface', plus images and a Shader Mixer file so the internal nodes can be poked through more easily for those who have the inclination to do so (ungrouping the brick unfortunately messes up the arrangement).

The bricks in the network have been retitled to make their function more understandable. The following post explains what's going on.

(Yes, I know the preview image is godawful ugly.)

Post edited by agent unawares on

• Posts: 3,513
edited December 1969

First set of components: Two Variable [Fixed], one set to E (this gives the position of the viewer) and the other set to P (this gives the position of the surface). Plug both of them into a Distance brick, and it gives you something that will spit out the distances between points on an object, and the viewer. I personally grouped this and saved it as a custom “Eye to Point Distance” brick so I could work with it more easily later.

Now, what that gives you isn’t usable straight out of the box. To be usable and intuitive, values should stretch from 0 to 1, as that’s basically from pure black to pure white. Anything else clips. If it was only being used for a pure math calculation, that might be fine. However, if you want to use it later to render a depth mask, you’re SOL. Besides, having values range from 0 to 1 makes them far more intuitive for further calculations.

So we’ll fix that. Add a Binary Operation brick, change the title to “Move to Scene Min,” and connect the Eye to Point Distance output to the first input. Add a Value brick, name its variable slider “Minimum Distance” and connect the output to the second input. Change the operation to “Subtract.” This will allow you to dial down the values of Eye to Point Distance all by the same amount, so you can set the position where pure black starts (yes, pure black, it’s in reverse at the moment, don’t worry about it for now) at the closest surface to to the camera.

Still unusable, of course. It goes way past pure white almost instantly. That’s what we fix next. In order to do that, we need to scale the current output by the visible scene size. Mathematically, this works out to maxdistance-mindistance, to take the camera position out of the equation. So add another Value brick and name its variable Maximum Distance. Add another Binary Operation brick and change the title to “Scene Size.” Plug the output of Maximum Distance into the first input of Scene Size. Plug the output of Minimum Distance into the second input. Change the operation to Subtract. That will give you a flat numeric value for the visible scene size, once the distance variables are set properly.

Now, we need to use that to scale the distance output properly. So add another Binary Operations brick and change the title to “Scale to Scene Size.” Plug the output of Move to Scene Min into the first input. Plug the output of Scene Size into the second input.Change the operation to Divide. This will scale all the values appropriately, so pure white (yep, still backwards) will be at the far side of the scene once the Distance variables are set correctly.

Now, we don’t really want a backwards depth shader. It’s “technically” accurate. Black is mapped to the closest distance, the closest distance is the smallest distance, and black represents zero. But for a intuitive shader, we want the closest part of the scene to be white, the closer to us the more “important.” It makes using the output to scale effects simpler. You can stop here if you like. However, I added one more Binary Operations brick, changed the title to “Invert,” changed the first value to 1, set it to hidden (not locked, never ever locked, this can cause fun, fun problems depending on the situation), plugged the output of Scale to Scene Size into the second input, and changed the operation to Subtract. This inverts the shader values so they run from high (close) to low (far).

The best thing about this is, since it’s based on the surface, it can be mapped with transparency. You have to mess with ray depth and such to get those camera shaders to work with it - they might be simpler at face value, but this will give you surface by surface control.

• Posts: 3,513
edited April 2013

Now, can anyone tell me why it is that the opacity of the Surface root itself doesn't work right with transparency? Even with a completely black image plugged into the opacity input, the surface is only partially transparent. Is that a bug?

Post edited by agent unawares on
• Posts: 260
edited December 1969

Now, can anyone tell me why it is that the opacity of the Surface root itself doesn't work right with transparency? Even with a completely black image plugged into the opacity input, the surface is only partially transparent. Is that a bug?

Just a guess: Sounds like you forgot to (pre-)multiply the color with the opacity. Technically it is not wrong, but it will look strange in the render (the color will be added to whatever is behind it). The Default Material Node contains the multiplication internally, but when using the Surface root node directly, you will have to do it yourself.
• Posts: 3,513
edited December 1969

Wow, that's strange. I'd never have guessed. Thanks very much for the explanation. That's been bugging me for pretty much all of the shaders I've been playing with, and most of them I'd rather not go through the DAZ Default Material, which was the only way I found to fix it so far.

• Posts: 815
edited December 1969

Thank you Millighost. That was a rather perplexing issue that was bugging me as well.

• Posts: 42,684
edited December 1969

The tinting effect came up a few weeks back and I opened a bug reprot on it, one of the devs told me the same as millighost posted above so that is the official answer.