UnigineScript
The Language
Core Library
Engine Library
Node-Related Classes
GUI-Related Classes
Plugins Library
High-Level Systems
Samples
C++ API
API Reference
Integration Samples
Usage Examples
C++ Plugins
Content Creation
Materials
Unigine Material Library
Tutorials

Level Design

In short, there are two basic rules of thumb related to level creation that you need to adopt:

  • Jesse Ventura, a professional wrestler, said, "Win if you can, lose if you must, but always cheat." Surprisingly, this is true for level design, too. If you can fake without being caught red-handed, fake! Use all technologies that help you faking.
  • Everything that does not add to reality and feel of your game is superfluous. Everything that is superfluous tends to decrease FPS.

And now, more specific guidelines.

Requirements

The following advice are not strictly requirements, as you will be able to start your game anyway. However, if you do not follow them, you will probably get into serious trouble. So, here is the list of the most important aspects of level creation and optimization with Unigine.

  • Scale of the world is important. Unigine uses floating point coordinates, and precision of the float type is naturally limited. Therefore, if you create an ordinary world, stick to the scale 1 unit = 1 meter. If you use a larger scale, you may get problems with small objects, and if you use a smaller scale, large objects may lack precision.
  • World position is important. The reason is the same as in the previous case. It is better to place the center of the world around zero, because otherwise the most distant parts of the world might jitter.
  • File formats are important. This mainly refers to texture formats, as geometry can be loaded only in native Unigine formats. For all textures, use one of the DDS formats, unless you get visual artifacts.

    DDS formatUncompressed formatCompression ratioExamples
    ATI1N L8 2:1Gray scale textures.
    ATI2N LA8 2:1Normal maps.
    DXT1 RGB8 6:1 Diffuse maps, specular maps. One-channel height and ambient maps can also be compressed into this format (see the -d1 flag of ImageDDS).
    DXT3 RGBA8 4:1Diffuse maps with alpha testing/blending. Specular maps with reflection. This format does not interpolate alpha values (sharp alpha transitions).
    DXT5 RGBA8 4:1Diffuse maps with alpha testing/blending. Specular maps with reflection. This format interpolates alpha values (smooth alpha transitions).

    Note that all DDS formats compress images by 4×4 blocks, so smaller textures should not be compressed. ATI2 format is not supported by NV40 level hardware, under OpenGL this format is decompressed into the LA8 format and under Direct3D9 this format is decompressed into the RGBA8 format and it's the worst case.
  • Control your DIP count. The less is the DIP count, the faster the scene renders. It is cheaper to draw one large surface than to check visibility and LODs for a number of small ones; so, join surfaces and textures. Also, re-use the same meshes and materials as much as possible, as in this case the GPU will use instancing, and all alike objects will be drawn in one DIP.
    Notice
    DIP count and other statistics are available when UnigineEditor profiler is turned on (bound to the 1 key by default). If the number of surfaces is equal to the number of DIPs, then there are no instanced drawing calls. You should reorganize surfaces and materials if there is a bottleneck.

Guidelines and Tips

  • For indoor scenes, always use sectors and portals because they facilitate occlusion culling and are able to significantly increase performance.
  • Use occluders when possible to reduce number of drawn surfaces and materials.
  • Set up and use geometry LODs with appropriate materials. That is, turn off detail textures for coarser LODs or even assign other simpler materials, if a shader for the original LOD is rather complex.
  • Be careful with lights.
    • If possible, use static lighting, in Unigine you can combine up to three light maps. If dynamic lighting is required, try to combine it with the static one.
    • Remember that it is very important to choose a correct light source for dynamic lighting. The cheapest are projected lights, and the most expensive are omni lights. Try to reduce the number of lights, for example, you can use one cubemap modulated light to emulate several light sources.
    • Try to avoid overlapping of areas lit by different sources.
    • Create and use ambient textures for environmental ambient lighting.
    • Not all object have to cast or receive shadows. And don't forget that you can separately turn off shadows for non-world and world light sources. Also, turn off shadows for all distant objects (Render settings → Common → Shadow distance).
    • Use environmental lighting to increase ambient level without visual flatness of the scene. This reduces amount of required light sources.
  • Be careful with reflections.
    • Planar reflections in water and mesh_reflection_2d_base materials multiply the number of rendered primitives by two by default. If you can, remove shadows in reflections and use reflection masks (available both in material and surface settings).
    • Cube reflections in mesh_reflection_cube_base and mesh_indirect_base materials multiply the number of rendered primitives by six by default. To increase performance, you can update only several faces of a cube map and, of course, use tweaks described above.
  • Use NodeRef objects to decrease DIP count because this objects are always instanced. This can also save your time, if you need to change all alike objects at once.

Memory Consumption

We prepared several tables summarizing memory consumption by Unigine renderer. They will help you decide which settings are the most expensive and, therefore, should be used carefully.

Render Options

Below is a table showing memory use with different render options turned on. These options can be found in the main settings dialog (opened with the ESC key), in the Render tab. It is supposed that anti-aliasing is turned off.

Render optionMemory consumption
640×480 (lowest)1280×10241920×1200 (full HD)
All options unset3.5 MB14.1 MB26.4 MB
Occlusion+1.2 MB+4.7 MB+8.8 MB
Refraction+1.2 MB+4.7 MB+8.8 MB
Volumetric+0.6 MB+2.4 MB+4.4 MB
Glow+0.8 MB+3.6 MB+7.7 MB
DOF+0.4 MB+1.4 MB+3.8 MB
HDR+3.5 MB+8 MB+14.2 MB
All options set11.2 MB38.9 MB74.1 MB

Impostors

Here is a table demonstrating memory usage with impostors turned on.

render_impostor
value
Memory consumption
640×480 (lowest)1280×10241920×1200 (full HD)
LDR 12.7 MB10.5 MB15.9 MB
210.5 MB42.3 MB64.2 MB
342.3 MB168.6 MB256.8 MB
HDR 15.4 MB21 MB31.8 MB
221 MB84.6 MB128.4 MB
384.6 MB337.2 MB513.6 MB

Shadow Maps

The following table shows how much memory each light requires for a shadow map. All values are listed for default map sizes (in parentheses); if a smaller or larger map is used, memory usage decreases or increases proportionally.

Projected (1024)Omni/cube (512)World (1024)
No translucency4 MB6 MB16 MB
Translucency8 MB12 MB32 MB

Notice
If a light does not create shadows from a transparent object, its shadow map can be overwritten by other lights. But if the light creates such shadows, the corresponding shadow map cannot be re-used.
Last update: 2017-07-03