PDA

View Full Version : bump mapping (blinn's 1978 method)

Matthew Doucette
11-Sep-2006, 18:07
I'm having a few problems implementing bump mapping as Jim Blinn describes in his 1978 "Simulation of Wrinkled Surfaces" paper. (A download of that paper can be found in this thread: http://www.beyond3d.com/forum/showthread.php?t=25306 )

Just curious if anyone here has implemented it (exactly) as described in that paper?

Simon F
12-Sep-2006, 10:01
I'm having a few problems implementing bump mapping as Jim Blinn describes in his 1978 "Simulation of Wrinkled Surfaces" paper. (A download of that paper can be found in this thread: http://www.beyond3d.com/forum/showthread.php?t=25306 )

Just curious if anyone here has implemented it (exactly) as described in that paper?
I haven't implemented Blinn's method "to the letter", but I have implemented a number of different bump mapping techniques, so I might be able to help.

What problem are you having?

Matthew Doucette
12-Sep-2006, 14:17
The problems I am having occur when bump mapping a height map, whenever the slope of the height map is at extreme (nearly flat) levels. I have a demo that shows the 3D vector math of Blinn's method in Ken Silverman's Evaldraw ( http://advsys.net/ken/download.htm ). I will post the code here once I clean it up to make it easier to review. I will do this later on today...

It is not uncommon to get confused with 3D vector math, so I am not doubting that I have missed something simple!

Matthew Doucette
21-Sep-2006, 19:57
Simon F,

I figured out the problem with my Blinn bump mapping. It requires that the partial derivatives (pu, pv) of the original surface and the original surface's normal (N) to create a coordinate system (pu, pv, N). In other words, pu and pv must create a right angle, which they do not if they are not "flat". The original surface must be parameterized in order to have this set properly... I was assuming I could use the px and py (of my height map defined in (x,y)) as the pu & pv, which obviously do not create a coordinate system on most slopes.

Anyways... Blinn's method does not work for me unless I parameterize my height map into (u,v) which I am not sure how to accomplish.

Another issue is that I am using fully 3D procedural bump map textures, and fully 3D surfaces, not 2D ones. This matters in that it is difficult for me to parameterize my 3D surfaces into a 2D (u,v) system, and I do not wish to as I want to map my 3D bump map precisles "as-is" to my 3D surfaces (as if they were carved out of an already existing 3D material).

Sorry if they is unclear, I am almost confusing myself here. I'm hoping that discussing it will help clarify the issue to myself!

Have your (Simon F or anyone) experiences with bump map coding involved fully 3D bump maps?

ERP
21-Sep-2006, 20:14
There are lots of articles on creating the necessary U/V coordinate systems.
The short version is it's not trivial.
I'd start on Nvidias site.

Matthew Doucette
21-Sep-2006, 22:40
It turns out I found a very simple solution, due to the fact I am using a 3D bump map texture. I can perturb the original surfaces normal vector by another "perturbation vector" that is nothing more than the gradients (rate of change in rise/run) in x, y, and z in the 3D bump map texture. In other words, the values of (x,y,z) in this perturbation vector are the slope values of the bump map in x, y, and z. I've tried it out and it seems to work fine in all the extreme cases.

To create the u/v coordinate system seems to be something required if I were to be using a 2D bump map texture.

Thanks for helping me out!!

Matthew Doucette
27-Sep-2006, 15:47
The solution I have is not optimal. The perturbation of the original (smooth) surface normal can exceed 90 degrees (something which should not happen if the bump map represents a height field, as the bump map can never represent an angle of greater than 90 degrees.)

Is there a simple solution I am missing?

Anyone would has bump mapped a 3D surface via a 3D texture, I would love to discuss these issues with you!

Simon F
27-Sep-2006, 16:13
The solution I have is not optimal. The perturbation of the original (smooth) surface normal can exceed 90 degrees
How can that be possible? IIRC, the pertubation you add to the normal lies in the plane of the tangents.

Matthew Doucette
27-Sep-2006, 19:46
How can that be possible? IIRC, the pertubation you add to the normal lies in the plane of the tangents.

Very true, but the perturbation is added to a normalized (lenght 1.0) normal, so if you were to get a gradient (rise/run rate of change) of greater than 1.0 in the direction of the normal, (because the gradient value is subtracted from the normal) it would perturb the normal to point in the opposite direction.

That is hard to understand, so let me clarify with an example:

------------

N = original smooth surface normal
N' = bump mapped surface normal
P = perturbation vector (composed of rise/run slopes, gradients, in x, y, and z)
N' = N - P

N = (0,0,1) = normalized normal pointing towards positive z
bump map gradient in x = 0
bump map gradient in y = 0
bump map gradient in z = 3
(In other words, the bump map has a rise/run slope of 3 in the direction of positive z, and 0 slopes in x & y.)
P is constructed from the gradients:
P = (0,0,3)

N' = N - P
= (0,0,1) - (0,0,3)
= (0,0,-2)

Normalize N':

N' = (0,0,-1)

N' now points in the opposite direction, 180 degrees rotated from N!

------------

A gradient of 3 is a rise/run of 3/1, which is only an angle of... atan(3/1) = 1.25 radians or 71.6 degrees.

71.6 degrees seems like a sharp slope. (It is.) But the bump map height field has the potential to produce slopes up to 90 degrees. But that is just from my extreme example. The point in which a slope has the potential to surpass the normalized original normal length of 1.0, is when the rise/run because greater than 1.0, which occurs at 45 degrees. 45 degrees in practice is uncommon, but I was hoping for a solution that would work in all cases.

I still feel like I'm missing a better solution.

What I have done for now, works, which is to catch all perturbations of the normal vector that are greater than 90 degrees, and rotate them BACK to the 90 degree point (in the same direction of rotation of course). So, whenever the perturbation causes a >90 degree rotation, I calculate where it would be if the rotation happened to be only 90 degrees.

I hope this explains my problem better!

Simon F
28-Sep-2006, 09:20
I don't think you are calculating that correctly. I've just skimmed through Jim Blinn's paper and the displacement that is added to the original normal, N, lies in the plane perpendicular to N. (Look 1/2 way down the second column of the second page)

Therefore, it should be impossible to achieve even a 90 degree perturbation.

He gives some (Fortran :-) ) pseudo code to do it that you could base your code on (shrug).

Matthew Doucette
28-Sep-2006, 14:01
Simon F, I'm sorry but I stopped using Blinn's method and started using a new method!

(I first explained this in my post in this thread that starts, "It turns out I found a very simple solution..." I realize that I confused this whole thread when I did this, but I could not go back and change the thread title!)

Blinn's method is great for 2D bump maps that have to be mapped onto 3D surfaces. But, I have a 3D bump map, which is just a 3D texture, mapped onto a 3D surface.

The bump mapping method I am using is a modified version of and idea I stumbled upon when looking at this 3D noise example (by Ken Perlin):
http://mrl.nyu.edu/~perlin/homepage2006/bumpy/index.html

Note that the above example is using a 3D texture as the bump map. Visit the above link to see visuals.

The code of that example:
http://mrl.nyu.edu/~perlin/homepage2006/bumpy/Sphere.java

The bump mapping portion of that code:

/* sample code of Ken Perlin's 3D bump mapping of a unit sphere */

// COMPUTE POINT ON UNIT SPHERE (WHICH IS ALSO THE SURFACE NORMAL)

normal[0] = X / R;
normal[1] = Y / R;
normal[2] = Math.sqrt(1 - normal[0]*normal[0] - normal[1]*normal[1]);

// 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);

It is so simple and appears to work great. It (seems to) make complete sense when you look at it in 2D, but I know it can be broken (as previously explained) in 3D with extreme bump map angles. (I have actually "broken" it in my software, and I explain how it can happen in my previous post.)

I still have a feeling there is a better solution (that never "breaks" for any rise/run angle encountered in the bump map) when dealing with 3D bump map textures on 3D surfaces...

In searching for bump mapping methods, I usually only find methods that are for 2D bump maps. I have ideas on how to turn my 3D bump map into a 2D bump map (a 2D slice of my 3D bump map would do it) on a per-pixel basis, which would make these methods work, but Ken Perlin's code has given me some indication (or a feeling) that an easier, and more elegant, solution exists!

NicoRi
28-Sep-2006, 19:32
I might be missing something, but your example confuses me. How can you have a3d bump map?
I mean, for what purpose? You could produce "hang over" ;-) bumps in case you use a 3d color texture as well, hm? But I doubt that this works in practice. But in that case, of course you can produce bump normals pointing opposite the surface normal as in your example. You can produce any kind of bump normal with that. A 3D bump would needed to be coupled with a specific model to avoid this behaviour.

