bump mapping (blinn's 1978 method)

Yes, this is because bump mapping is basically only a fake... ;-)
Indeed!

Anyway, your example and your explaination still confuses me:

You worte in the example:

P = perturbation vector (composed of rise/run slopes, gradients, in x, y, and z)

If it is like it is in your explaination there shouldn't be a gradient in z direction because a bump map is only a 2d heightfield. There are just x- and y-slopes.

I have a strong feeling everything I am about to say is only going to add more confusion... as I am confused as to where I am losing you! :)

Let me try to figure some of this out...

My 3D bump map is just a 3D "array" of height values, so in that sense, any specific individual point in my 3D bump map is a height value the same as any point in a 2D bump map is.

Why I need to use the z-gradient:

If I were to ignore z when calculating the perturbation vector, then I would be ignoring all rate-of-changes (slopes) in the z directions of my bump map. This is obviously incorrect. (Well, this should be some sort of hint that it is incorrect I mean!) Imagine bump mapping a plane that exists in (x,z), which is the plane defined by y=0. If I were to bump map that plane, I would need to consider changes as we move through z in the bump map. If I were to only consider changes in x and changes in y, then I would be ignoring how the bump map defines bumps as we move through z.

I think you are confusing the three dimensions of the bump map (we can sample the bump map in 3D) and the single dimenison of the bump map's values (the values we get from sampling are 1D height values).

A bump map defined by a 2D texture is just a 2D height field. My 3D bump map would be a 3D height field, but that conceptually makes little sense, as you never use the full 3D of the 3D bump map... you only use 2D planes "carved" out of it. The only purpose of a 3D texture is so that it can be mapped to a 3D surface without distortion. Other than that, my 3D bump map is much the same as a 2D bump map.

...

At this point, I think the best thing to do is forget everything I said! :) Clear your mind, and check out the code snippet in this same thread. It is a very easy algorithm. That algorithm is the same bump map algorithm I have implemented. I think everything will make sense once you grasp what Ken Perlin is doing in that code.

Let me know if any part of his code makes no sense... because we are talking about his code really.
 
Last edited by a moderator:
If it is like it is in your explaination there shouldn't be a gradient in z direction because a bump map is only a 2d heightfield. There are just x- and y-slopes.

I think I can do a better job after clarifying to myself what you said...

In a 2D height field defined in (x,y), there are x and y slopes.

However...

In a 2D height field defined in (x,z), there are x and z slopes.
In a 2D height field defined in (y,z), there are y and z slopes.

So...

In a 3D height field defined in (x,y,z), there are x, y, and z slopes!

You can "move through" the 3D height field in x, y, and z, same as you can "move through" a 2D height field in x and y.
 
Now we are tracking down the part that is confusing me! ;-)

You say there are slopes in all directions in a 3d bump map. This would mean that a 3d bump map is more than you said: This would mean that it also defines the orientation of the heightfield, but this is not possible in my understanding. If it is a really just a 2d heightfield defined in 3d, it should be exactly the same as in 2d bump mapping: the bump mapped surface defines the orientation of the bumps. Consider what you said: A 3d bump map only contains height values. So any part you carve out from the 3d bump map defines a plane with a heightfield. This heightfield is than mapped onto a 3d object.

I Just took a closer look on Ken's program. What I discovered is that the way he computes the bump normal it is possible to get wrong normals. It depends on the function f he uses.

// SAMPLE THE FUNCTION FOUR TIMES TO GET GRADIENT INFO

double f0 = f(normal[0] ,normal[1] ,normal[2] ),
fx = f(normal[0]+.0001,normal[1] ,normal[2] ),
fy = f(normal[0] ,normal[1]+.0001,normal[2] ),
fz = f(normal[0] ,normal[1] ,normal[2]+.0001);

// SUBTRACT THE FUNCTION'S GRADIENT FROM THE SURFACE NORMAL

normal[0] -= (fx - f0) / .0001;
normal[1] -= (fy - f0) / .0001;
normal[2] -= (fz - f0) / .0001;
normalize(normal);

So f actually defines the bumps' orientation's in 3d, not just 2d height values. So if the function is not suitable for the underlying object (sphere here) there are easily generated wrong bump normals.
So the 3d bump map Ken uses is more than a heightfield defined in 3d! That's the way I see it. :)
 
You say there are slopes in all directions in a 3d bump map. This would mean that a 3d bump map is more than you said: This would mean that it also defines the orientation of the heightfield, but this is not possible in my understanding.
The 3D bump map does not define the orientation of its height field. You are right that it is not possible.

The sampling of the 3D bump map can be done with knowledge of the underlying surface's orientation (given by the original surface normal) to calculate the rate-of-change (the bump slopes) in that specific orientation. (Ken Perlin's algorithm is amazingly simple in that it does not use or require the orientation, the surface normal, of the original surface in calculating the bump slopes.)

...

To clarify what a 3D bump map is, consider this simple example:

