propery way to set up camera distance based bump/normal effect

Hi,

system: Windows 10, Maya 2018.2, V-Ray v4.03.02.28351

I try to set up normal (tangent space) effect based on how far the character is from the camera so the bump mult is higher when he is far away from camera and lower when he is closer to camera.

Found a couple approaches online and I go with this one (seem most straighforward). With connection below, I am able to see bump mult goes up/down as I move camera away/toward the character.
But when trying to render, it shows a warning // Warning: line 1: V-Ray : TexDistanceToObject: object: incompatible object (requires EXT_WORLD_MATRIX)
And the bump effect is as if the Bump Mult is set way too high.

Do I miss something or is there a more V-Ray native way to set this up?

Thanks!

Use the VRayFalloff node with Falloff Type set to “Distance Blend” and Falloff Direction set to “Viewing Direction (Camera Z-Axis)”. You can tweak the distances under the Mode specific parameters rollout.

Thanks dgruwier, I was actually looking into this on DOCs page but wasn’t sure which slot of the VRayFalloff I should plug the bump map to and where I should feed the render camera world position info. Do you happen to come across any examples on Internet to showcase this setup?

That could be a bit tricky, depending on whether you need this setup to work for a single object or for multiple objects. I.e. do you want to use the same shader setup on multiple objects where each would have a different bump mult based on each object’s distance from the camera… or you just want one object to change it’s bump mult based on how far from the camera it gets? I somehow have the feeling it would be the first one.

Should be as simple as just plugging the VRayFalloff node into the bump multiplier, and your bump/normal map where it normally goes. That will multiply the the bump by the distance from the camera to the surface of the shader, making it the stronger/weaker as your object moves away from it.

Good tip dgruwier!

@yolov it’s the first one. :slight_smile: When it’s a medium shot, Bump Mult can be 1 for all parts of the character; whereas for close-up shots, ex. Bump Mult for the head is 0.1, but a different amount for other parts of the character. Ideally, I hope the setup can be adaptive so I don’t need to re-connect lots of nodes for multiple shaders if I switch render camera.

@dgruwier I’ve tried directly drag and drop VRayFalloff to Bump Mult of a VRayMtl. Also tried other options, but none of them gives me the result where I see Bump Mult value changed based on how close/far the camera is (It stays at a constant value). Do I miss something?


​​​​​​​


Hmm, I don’t spot anything wrong, by all means that looks like it should work. I just tested it, and it works fine here. I’d guess that the Near and Far Distances are off… Maybe they’re too far apart for the difference to be noticeable, or your object is closer than 16 or further away than 50.

EDIT: on second thought, are you talking about seeing the bump multiplier change in the Maya interface? Because VRayFalloff is a render-time effect, and it’s per-pixel, it doesn’t output a value to the Maya interface, it just shows “0”.
If you want to preview the values, you can add the VRayFalloff node to an Extra Tex render element, which will show you the exact values that VRay is going to read from the VRayFalloff node for each pixel. You can also add a BumpNormals render element to better see the bump directly. I’d suggest dialing in the values while rendering in the IPR to preview the results.

As for making the effect stronger or weaker on a per-object basis, you can use a User Attribute for that. Use a multiplyDivide node to multiply the VRayFalloff with a VRayUserScalar node (With the default value set to 1). Then you just add that user attribute to only the objects/groups need to tweak, where it’ll act as a bump strength multiplier, and everything else will be unaffected.

We’ve considered a lot of options here, and have come to three solutions that should work (almost) perfectly based on your specific needs (of course, some settings might need tweaking). We’ve also considered using custom attributes and expressions, but the setup gets too complicated. So here’s 3 setups that require a minimum amount of setup time and should (hopefully) work for you.

All setups rely on the singleShadingSwitch, where all of your objects but one receive a constant float value for the bumpMult, then the one object receives a value based on some calculations.

1. VRayFalloff
A VRayFalloff texture is set to distance blend based on camera Z. You’ll need to tweak the far/near range. The texture outputs 0-1 values based on what color is used. The output is fed to a condition node, which clamps the value to either 0 or 1 based on the 0.5 mid value (i.e. if output>=0.5, then 1, else 0). The ‘1’ case hardcodes a 1 value to be used for bumpMult, otherwise we hardcode a 0.1 value for bumpMult, and the condition feeds into VRayMtl.bumpMult.

Pros: easy to setup
Cons: Works on pixels, not objects! This means that if part(s) of your ‘special’ object is on one side of the near/far distance range, while the rest of it is on the other side - it will receive different bump mults based on what pixels it takes in the image. I suppose this could be used in a scenario, where your character does *not* come gradually closer to the camera, but instead you have different cameras for the mid-shots and the close-ups. So - use with caution.

2. Distance between with pre-frame MEL
A distanceBetween node gets you the distance from an object to the camera. I’ve used a sphere (the two cubes are the ones with constant mults).
The problem here is switching the cameras. To avoid having too many nodes, I’ve used a MEL scripts that looks up the current camera and connects it to one side of the distanceBetween, while the sphere is always connected.
The script is executed pre-frame, and checks if the camera actually needs changing to avoid any errors/warnings printed. I’ve inserted some debug prints that you can remove, but the scripts is:

