# FFT to obtain heightfield normals

This topic is 4840 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I've implemented a FFT-based method to animate heightfields, and then the normals are computed using finite differencing between nearby grid points. It works, but now I realize that I only need the normals for rendering (normal mapping). I've read a paper saying that for computing normals we just need to use another FFT (with minor change to the original one used for heights). My question is, after FFT you gets a complex number for each grid point, so how to map this complex number to a 3D normal vector?

##### Share on other sites
I'd expect that with method described in paper, you get gradient of heightfield, i.e. derivatives (dh(x,y)/dx and dh(x,y)/dy) (where h is heightfield function). (Though, it can be something different, I haven't seen paper you talk about)

I suppose you know how to compute normal from height derivatives.
But some explanation anyway: vector (-dh(x,y)/dx,-dh(x,y)/dy, 1) assuming z points to up is orthogonal to land. You only need to normalize it.

##### Share on other sites
Thanks for reply. So it means the horizontal and vertical gradients are stored in the real and imaginary parts respectively (I'm not sure about it before), and the normal is derived from them.
Btw, the paper I mentioned is the deep water animation & rendering paper on gamasutra (1st hit on google).

##### Share on other sites
Quote:
 Original post by gamelifeThanks for reply. So it means the horizontal and vertical gradients are stored in the real and imaginary parts respectively (I'm not sure about it before), and the normal is derived from them.Btw, the paper I mentioned is the deep water animation & rendering paper on gamasutra (1st hit on google).

Yes, by idea, ∇h(X,t) note for internet explorer users: character in front of h might not display correctly. It should look like upside-down-delta aka nabla should mean gradient by X. Though, I'm is not entirely sure it is computed correctly by that formula.
Anyway, it's rather simple to derive. Just note that ei K.X =
cos(K.X)+i*sin(K.X)
so
h(K,t)* ei K.X =
h(K,t).re*cos(K.X)+i*h(K,t).re*sin(K.X)+i*h(K,t).im*cos(K.X) - h(K,t).im*sin(K.X)

where .re denotes real part and .im imaginary. K.X stands for vector dot product of K and X

I am assuming the heightfield, H(X,t) is real valued, i.e. we ignore imaginary part. (big H to not confuse with their h with ~ ontop.)

So we have
H(X,t) = sum h(K,t).re*cos(K.X) - h(K,t).im*sin(K.X)
and we must find gradient of right part of sum
h(K,t).re*cos(K.x*X.x+K.y*X.y) - h(K,t).im*sin(K.x*X.x+K.y*X.y)
so we get d/dx=
-K.x*h(K,t).re*sin(K.x*X.x+K.y*X.y) - K.x*h(K,t).im*cos(K.x*X.x+K.y*X.y)
and d/dy=
-K.y*h(K,t).re*sin(K.x*X.x+K.y*X.y) - K.y*h(K,t).im*cos(K.x*X.x+K.y*X.y)

-K*(h(K,t).re*sin(K.x*X.x+K.y*X.y) + h(K,t).im*cos(K.x*X.x+K.y*X.y)) =
K*((i*h(K,t)*ei*K.X).re)

Sooo... their formula is sort of correct, BUT as far as I can see, you must be very careful not to confuse vectors and complex numbers.
I.e. as they wrote it,
i*K*h(K,t)*ei*K.X).re
it'll work only if you treat vector as 2 _real_ numbers, so in result you get vector consisting of 2 _complex_ numbers (!!!) I.e. like (a+b*i,c+d*i) and real parts give gradient, and imaginary to be ignored.
(I might be wrong but I think I'm isn't.[grin])

##### Share on other sites
Okay, if I understand correctly, it is equivalent to using two FFTs, one for each direction. I originally thought that I could compute normals quickly by just one FFT :/

Thanks again~~~

##### Share on other sites
Maybe it can be implemented at cost of one FFT, just i'm is not sure how, and paper doesn't get into details either...

1. 1
Rutin
34
2. 2
3. 3
4. 4
5. 5

• 12
• 14
• 9
• 9
• 9
• ### Forum Statistics

• Total Topics
633331
• Total Posts
3011399
• ### Who's Online (See full list)

There are no registered users currently online

×