If you were to make a bump map from random values between 0.0..1.0...

...a 2D bump map could be a 256x256 array of random values between 0.0..1.0.
...a 3D bump map could be a 256x256x256 array of random values between 0.0..1.0.

(3D bump maps that Ken Perlin and I use are actually infinitely large, as we use procedural methods to create them. But it is easier to compare 2D vs. 3D if we ignore that fact for now.)

They are just height values, nothing more. There is no orientation of the height field defined in the bump map. It allows all for bump mapping in all possible orientations, though.

A 2D bump map is always oriented that when you "move" along the original smooth surface, you "move" in (x,y) in the 2D bump map, grabbing height values which define the bumps.

A 3D bump map has no orientation, in the sense that it does not need to be oriented. When you "move" along the original smooth 3D surface, you "move" in (x,y,z) in the 3D bump map, grabbing height values which define the bumps.

The only orientation of the bumps is that the bumps bump out (and in) in the direction of the original surface's normal, both in 2D and 3D bump mapping.

If it is a really just a 2d heightfield defined in 3d, it should be exactly the same as in 2d bump mapping: the bump mapped surface defines the orientation of the bumps.
If you mean the original surface (that is to be bump mapped) defineds the orientation of the bumps, this is true.

I Just took a closer look on Ken's program. What I discovered is that the way he computes the bump normal it is possible to get wrong normals. It depends on the function f he uses.
What you mean by, "It depends on the function f he uses". In what way does it depend on this? (I'm not sure if you are on the same track as me, but it actually does depend on the function f, the bump map function, whether or not the algorithm "breaks". As I explained much earlier if you wish to go back, if the bump map function produces slopes greater than 45 degrees, it is possible for the formula to break down and perturb the original smooth surface normal by more than 90 degrees.)

So f actually defines the bumps' orientation's in 3d, not just 2d height values. So if the function is not suitable for the underlying object (sphere here) there are easily generated wrong bump normals.
So the 3d bump map Ken uses is more than a heightfield defined in 3d! That's the way I see it. :)

This is where I am lost with how you see it, so my response may be totally unhelpful! :)

"f" is the bump map function, which passes back only 1D height values, not 2D! A length is one dimensional. Perhaps realizing the values are only 1D showcases that a 2D bump map is very similar to a 3D bump map, as they both contain 1D values which does not match their amount dimensions.

The "f" bump map function is suitable for any and all underlying objects. Because it is in 3D (and it is infinitely big) you can picture it as a huge block of wood, where any object can be carved out of it.
 
Last edited by a moderator:
Another way to help describe what a 3D bump map is and how to use it, is to consider these simple (but slightly difficult to describe) examples:


First, using a 2D bump map (1 example):

1/1:

Assuming you were bump mapping the 2D plane, in a 3D world, defined by z=0. As you move through x and y of the 2D plane, you sample x and y from the the 2D bump map.

Simple, right? Don't read on until you visualize that example.


Now, using a 3D bump map (3 examples):

1/3:

Assuming you were bump mapping the 2D plane, in a 3D world, defined by z=0. As you move through x and y of the 2D plane, you sample x and y from the the 3D bump map. The z value of the bump map is 0. The 3D bump map is effectively a 2D bump map in (x,y) with z ignored.

2/3:

Assuming you were bump mapping the 2D plane, in a 3D world, defined by y=0. As you move through x and z of the 2D plane, you sample x and z from the the 3D bump map. The y value of the bump map is 0. The 3D bump map is effectively a 2D bump map in (x,z) with y ignored.

3/3:

Assuming you were bump mapping the 2D plane, in a 3D world, defined by x=0. As you move through y and z of the 2D plane, you sample y and z from the the 3D bump map. The x value of the bump map is 0. The 3D bump map is effectively a 2D bump map in (y,z) with x ignored.


It goes to show that any 2D slice of the 3D bump map is a regular every-day 2D bump map. If you were to hard-code z=0 in my 3D bump map, I would have a 2D bump map.

The bottom line is that a 3D bump map is used the same as a 2D bump map, only that we do not have to worry about mapping 2D textures onto 3D objects... 3D textures require no mapping or stretching or anything to be applied to a 3D object. That's the power in 3D textures.

Hope this helps!
 
Last edited by a moderator:
Thanks for your examples. Still don't know how Ken's gradient relates to a 2d heightfield, though, do you? Considering the gradient he computes from the function f: as long as this gradient's length is slighly less than 1, a wrong normal cannot be computed, because the purturbed normal will stay in the 90 degree cone of the original normal in any case, right? But how to generate a perturbed normal with 90° angle in respect to the original normal? It seems to me the "height field" function must be carefully designed for that. But that is what you already discovered earlier, I think. ;-)
 
Last edited by a moderator:
Thanks for your examples. Still don't know how Ken's gradient relates to a 2d heightfield, though, do you?
I'm not sure what you are asking, but I'll try to answer:

