i calculate the normals like this:
Code:
// linear interpolation based
PVector[][] normals = new PVector[SIZE][SIZE];
void setNormals() {
for (int y = 0 ; y < SIZE ; y++) {
for (int x = 0 ; x < SIZE ; x++) {
// edge normals point straight up
if (x == 0 || y == 0 || x == SIZE - 1 || y == SIZE - 1) {
normals[x][y] = new PVector(0, 0, 1);
continue;
}
// cross product of neighbours
PVector v1 = new PVector(2.0, 0.0, grid[x + 1][y] - grid[x - 1][y]);
PVector v2 = new PVector(0.0, 2.0, grid[x][y + 1] - grid[x][y - 1]);
normals[x][y] = v1.cross(v2);
normals[x][y].normalize();
}
}
}
and added this to bottom of draw to show the normals (mostly for debugging, hence the condition at the top)
Code:
if (showNormals) {
for(int x = 0 ; x < (raio * 2) ; x++) {
for(int y = 0 ; y < (raio * 2) ; y++) {
int q = 5;
stroke(255, 0, 0);
line(
x * q, y * q, -grid[x][y] * q,
(x * q) + (10 * normals[x][y].x), (y * q) + (10 * normals[x][y].y), (-grid[x][y] * q) - (10 * normals[x][y].z));
}
}
and the main drawing beginShape() contents now looks like this with the normals added in
Code:
normal(normals[x][y].x, normals[x][y].y, normals[x][y].z);
vertex(x * q, y * q, -grid[x][y] * q);
normal(normals[x][y + 1].x, normals[x][y + 1].y, normals[x][y + 1].z);
vertex(x * q, (y + 1) * q, -grid[x][y + 1] * q);
normal(normals[x + 1][y].x, normals[x + 1][y].y, normals[x + 1][y].z);
vertex((x + 1) * q, y * q, -grid[x + 1][y] * q);
normal(normals[x + 1][y].x, normals[x + 1][y].y, normals[x + 1][y].z);
vertex((x + 1) * q, y * q, -grid[x + 1][y] * q);
normal(normals[x][y + 1].x, normals[x][y + 1].y, normals[x][y + 1].z);
vertex(x * q, (y + 1) * q, -grid[x][y + 1] * q);
normal(normals[x + 1][y + 1].x, normals[x + 1][y + 1].y, normals[x + 1][y + 1].z);
vertex((x + 1) * q, (y + 1) * q, -grid[x + 1][y + 1] * q);