Just a few thought... Please tell me if I missing the whole point... lol

Edit: Just took a look at Ken Perlin's example. At first glace I guess the function f produces a "good" bump normal, i.e. one which doesn't hang over. However, its just a guess. Did you try using Ken's noise functions?

Matthew Doucette
28-Sep-2006, 21:42
The bump map is not 3D in the sense that you are thinking about it.

The bump map is nothing more than a 3D texture. The 3D texture is a 3D procedural texture that takes in (x,y,z) and returns -1.0..1.0. The -1.0..1.0 output is a height. -1.0 is the lowest height possible, and 1.0 the highest.

So, the 3D bump map is still only a height field, but just one that has values within a 3D area as opposed to a 2D area (like a normal 2D texture).

The way this helps is that the 3D surface being bump mapped with the 3D bump map can use a "carved out" section of the 3D bump map that perfectly fits the 3D surface. Imagine texturing a 2D texture on a sphere. It is difficult to do without distortion the 2D texture in one way or another. Texturing a 3D texture on a sphere just requires sampling of the 3D texture in a spherical shape. The values returned by that 3D texture can be used just the same as value from a 2D texture would be used.

Please let me know if that explains it... or if it explains it but still sounds confusing. I can always clarify more!

...

By the way, the Ken Perlin example above uses his 3D noise as a 3D bump map texture, exactly the way I explained above (in this post).

