Vector3 CalculateNormal(int u, int v)
{
// Value from trial & error.
// Seems to work fine for the scales we are dealing with.
float strength = scale.Y / 16;
float tl = Math.Abs(this[u - 1, v - 1]);
float l = Math.Abs(this[u - 1, v]);
float bl = Math.Abs(this[u - 1, v + 1]);
float b = Math.Abs(this[u, v + 1]);
float br = Math.Abs(this[u + 1, v + 1]);
float r = Math.Abs(this[u + 1, v]);
float tr = Math.Abs(this[u + 1, v - 1]);
float t = Math.Abs(this[u, v - 1]);
// Compute dx using Sobel:
// -1 0 1
// -2 0 2
// -1 0 1
float dX = tr + 2 * r + br - tl - 2 * l - bl;
// Compute dy using Sobel:
// -1 -2 -1
// 0 0 0
// 1 2 1
float dY = bl + 2 * b + br - tl - 2 * t - tr;
Vector3 N = new Vector3(dX, dY, 1.0f / strength);
N.Normalize();
//convert (-1.0 , 1.0) to (0.0 , 1.0), if necessary
//Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);
//Vector3.Multiply(ref N, ref scale, out N);
//Vector3.Add(ref N, ref scale, out N);
return N;
}