I often use a 2D Perlin noise texture to displace a grid in the vertex shader (e.g. terrain, ocean). However, every time I google the method to calculate post-displacement normals there is a slight difference. For example, the value to place in the Y-component varies depending on the source. In this example, they place a '1' in the Y-component prior to normalization:

Real-Time Parametric Shallow Wave Simulation | Intel® Software

Whereas in these codes, the value '2' is chosen:

Terrains, Normals, and a Heightmap | dian-xiang.com/blog

What gives? Is there a definitive source for calculating normals from a height map?

Might this be related to unprojecting mouse clicks? It always bothered me that you could throw a '0.5' in the Z-component, as mrdoob mentioned here:

Three.js Projector and Ray objects | Stack Overflow

Or use a '1' in the Z-component as Anton does here:

Mouse Picking with Ray Casting | Anton's OpenGL 4 Notes

Is there a connection between calculating normals from height maps and unprojecting mouse clicks?

The second part of my question concerns choosing an epsilon to sample the height map. Before I learned about height maps, I read about getting the normal from an implicit surface as in this link:

Fractals, computer graphics, mathematics, demoscene and more | Inigo Quilez Blog

It seems like the epsilon number is just made up though. In my projects, I typically just fudge the value until it looks good. Is there a definitive source, or at least a good rule of thumb?

  • 1
    $\begingroup$ The divide by 2 is because you're taking the neighbouring vertices height, which happen to be 2 units apart (see the diagram in your second link which lables in/out and left/right neighbour vertices). It's to normalise height (Y) with X/Z. $\endgroup$ – PaulHK Feb 23 '17 at 9:11

The Epsilon is chosen to hit the appropriated Nyquist-Frequency avoiding aliasing. It refers to the highest frequency in your heightfield function. You'll need well knowledge of the definition of your function to find it. For example, the figure shows an iterated Brownian motion (IBM) which approximate Perlin noise. The frequency of each added noise function is given by . So the Epsilon would be the last added frequency: \frac{1}{2^{N-1}}. That means the Epsilon is predefined for each Noise.

enter image description here

IBM by Hugo Elias approximating Perlin Noise.

Might this be related to unprojecting mouse clicks? It always bothered me that you could throw a '0.5' in the Z-component, as mrdoob mentioned here:

Your first question has nothing to do with mouse picking in my opinion. Your mouse is defined in normalized-device-coordinates (NDC) meaning a click in a window is ranging from -1 to 1 in each direction. The Z component is not given since our screen is just 2-dimensional, meaning we have to select a value from -1 to 1. -1 refers to the near plane and 1 to the far plane.

For further information on that topic: https://www.youtube.com/watch?v=DLKN0jExRIM&t=371s


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy