Advice on applying incoming funciton nodes to bump gradients?

jrandom

eye kan kode gud
I can't seem to wrap my head around this one. My node takes an incoming function node and applying that to color and alpha were easy, but how do I apply it to my bump gradient? Applying it directly to the individual bump vector elements doesn't give the desired results, but I can't quite figure out what the right way is.

Can anyone help me out here?
 
It's been quite a while since I dealt with the bump/node stuff, but if you have calculated your own bump gradient and want to perturb the incoming bump with your own, have you tried to simply add the incoming gradients with your own?


LWDVector bump;
inputfuncs->evaluate(inst->inBump, na, &bump);
bump.x += myBumpy.x;
bump.y += myBumpy.y;
bump.z += myBumpy.z;
 
I've got bump mixing working just fine. But you know those yellow "function" inputs on nodes? I'm trying to apply that to my internally-generated bump gradient. My naive solution above doesn't work because bump gradients aren't heights, they're rates of change.

I know it's possible because the built-in lightwave procedurals apply function nodes to bump gradients in a way that gives the results you'd intuitively expect, behaviour-wise. I just can't seem to figure out how they did it.

(I can apply the function input to my color and alpha channels easily because those represent discrete intensities -- a direct application of the function input works just fine in that context.)
 
It just occurred to me that the built-in 3D texture nodes in lightwave might be generating their bump gradients by multi-sampling 3D space in the vicinity of the desired point, which makes applying the function easy: apply function to the multiple samples and generate a gradient from those.

Simplex noise generates the bump gradient directly without multi-sampling, so what I get back from a single call is the noise value and three gradient values... so it might not actually be possible to apply the function input to the bump gradient in this case.

I'm hoping that's not the case, but I don't know enough math to say one way or the other.
 
Last edited:
Myagi, here's my bump-mixing code (allows for both incoming foreground and background bump channels instead of just one):

Code:
        // Mix in incoming bump vectors
        const LWTypes::LWDVector incoming_foreground_bump( Input_Bump_Foreground.Get(nodal_access) );
        const LWTypes::LWDVector incoming_background_bump( Input_Bump_Background.Get(nodal_access) );
        
        const LWTypes::LWDVector incoming_bump( LERP( final_noise, incoming_foreground_bump.X(), incoming_background_bump.X() ),
                                                LERP( final_noise, incoming_foreground_bump.Y(), incoming_background_bump.Y() ),
                                                LERP( final_noise, incoming_foreground_bump.Z(), incoming_background_bump.Z() ) );

        VADD( bump_vector, incoming_bump );

I think this isn't quite right, because if the bump gradients are rates of change, it will be impossible for an incoming bump that goes in one direction flatten out another that goes in the opposite direction (assuming all individual bump vector channels are between 0-1). I'll have to re-think that code and see if I can come up with something more correct.
 
Last edited:
Oh hey, some experimentation with LW nodes shows that the outputted bump vector is in the range [-1, 1], so some of my bump math is flat-out wrong. Will have to go back and re-work those. On a positive node, the above bump-mixing code works fine after I went back and used the original gradient (instead of scaling it to the range [0, 1]).

Still no idea how to apply functions to them, though.
 
Last edited:
Oh that "function". Forgot about that connection type, sorry. I get the impression that the standard nodes apply the function on the procedural output value itself, which is later used as a height value to calculate bump gradients (as you feared).
 
Back
Top