Bump Filtering in the Rendertree

May 24th, 2008 by Stefano Jannuzzo - Viewed 12843 times -

The current bump node (formerly known as zbump) became very popular for its simplicity, and for its ability to get procedural textures as inputs.

However, it has some limitations, for instance not supporting texture pre-filtering, and the fact that its spacing is expressed in world coordinates instead of uv coordinates like the old node. This leads to frequent aliasing problems, that can sometimes be limited by texturing the spacing based on the object’s distance from the camera.

Another way of fixing the aliasing is to filter the high frequencies of the input texture. The primary way to achieve this filtering is to do it on the image in an editing program like Photoshop, but this is harder to do with procedural nodes.

However, by using a few nodes in the rendertree, it is possible to do it there also.

The bump node outputs the new normal (N’), after having bent the original one (N) based on the texture gradient at the current point.

So, we can compare N to N’ by subtracting them and getting the length (L) of this difference vector (D). Since N and N’ are normalized, and the maximum bump angle is 90 degrees, D ranges from 0 (no bump) to 1.41, ie the hypotenuse of a right triangle with unit catheti.

We can then set a maximum length for D, and re-arrange N’ in order not to exceed it, so to filter off the high frequencies and limit the aliasing.

In this first rendertree, we simply want to check the “dangerous” zones. We take the length (L) of the normal’s difference (D) and check it against a maximum scalar. If this scalar is exceeded red is returned or green otherwise.

In this example the scalar is set to 1, we are seeing in red the parts where the bending angle exceeds 60 degrees.

To output the filtered normal, we do the same test as above, but connected to a scalar switch.
The switcher outputs the maximum between Max Displacement and L. This value is used to set the new length of D (VectorNormalize + VectorSetLength).

This vector is then added to the original normal N and normalized. This is our new, filtered normal.

Of course this is a very basic filter, more complex ones can easily be built to fit your needs.

You can grab the scene if you want. The red and green subtree is also included, connected to the shadow port.

5 Responses to “Bump Filtering in the Rendertree”

  1. Enea Le Fons says:

    Such a handy and elegant article! Thank you Stefano!

  2. gavin h says:

    where is the test scene?

    is this the only work around?

  3. Sorry… The link to the scene was broken. Fixed now.

  4. Aldanor says:

    It would be even more elegant to “feather” the threshold area, i.e., add linear interpolation with smoothing parameter:

    L =< Max_L * smooth
    Bump := N’

    If Max_L * smooth < L = Max_L:
    Bump := N

  5. Aldanor says:

    The formulas in my comment got totally messed up somewhy, but you got the point.