A typical bump map is a 2D array of 1D values.
A 3D bump map is a 3D array of 1D values.

I am assuming you are thinking of a bump map as a 2D height field... it is not. A bump map is just a collection of 1D height values, nothing more. The dimensions of a bump map are up to its creator. If you wish to store a 2D array of such values, you have a 2D bump map. If you wish to "store" a 3D array of such values (I calculate them procedurally, so I do not store them), you have a 3D bump map.

I'm not sure if I am right in my assumption, and even if I am right I am not sure if this is causing you some confusion.

Considering the gradient he computes from the function f: as long as this gradient's length is slighly less than 1, a wrong normal cannot be computed, because the purturbed normal will stay in the 90 degree cone of the original normal in any case, right?
Exactly!

But how to generate a perturbed normal with 90° angle in respect to the original normal?
Are you asking for an example of this (with Ken's bump mapping algorithm)? I can give you one, as it is possible.

It seems to me the "height field" function must be carefully designed for that. But that is what you already discovered earlier, I think. ;-)
It can be designed for that, just make sure your bump maps never surpass the 45 degree slope limit. I will be doing this, but I was taking it one step further... I wanted to handle bump maps of greater than 45 degree slopes elegantly, just in case they come up by accident. I wanted my bump mapping algorithm so it will never "break" and start returning normals facing the opposite direction, even with ridiculously high bump map slopes! (Such ugly artifacts!) Ultimately, bump maps of such slopes are ugly anyway, so I will be doing my best to avoid them.
 
Last edited by a moderator:
Matt,
I haven't thought through the details, but it sounds to me that, along with your 3D texture mapping R^3->R, then you also need something that computes the derivatives of that function in a given direction.

You'd then probably use the object's tangents (at the given screen pixel/ location) to compute the derivatives of the 3D bump function (in the directions of the tangents) and, from those results, compute the displaced normal... or something like that :)
 
Matt,
I haven't thought through the details, but it sounds to me that, along with your 3D texture mapping R^3->R, then you also need something that computes the derivatives of that function in a given direction.

You'd then probably use the object's tangents (at the given screen pixel/ location) to compute the derivatives of the 3D bump function (in the directions of the tangents) and, from those results, compute the displaced normal... or something like that :)
That makes complete sense.

You are essentially using the 3D bump map as a 2D bump map at the point in question, then using Blinn's known-to-work method with the 2D bump map. I'm not sure how you would orient the derivative vectors for all possible normals, but this is a solution that works. I have not implemented this, yet.

I just found out in my "Texture & Modelling: A Procedural Approach (3rd Edition)" that they mention my easy "hack" method of using the derivatives in x, y, & z, and that Ken Perlin uses it. They also mention it is wrong (in another place in the book) where they mention that Blinn's method is the most accurate method.

I have never seen Blinn's method used on a 3D bump map, though.
 
Ah, now it seems we are getting closer to the thing that still confuses me a bit! ;-)
In case you use the local tangent frame at a given surface location of the bump mapped object for the 3d bump map lookup, you can't produce any wrong normals as in yours and Kens case! Using only the slopes in tangent and binormal direction for the lookup and then computing a bump normal from the slopes should be the way to go, as far as I understand it. Then all makes much more sense to me (;-)) than if using derivatives in xyz-direction...
 
It does make more sense. That fact that I can "break" Ken Perlin's method, and have it causing >90 degree perturbations of the original normal, means that it is only an approximation (a very good approximation from my testing).

I have yet to see or run into any one using Blinn's method with a 3D bump map... I wonder why this seems to be so rare?

Out of all of the 3D renderers out there, including all the ray tracers, you would think this would be quite common. Unless I am just not looking hard enough.

I am trying to contact Steven Worley (one of the "Texture & Modelling: A Procedural Approach (3rd Edition)" authors) to discuss this some more.

I am going to continuing digging until I can shed some light on exactly how the 'pros' do it! I am really interested if it is similar to the method you (NicoRi) and I have just been discussing. I will update this thread as I find out more. Thanks for going through this with me! :)
 
I am trying to contact Steven Worley (one of the "Texture & Modelling: A Procedural Approach (3rd Edition)" authors) to discuss this some more.

I am going to continuing digging until I can shed some light on exactly how the 'pros' do it! I am really interested if it is similar to the method you (NicoRi) and I have just been discussing. I will update this thread as I find out more. Thanks for going through this with me! :)

Cool. By the way, do you have a job for me? ;-)
 
No, you didn't miss anything. It's just that I'm looking for a job right now... Graduated from University a few moth ago and still haven't found somthing suitable.
 
Have you thought about doing your own thing, becoming an entrepreneur, and working for yourself? It is what I am doing, and I wish I started putting efforts into it much earlier.
 
Well, I thought of it a few times, but isn't it difficult to do something on your own and earn enough money with it to live? So, what kind of stuff do you exactly do? I know this is off topic. Maybe we could use private messages.
 
Back
Top