Monday, December 17, 2012

Code, Video and Paper

Deformable Terrain

I have added an algorithm to blast off (destroy) terrain based on user input. I am using the following algorithm to achieve the same.

  • When the user clicks on the output screen, depending on the coordinates, a ray is generated from the camera into the screen.
  • This ray is traced for a random distance and then the terrain at that location is marked for destruction.
  • A random radius is generated.
  • The center and the radius of the circle to be destroyed are stored in an array and passed to the Tessellation Evaluation Shader (TES).
  • The TES flattens the height based on some value generated using Perlin noise.
  • The TES then perturbs the vertices by small amounts to give the destroyed area some random shape.
The number of deformations are currently limited by the array size as the 4.0 shaders do not allow dynamic arrays. 
The red ellipse above shows the destroyed part of the terrain

Friday, December 14, 2012

Heightmaps

Until now I was generating terrains using Perlin noise. Won't it be nice to generate terrain based on your needs. In comes heightmaps. Made few small changes and got the program to load heightmaps. Below is terrain generated using a height map of some place in Norway (from USGS maps)

The height map used - West Norway

Terrain using height map 

As you can see, I displaced the water a bit to give some effect. But have to apply a water shader to make it look like water.

Thursday, December 13, 2012

Adding more substance

Added fog to the terrain, to give a better feel and better feel of the depth of terrain. I added a linear fog based on depth and used the smoothstep and the mix functions to get the effect of fog.

Fog based on depth

Then I pictured that while travelling by flight, you see a lot of fog down in the lower areas in mountainous regions and the peaks just stand out of the fog. So I went ahead and implemented fog based on height. The lower the terrain, the thicker the fog is. Below is what I got as the output.

Fog based on height above ground

Combining both of these, gives the effect as seen below.

Next Steps:
  • Deform terrain
  • Load a heightmap

Screen based rendering

To implement any screen space algorithms, I needed to have mutpli rendering passes. The first pass will cover all that I did as mentioned below and then the second pass will work in screen space.

I attacjed the outputs from the fragment shaders to different textures and then passed it on to the next rendering cycle. The depth buffer values were attached to a texture as well as positions, normals and colors. In the second pass, I just create 2 screen space triangles and then used the values from these textures to determine what gets shaded and what doesn't. Though I had done something similar as part of another assignment, this was a good learning experience for getting the 2 passes to work correctly. Once the 2 passes were running smoothly one after the other, I implemented the algorithm to get normals using the screen space. The algorithm takes the values of the neighboring pixels and then finds the world space coordinates for these pixels. Then taking the difference of values in the x-direction and taking the cross product with values in the y-direction, gives the normal for the terrain, The normals have to be handled with special cases at the edges because the neighboring pixels may have a completely different depth at the edges.

Screen Space Ambient Occlusion using Poisson disk

Tessellation based on distance


As mentioned previously, I got my tessellation working, but it tessellated the entire geometry. So then I went on to implement a distance based tessellation. The goal was to have multiple levels of tessellation based on distance from camera. So I separated out the distance between the near and far planes and did a gradual tessellation based on distance. This speeds up the frame rate of display. It increased quite a bit. I was getting about 6-9 fps which increased to around 40-50 fps.

Then I realized that I was just basing my tessellation on z-distance and the terrain was getting tessellated on the left and the right. I think clipping happens later, so the terrain is tessellated even if it is out of view, though it doesn't get rasterized. So I then went on to calculate which vertices actually lie in the frustum of the camera and made sure that only those vertices get tessellated. Even this gave me a 4-5 fps increase.

The image and video below shows the tessellation of the terrain. This is just a constant tessellation for display, but I have modified it to tessellate to certain distance and then keep on decreasing tessellation as we move further away.

Tessellation based on distance from camera

Video shows tessellation based on distance from camera

Next steps:
  • Ambient Occlusion
  • Screen space normals