My 3D noise is based upon Ken Perlin's original gradient noise (aka Perlin noise) work, so it is very familar. That's where I adopted the -1.0..1.0 range (as opposed to a 0.0..1.0 range).

Simon F
29-Sep-2006, 09:48
Matthew,
What you are doing with the 3D Perlin textures sound very much like what I/we did in a previous job when applying bump maps in a ray tracing system. Unfortunately it was a long time ago and I can't remember the details.:sad:

I can't recall having any problems with normals etc.

There were images of the results on the net but they seem to have vanished.

Matthew Doucette
29-Sep-2006, 13:11
Anyone who has programmed a ray tracer with bump mapping using 3D textures would be running into the same issues as I am.

I think the solution I now have works, so I am ok. The solution works for small bumps, and large bumps "break the system" of bump mapping, what I mean is the bump emulation effect stops working for large bumps (it produces unconvincing results for large bumps), so I will be avoiding this anyway.

I just had to make some effort to see if a more elegant solution existed!

If you ever stumble upon this problem (or solution), and you remember me, please let me know! My bump mapping code is quite modularized and very easy to change at any point in time.

NicoRi
29-Sep-2006, 21:20
Please let me know if that explains it... or if it explains it but still sounds confusing. I can always clarify more!

Thanks, well, ok, got it. But in this case it is definitely not possible to get a bump normal having a negative z component. (If the 3d bump map is really just a 2d heightfield defined in 3d space it has the same limitations like a 2d bump map, hm?)

