Thursday, December 1, 2011

Tech Demo 2 - Trees, Rocks, Grass and Shadows

This demo shows the progress made in filling the landscape with natural objects such as foliage and rocks



2x2km high res texture terrain showing GPU & CPU instancing, shadows and long draw distance.

Looking at the video time index:

0:06 6,000 Low LOD trees and 200 high LOD tree trunks and 200 high LOD leaf canopies are introduced. Turning on the 6,000 low LOD trees gives a performance of approx. 850fps. During early development up to 500,000 trees where tested which gave a performance of 60fps with the large terrain also rendered. This opens up the distinct possibility for effective high detail real time physics simulations once nVidia PhysX is implemented.

0:14 Rocks are rendered (approx 200 over a 200x200m patch) via CPU instancing to allow for collision detection.

0:20 Grass meshes are rendered, approx 2500 over a 140x140m via GPU instancing (no collision detection required). I think there needs to be larger grouped patches of grass, perhaps further apart. Analysis of the top modern engines show a greater degree of local terrain undulation adds greatly to the perceived detail in the scene. At this point the engine is performing well and it's just down to an artistic touch now.

0:46 - 1:04 Shows animated grass and leaf canopies swaying in the wind. This adds slightly to the load on the GPU, but makes for a more dynamic scene. The canopy animation is exaggerated to show the effect.

1:53 An overhead view of the Shadow class ready for implementation, showing high quality shadows tracking with the camera. These shadows have a draw distance of approx 200m as opposed to about the 50m commonly seen, or even the amazing 30m seen in a recently anticipated and well received game engine.

1:56 The video ends with a track back revealing the whole terrain with trees drawn up to the 2km boarder. Many of the most modern engines use fog and / or hills in the case of indie engines, or generally mountains, high rocks or hilly terrain in the case of top quality engines to realistically reduce the draw distance to a few 100m for at most. In some cases the draw distance is increased by the sparse use of alpha blended textures for grass, bushes and tree canopies for example, to reduce the overall render load.

This represents a significant step as it involves quite a few concepts, all of which must be optimised to maintain rendering performance.

The first concept to consider is GPU instancing. Generally when a mesh is rendered the data defining the structure is sent to the graphics card every time it is drawn (a draw call), that is once every frame for each drawn mesh. So if you have 6,000 trees (as shown in this demo), that's 6,000 separate draw calls  per frame. This would have a significant impact on performance.

It is now possible via GPU programming (Shaders) to pass 2 data streams to the GPU. One containing the data for the mesh structure and one containing data on how to repetitively draw the same mesh with various differing properties, such as position, scale, rotation and colour for example. As you can manipulate the mesh in this way, you can also add animation to simulate grass or leaves blowing in the wind, all with a low performance impact. This method is used primarily for tree canopies and grass as other meshes such as characters, projectiles and cameras can realistically pass though these objects (basic collision detection is tested for on the CPU and not normally the GPU - at the moment). Mesh instancing can be particularly tricky to implement as the fault intolerent GPU streams are sensitive. Edge goes a step further an implement a method to actually create GPU instancing from a mesh loaded from the hard drive, again particularly tricking to get working as a re-usable class in a re-useable DLL, something rarely seen in current engines.

Another concept is CPU mesh instancing, as opposed to GPU mesh instancing (described above), CPU mesh instancing involves a source mesh being loaded into memory and then redrawn with differing parameters (scale, position, rotation, textures) in separate draw calls. The advantage here is, as the mesh is processed on the CPU it is exposed to the 3D graphic drivers' collision detection algorithms. It is therefor useful for scene objects such as rock and tree trunks with which characters, projectiles and the camera will interact.

As the camera moves through the scene all these components must be managed with  LOD (Level Of Detail) scene management. This operation is many-fold. Far off objects. such as low LOD trees must be turned off and replaced with higher LOD tree trunks and canopies as the camera approaches them. Tree trunks and rocks must be switched on and grass must be destroyed from out of distance grids to the rear and built in within distance grids to the front, quite a complex set of operations.

The shadows you can see towards the end of the video have been developed and tested, they just need the final implementation and testing in the engine. 

The video ends with a full view of the terrain with far distance trees distributed with a moderate to high density, showing the engine performance even with a large terrain and long draw distance. All these trees are also animated and swaying in the wind.





No comments:

Post a Comment