t(x,z) := d y(x,z) / d x

b(x,z) := d y(x,z) / d z

then t denotes the rate of change of y when stepping in direction of x, and analogously b denotes the rate of change of y when stepping in direction of z. Written as vectors, you'll choose the unit length 1 for the step in direction of x or z, resp., and t or b for the corresponding change of y, i.e.

**T**(x,z) := [ 1; t(x,z); 0 ]

**B**(x,z) := [ 0; b(x,z); 1 ]

The cross product of these 2 vectors gives you the normal. However, you have 2 possibilities

**T**x

**B**and

**B**x

**T**, but only one is valid for your purpose (depending on your choice of co-ordinate system). Above you've chosen

**N**(x,z) :=

**B**(x,z) x

**T**(x,z) = [ -t(x,y); 1; -b(x,z) ]

It has to be normalized, of course.

So what does this mean w.r.t. some picked slopes?

a) For a flat height field you'll get

y(x,z) = c ==> t(x,z) = 0; b(x,z) = 0 ==>

**N**(x,z) = [ 0; 1; 0 ]

b) For a wave in x direction only you'll get at a position with slope of 45° (i.e. increasing)

t(x,z) = 1; b(x,z) = 0 ==> N(x,z) = [ -1; 1; 0 ]

c) For a wave in z direction only you'll get at a position with slope of -45° (i.e. decreasing)

t(x,z) = 0; b(x,z) = -1 ==> N(x,z) = [ 0; 1; 1 ]

This seems me okay.

Now, there are some mistakes in your pre-previous post:

1. Notice that normals are not invariant to non-uniform scaling.

E.g. scaling the height by a factor of 0.25 is non-uniform, because it has an effect on y only but not on x and z. If you scale y(x,z) by s and compute

**N**as above, you'll see that

**N**'(x,z) = [ -t(x,y) * s; 1; -b(x,z) * s ] !=

**N**(x,z) * s

2. The 1st sin() is scaled by 50, while the 1st cos() is scaled by 150.

3. The argument in the 3rd sin() has a frequency of -fs/4, but the factor of the 3rd cos() shows -fs only.

4. The argument in the 4th sin() has a frequency of -fs/8, but the factor of the 4th cos() shows -fs only.

5. The wave function depends on both x and z position, but you compute only one derivative and use it for both directions.