Matthew Doucette
30-Sep-2006, 01:11
Thanks, well, ok, got it. But in this case it is definitely not possible to get a bump normal having a negative z component. (If the 3d bump map is really just a 2d heightfield defined in 3d space it has the same limitations like a 2d bump map, hm?)
Exactly. Any 2D plane (oriented in any angle at all) of the 3D bump map is a 2D bump map just like any other 2D bump map. The fact that they values are obtained via 3D (x,y,z) instead of 2D (x,y) doesn't change what the values mean. They are still just height values.

EDIT:

I should be using (u,v,w) and (u,v) when dealing with 3D and 2D texture coordinates instead of (x,y,z) and (x,y).

NicoRi
30-Sep-2006, 08:04
So, but what you just said contradicts this earlier post:

What I have done for now, works, which is to catch all perturbations of the normal vector that are greater than 90 degrees, and rotate them BACK to the 90 degree point (in the same direction of rotation of course). So, whenever the perturbation causes a >90 degree rotation, I calculate where it would be if the rotation happened to be only 90 degrees.

There cannot be a any perturbations greater than 90 degrees in a 2d bump map.

Matthew Doucette
30-Sep-2006, 14:41
There cannot be any perturbations greater than 90 degrees in a 2d bump map.

With the proper formula, this is true. (This is the algorithm I am looking for!)

With the formula I am using (based on Ken Perlin's code), this is not true. So, the bump mapping formula I am using is not optimal.

The bump mapping algorithm I am using only causes >90 degree perturbations when it encounters extreme bump map angles, which I now catch for and handle. These are angles that rarely, and hopefully never, happen... as they are so extreme that bump mapping itself begins to stop working as a visual tool to showcase such extreme angles. (Anyone who has tried to see how far bump mapping can go by increasing the "strength" or height of their bump maps, knows what I mean. You can only go so far before the visuals stop making sense.)

From my explanations in previous posts of how and when the algorithm I am using "breaks", I showed it requires a bump map gradient, rise/run slope, of greater than 1.0, which is a 45 degree angle. And even still, even with a greater than 1.0 gradient, the gradient has to be pointing in right direction to fail. So, it never fails just because a >1.0 gradient exists, but it requires a >1.0 gradient in order for it to fail.

NicoRi
30-Sep-2006, 21:18
Anyone who has tried to see how far bump mapping can go by increasing the "strength" or height of their bump maps, knows what I mean. You can only go so far before the visuals stop making sense.

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

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.

Matthew Doucette
30-Sep-2006, 23:13
Yes, this is because bump mapping is basically only a fake... ;-)
Indeed!

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.

Matthew Doucette
30-Sep-2006, 23:46
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.

NicoRi
01-Oct-2006, 11:03
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. :)

Matthew Doucette
01-Oct-2006, 17:15
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.

Matthew Doucette
02-Oct-2006, 04:56
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!

NicoRi
02-Oct-2006, 21:43
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. ;-)

Matthew Doucette
02-Oct-2006, 23:42
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.

Simon F
03-Oct-2006, 16:59
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 :-)

Matthew Doucette
03-Oct-2006, 17:29
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.

NicoRi
03-Oct-2006, 22:14
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...

Matthew Doucette
04-Oct-2006, 03:47
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 (http://www.worley.com/) (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! :)

NicoRi
04-Oct-2006, 08:03
I am trying to contact Steven Worley (http://www.worley.com/) (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? ;-)

Matthew Doucette
04-Oct-2006, 18:59
Cool. By the way, do you have a job for me? ;-)
Sorry no!! (Did I miss something?!)

NicoRi
04-Oct-2006, 20:36
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.

Matthew Doucette
05-Oct-2006, 01:01
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.

NicoRi
05-Oct-2006, 09:52
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.

Matthew Doucette
05-Oct-2006, 19:21
It is off topic, so hit me in email: http://xona.com/matthewdoucette/