geomipterrain.getNormal algorithm

i wonder whether getNormal() produce correct result:

as getNormal() request 2 INT type value, it calculates the normal at the location of a pixel in the heightfield image? not the location between pixels?

but there are 8 other pixels around a pixel, each has different brightness (meaning different heights), how can a pixel decide its normal?

It works bilinearly, which means that it uses the difference in height with 4 neighbouring pixels to calculate the normal vector.

The source is always your friend, so I copied the relevant method for you:

//     Function: GeoMipTerrain::get_normal
//       Access: Published
//  Description: Fetches the terrain normal at (x, y), where the
//               input coordinate is specified in pixels. This
//               ignores the current LOD level and instead provides
//               an accurate number.
//               Terrain scale is NOT taken into account! To get
//               accurate normals, please divide it by the
//               terrain scale and normalize it again, like this:
//               LVector3f normal (terr.get_normal(x, y));
//               normal.set(normal.get_x() / root.get_sx(),
//                          normal.get_y() / root.get_sy(),
//                          normal.get_z() / root.get_sz());
//               normal.normalize();
LVector3f GeoMipTerrain::
get_normal(int x, int y) {
  int nx = x - 1;
  int px = x + 1;
  int ny = y - 1;
  int py = y + 1;
  if (nx < 0) nx++;
  if (ny < 0) ny++;
  if (px >= int(_xsize)) px--;
  if (py >= int(_ysize)) py--;
  double drx = get_pixel_value(px, y) - get_pixel_value(nx, y);
  double dry = get_pixel_value(x, py) - get_pixel_value(x, ny);
  LVector3f normal(drx * 0.5, dry * 0.5, 1);

  return normal;

i see , thanks.
i thought the normal meant the normal of a polygon.

It uses vertex normals. Otherwise the terrain wouldn’t be smooth-shaded.
Every vertex corresponds to a pixel on the heightmap.