Rob,
Here's the mathematical version of normals. Your water lies on this surface:
y = -1.2 * Sin( freq + x*500 + z*300 )
The first step is to reformulate this as
y + 1.2 * Sin( freq + x*500 + z*300 ) = 0
We now have the form F(x,y,z)=0.
The gradient vector, which is perpendicular to this surface, is
( dF/dx, dF/dy, dF/dz )
where e.g. dF/dx denotes the partial derivative of F with respect to x.
NOTE: d is not the correct symbol for partial derivative.
The proper one looks like a flipped over 6, but we don't have that on our keyboards.
Finally, we need partial derivatives, e.g.
dF/dx = 1.2 * (Pi/180) * 500 * Cos( freq + 500 * Vertex(i)\x# + 300 * Vertex(i)\z# )
Here is your vertex code, updated to calculate normals:
s=GetSurface(water,1)
A# = 1.2 * (Pi/180) * 500
B# = 1.2 * (Pi/180) * 300
For i=0 To CountVertices(s)-1
u# = freq + 500 * Vertex(i)\x# + 300 * Vertex(i)\z#
Vertex(i)\y# = 1.2 * Sin(u)
VertexCoords s,i, Vertex(i)\x#, -Vertex(i)\y#, Vertex(i)\z#
; Now the gradient at point (x,y,z)
C# = Cos(u)
nx# = A * C
ny# = 1
nz# = B * C
; (nx,ny,nz) is the gradient, which is perpendicular to the surface.
; It has length greater than 1, but that is probably harmless.
; If there is any problem you can scale to length 1 before doing:
VertexNormal s, i, nx, ny, nz
Next
This hasn't been tested, but it should work.
You can see how much simpler the gradient calculation is than doing vector cross products.
The only hard part is that you need to know some elementary calculus.