string $cam = `vrend -query -camera`;
string $connected[] = `listConnections -t transform distanceBetween2`;

if ($cam != $connected[1]) {
    connectAttr -f ($cam + ".worldMatrix[0]") distanceBetween2.inMatrix2;
    print ("\n=== Connecting camera " + $cam + " ===");
} else {
    print ("\n=== Camera " + $cam + " already connected ===");
}

Note: in my case I’m relying on having my sphere always connected to the first matrix input (index 0) of the distanceBetween, and the camera - always to the second one (index 1)!!! (Can be improved, didn’t have the time).

Pros: Works on objects, not pixels.
Cons: requires scripting

3. Distance between with post-translate python
Same as the previous setup, only the camera does not actually ‘change’. I’m feeding the distanceBetween with the transformation of the renderView plugin (essentially the camera) that gets exported after the scene is translated to VRay in memory (or to vrscene on disk).
Since you can’t have more than one camera in a vrscene, whatever new camera is used for your frame/sequence/etc is translated as a single renderView plugin. I’m always getting that exact transform to feed the distanceBetween.
Essentially, the code is shorter and is used as post-translate python access to the exported vrscene (works for gui renders, batch renders and vrscene export that goes to a render farm/standalone).

from vray.utils import *

dist = findByName('distanceBetween2')[0]
cam = findByType('RenderView')[0]
camT = cam.get('transform')
dist.set('transform2', camT)

Pros: works on objects, not pixels.
Cons: requires (less) scripting. Camera is changed only in Maya, can’t be changed after the vrscene is exported.

Notes: There might be some tweaking required to get this to work, but let me know if you come across any problems.
Also - let me know if you can use these setups, I don’t know much about your project other than what you’ve shared here, so I might have missed a detail that you need to account for.
In any case - I hope you find this helpful. Let me know if there’s anything else.

SCENE FILES: custom_bump_mult.zip
I’ve not included the texture used for the scenes, just use any normal map.
custom_bump_mult.zip (176 KB)

Ah, forgot to mention that my scenes use V-Ray Next and Maya 2018, so in case they don’t work for you, let me know and I’ll re-do them for 3.6.

I’ll admit I was assuming he wanted a continuous fade if possible, rather than a switch. I think it might help to know exactly what this is for. That being said, that was a very nice breakdown of the options :slight_smile:

Hmm, in that case, something based on the VRayFalloff texture should work, but it really depends on the specific need. :slight_smile:

@yolov and @dgruwier Thanks guys! Much appreciate it for all the details, breakdown, and options. I should be more specific on the actual need. The UserAttribute node is interesting. I’ll give that a go.
Yes, a smooth fade is needed as the camera is going to pull smoothly from wide shot to close-up of a human size hard-surface character. Bump Mult at 1 works well for the wide shot but the value needs to be as small as 0.1 on certain objects depending on the distance between the camera and object. Even when the camera is at close-up, I want to be able to dial in different Bump Mult value for the head parts and neck parts separately, for example.

The reason I was concerned about the camera is that if the setup involves connection to a specific camera, then when the lookdev-ed scene is referenced into a lighting/render scene, I need to swap the camera for all shading networks involved. I am excited to explore Alex’s approaches to utilize some scripting tricks there for this.

I also came across an approach here (https://jdbeals.com/tutorials/camera-distance-based-bump-mapping/) and with that, I was able to see the Bump Mult value changing in UI as pull camera close/away from the character, something I couldn’t visualize with VRayFalloff until I IPR the scene. It works when I test it but again need to figure out a way to scale up for my scene that has multiple shaders and camera switch at the end.

The VRayFalloff node just gives you the per pixel distance from whatever camera it’s being rendered through, there are no connections involved.

Yeah, I did a quick test and noticed that’s one of the benefits where I don’t need to spend time on connecting a camera to multiple nodes. Trying to figure a way to get a visual read of the Bump Mult value at the moment though. I kinda know the range of Bump Mult I want for each shader so being able to get a read before kicking off an IPR really helps speed up the setup.

You know the options now, so pick what works best for you.

That being said, you could create a very fast render layer with no lights or reflections, using the Extra Tex element like I mentioned earlier, then just have that running in the IPR while you make your tweaks. That way you can see the exact bump multiply value across the entire image, for every object at the same time, and (most importantly I’d argue) you can actually see the bump itself. If you just have that running constantly, there’s nothing to kick off.

That’s an interesting approach.
Do let us know how things turn out at the end, I’m curious.

@dgruwier Oh man, cool trick! I’ll give that a go. cheers!

@yolov sure thing Alex. I didn’t realize there are multiple ways to achieve this each with pros and cons until this thread. Thanks guys!

Also, is this setup gonna be obsolete if I use displacement map instead?