Tessellation
Rendering with hardware tessellation allows to drastically increase the complexity and detailing of geometry as well as get finely contoured shadows given only a rough low-polygon model in the game. This technology is scalable, quick due to hardware acceleration and easy to use. It also makes creation of art assets much more convenient and faster: each intermediate LOD of the model no longer needs to be created by hand; instead, they will be generated automatically.
Hardware Requirements
Hardware tessellation is only available on:
- DirectX 11 (use d3d11_render_use_tessellation console command to enable tessellation)
- OpenGL 4.0 (use gl_render_use_arb_tessellation_shader console command to enable tessellation)
You can also see tessellation in full action in the Heaven benchmark.
Tessellation Pipeline
Hardware tessellation is a scalable technology that subdivides polygons into a number of higher detail primitives on the fly depending on their distance to the camera. As tessellation is implemented in GPU hardware of DirectX 11 or OpenGL 4.0 level, it can perform these operations together with displacement mapping very quickly and generate a stunningly much richer visual detailing. As the result, the work is off load from the CPU to the GPU, load times decreases and it becomes possible to render more complex models and realistic animated characters.
The Unigine engine uses specific shaders for rendering tessellating materials. After one of them is assigned to a model, and displacement and tessellation density textures are fed to the engine, the processing is performed in hardware. In detail, the tessellation pipeline is as follows:
- During the first stage, polygons of the low-poly control mesh are automatically subdivided basing on:
- adjustable tessellation factor (how finely to tessellate),
- distance to the camera (further-away polygons will be less tessellated then close-by ones),
- tessellation density map (indicates areas artists want to be less tessellated).
Using these control points, a tessellator subdivides each edge of the triangle patch and creates a number of new small triangles instead of one input big triangle. To put it short, the control shader tells the tessellator how much to tessellate and the tessellator performs the subdivision. - Then comes the turn of tessellation Evaluation shader (aka the Domain shader). It looks up the displacement texture and specifies the position of generated vertices.
After the camera has moved from the model far away enough, the tessellation factor decreases down to 1, indicating that input triangles do not need to be subdivided. When this happens, the tessellating material is automatically switched to its non-tessellating version with lighter shader, and the model is rendered as a simple low-poly mesh.
Terrain Tessellation
Tessellating a terrain has its own peculiarities. Its flat triangles are tessellated into smaller triangles, while normals of new vertices are interpolated to create a smooth curve. It will not re-sculpture terrain's relief — tessellation will only soften its shape. If in the source terrain normals of two adjacent vertices are pointing in the same direction, tessellated surface will stay flat. If normals are directed differently, the tessellated surface will be rounded.
Setting Up Tessellation
Setting up tessellation is quite easy. For that you need:
- Tessellation is enabled by default. If not, do the following:
- In the console type d3d11_render_use_tessellation 1 (for DirectX 11) or gl_render_use_arb_tessellation_shader 1 (for OpenGL 4.0).
- Then type render_restart.
- Assign one of the tessellating materials to the low-poly model:
- mesh_tessellation_base
- mesh_tessellation_indirect_base
- mesh_tessellation_reflection_2d_base
- mesh_tessellation_reflection_cube_base
- mesh_tessellation_reflection_fresnel_base
- mesh_tessellation_paint_base
- mesh_tessellation_paint_reflection_cube_base
- Specify a height map for displacing vertices.
- Use a tessellation density map to optimize performance.
- Tweak tessellation parameters.
For a step-by-step guide see Using tessellation tutorial.
Usage and Benefits of Tessellation
Tessellation allows achieve stunning visual results that are unprecedented for in real-time. Unlike the bump mapping or parallax mapping that merely fakes relief changing, tessellation really modifies mesh topology. It can be used to gain the following.
- Adding displaced details for refinement. At last the rendered result can fully coincide with artist's conception. In-game objects look drastically more realistic due to increased number of polygons generated on the fly. For example, it was possible to render a dragon with all impressive spikes jutting out, while using only the low polygon count model and a height map.
Non-tessellated model is a simple coarse mesh without details.Tessellated model has increased detailing.
- Smoothing of curved shapes. With tessellation you can forget about pointy and edgy-looking spheres.
Non-tessellated model looks edgy.Tessellated model with smoothed curves.
- Contouring and embossing of flat surfaces. Tessellation can be effectively used on both flat and curved surfaces unlike parallax mapping that is strictly limited to flat ones. Tessellation is not an illusion of displacement. No matter from what angle the tower wall is looked at, its stonework bulges forward. There will be no artifacts, as each and every stone was really displaced, which is especially noticeable in the profile view.
Non-tessellated model is flat in profile.Tessellated model is embossed and finely contoured.
- Adjoining edges of tessellated surfaces look much more realistic and credible due to a lot of high-frequency details. The seam where two tessellated surfaces or objects adjoin is shaped completely automatically, without artists having to adjust it manually.
Non-tessellated model.Tessellated model. Adjoining edge is shaped automatically.
- Realistic shadows. Tessellated objects cast and receive accurate and finely contoured shadows as high-poly models. They are realistic to the smallest detail.
- Dynamic level-of-detail. No more irritating popping and flickering as discrete LODs are switched one by one. With tessellation, the number of polygons smoothly changes depending on distance to the object. While the actual mesh fed to the engine stays the same, in-game model has complex geometry when the camera is nearby it and becomes coarse as it moves away. At a certain point the tessellation is simply turned off for better performance.
- Creation of art assets is faster and simpler. In most cases, all you need for tessellation is a low-poly control mesh that will be tessellated and its high-poly model necessary to create a displacement map. That is it. There is no need to create a number of middle-poly models by hand and set up LODs, as they will be generated automatically.
It may still be reasonable to create distant LODs with lower polygon count than a control mesh to optimize performance.
- Geometry can be modified as easily as textures. This especially applies to tiled surfaces: you can transform texture coordinates to get another geometry in one click. For non-tiled objects, simply alter UV map for a different geometric profile.
Changing tile creates different geometry in one click.
- Protruded decals. Without tessellation, these windows are completely flat decals. When tessellated, they stand out in sharp relief protruding from the walls. Now it is extremely easy create loopholes, doors, crevices on the surafce and regulate how far they bulge out. Besides that, tessellated decals both cast and receive accurate shadows, while by parallax mapping it is impossible to achieve that.
As tessellated decals are imprinted into the surface as well, it is necessary to cut out geometry underneath them.Non-tessellated decals are flat.Tessellated decals have relief and can both cast and receive shadows.
- Saved bandwidth and storage space. If compared to using middle-poly meshes in the game, tessellation allows for rougher low-poly meshes that are transformed into high-poly looking ones at interactive frame rates. It means, their load time along with storage requirements decrease.
- Skinned mesh animation is less costly with tessellation. A rough low-poly mesh with fewer number of vertices is animated and only after that the result is tessellated into a more detailed and smoothed high-poly mesh.
Issues and Problem Solving
There are a number of limitations encountered when using tessellation.
- From a performance standpoint, tessellation is not completely free of charge. Keep in mind that some performance decrease is imminent and optimize your content accordingly.
- Texture seams cause gaps and cracks in the tessellated model. When looking at it against the light, there can be visible small holes in geometry. These texture seams can appear due to different reasons:
- Different heights are sampled from the displacement map along the seam
- Differently directed normals (along the seam or when two smoothing groups are present)
Texture seams are hardly avoidable; they can only be minimized or hidden. Whenever there is a discontinuity in tangent space, a crack is possible to appear when the model is tessellated. However, there are several workarounds to deal with seams:
- Normals should be co-directed. Use one smoothing group, because the less discontinuities there are, the better.
- Use a square UV map. It will eliminate the problem with sampling different heights along the seam.
- Cover the gap with a decoration detail above the seam.
- Place a dummy mesh inside. Dummy mesh basically dubs a low-poly mesh, but it is even smaller and rougher. A dummy is placed inside a low-poly and is exported it as its separate surface.
Dummy surface inside the low-poly mesh. Seams are in green.For a dummy a non-tessellating variant of material can be created, if necessary. Being enabled, it covers the gaps from inside.Texture seams cause gaps in geometry.Gaps along texture seams are covered by an inside dummy.
- Insufficient number of polygons of the low-poly mesh. Sometimes the polygon partitioning of the mesh fed to the engine is not enough to render all desired details. In this case, polygons are subdivided until the mesh becomes dense enough. If the model is made together with LODs, added primitives can be easily removed right in the first LOD that comes after the tessellated low poly, without noticeably changing any geometry.
In case the mesh density has been increased, excessive polygons slow down performance on graphics cards without tessellation.Source mesh with an increased number of polygons.Tessellated model has fine details.
- In the non-tessellating mode (or if the graphics card does not support it), art content oriented to tessellation looks harsh, as mere low-poly meshes are used.
- Placing decals onto tessellated surfaces can be problematic.
- Problems with physical destruction. If a tessellated object needs to be destructed in run-time (for example, a wall made of stone blocks is to be shattered to pieces), there can appear untextured gaps.
- Present-day consoles do not support tessellation.