Gradients and Choppy waves.
As mentioned in the last post, the focus of the last days was to fix proper normal calculations using the gradient of the height-field. Gradient, together with creating a displacement in x and z-direction, only required setting up a four more cuda-buffers and performing an inverse FFT-pass on each of them.
Calculating the gradient and the x-z displacement is easy, and comes from equation 20 and 29 in Tessendorf's paper, which you should be familiar with now. The input for calculating the x-gradient and z-gradient simply meant multiplying the input for the displacement map with the imaginary number ik, for each k where k is the propagation direction of the wave at each point.
Formula for gradient calculation for realistic surface normals (Tessendorf 2001)
One problem that occurred when calculating the surface normals using the gradient values was that the result of the FFT is naturally rather small. So when applying the normal calculation formula provided by Fredrik Larsson the result was that almost all normals pointed close to straight in y-direction. To solve this, I had to manually normalize the values, which I have not seen anybody else do in their ocean simulators. However, by calculating the largest and smallest gradient values in x and z-direction, followed by dividing all gradients in both direction by the value with largest magnitude in each direction, I was able to normalize the gradients to a range between -1 and 1, which gave a reasonable result.Formula for calculating normals given gradient function. (Larsson 2012)
Gradient normalization as the result of equation 20 naturally had values in a range of 0.03 to -0.03, causing the y-value to dominate in most vertices.
Each point x = (x, z) in the grid is then displaced by the formula x + lambda * D(x, t), where lambda is a negative constant to control the choppiness. One problem when having a large choppiness is that the wave tops may behave oddly. When displacing points in for example x-direction, so that points to the left are pushed to the right, and points on the right are pushed to the left, then points that are already very close to each other may cross. The consequence of this, is that on all points (in y-direction) above this intersection, the surface normal will be pointing inwards/downwards, causing those points/triangles not to be rendered if back-face culling is enabled. If these effects occur, decreasing the magnitude of lambda is necessary.
Another interesting point, which for me caused a rather oddly looking graphical bug, is that if lambda is positive, the effect will be inverted, causing the waves not to look choppy, but rather shubby. The result was rather interesting, and got me wondering if this algorithm could be used for simulating realistic looking clouds or smoke.
The final result after all calculations is something I am starting to feel a little proud of, and I am glad to present it here now.
The grid can be rendered easily at interactive rates at around 60fps for a grid size of 256x256 on my Nvidia 1070 and Ryzen 1600X. However, when increasing the grid size to 512x512, the frame rate drops significantly to about 20fps, which still could be considered interactive, but does not by far look as smooth.
Next up
* Skybox reflections
* Refraction
After that is done, I will mainly just strive to create an interesting environment as well as refactor the application so that it can be more easily configured. In the best case, I would want to integrate some kind of GUI-library such as Imgui so that parameters can be changed live without having to restart the application.
Something I also noticed, that probably is out of the scope of the course I am currently taking, but is something that I am interested looking into further later, is aliasing in reflections. When the grid is tiled say 10x10 times, it becomes so large that normals on distant vertices are inaccurately calculated. To solve this, one would have to render a surface in much more detail than the current, which would not be interactive with the current implementation.
Another solution is to look into state of the art research on aliasing in water rendering. I managed to find the relevant paper "Temporal and Spatial Anti-Aliasing for
Kommentarer
Skicka en kommentar