Search code examples
vectorgraphicslinear-algebracomputational-geometry

Calculate Normals from Heightmap


I am trying to convert an heightmap into a matrix of normals using central differencing which will later correspond to the steepness of a giving point.

I found several links with correct results but without explaining the math behind.

  T
L O R
  B

From this link I realised I can just do:

Vec3 normal = Vec3(2*(R-L), 2*(B-T), -4).Normalize();

The thing is that I don't know where the 2* and -4 comes from.

In this explanation of central differencing I see that we should divide that value by 2, but I still don't know how to connect all of this.

What I really want to know is the linear algebra definition behind this. I have an heightmap, I want to measure the central differences and I want to obtain the normal vector to use later to measure the steepness.

PS: the Z-axis is the height.


Solution

  • From vector calculus, the normal of a surface is given by the gradient operator:

    enter image description here

    A height map h(x, y) is a special form of the function f:

    enter image description here

    For a discretized height map, assuming that the grid size is 1, the first-order approximations to the two derivative terms above are given by:

    enter image description here

    Since the x step from L to R is 2, and same for y. The above is exactly the formula you had, divided through by 4. When this vector is normalized, the factor of 4 is canceled.

    (No linear algebra was harmed in the writing of this answer)