GSoC 2012 - Automatic adjustment of graphics level

From WorldForgeWiki
Jump to: navigation, search


I'm Arjun Kumar[[1]], and I'll be working on adjusting the performance of Ember automatically[2].


Currently to adjust performance, one can use the settings menu to adjust the various graphics settings. This menu does not contain a full list of graphics settings that can be altered. I will be implementing additional graphics altering features and adding them to a system that manages them automatically i.e. the system will try to maintain a playable FPS, set by the user, at all times.

A very basic example of this feature is: You walk into densely populated medieval village with lots of people, grass, shrubbery, buildings, fire etc. Now compared to an open vast land that you were in earlier, this new scene requires quite a bit more from your graphics card, and affects the FPS so much so that it drops to an unplayable rate. The system will try to compensate by lowering graphics detail of the various visible components. eg. Shrubbery shadow can be removed, the density of foliage lessened, level of detail of people can be lowered to use less performance intensive models/shaders etc.

Feature demos


Planned Features

Adding the ability to change:

Adding the above and following features to the automatic managing component:

  • Shadow level detail. (done, but requires testing with lower lod meshes)
  • A sweet GUI that shows how the automatic settings are performing and various adjustment options. (on hold, polishing code)
  • A warning to adjust the resolution if performance is lower than can be managed.


Here I'll be adding whatever I learn about Ember and it's various Ogre subsystems, how I've implemented the features, and what made me choose one way over another.

Basic Structure

The system consists of a three main classes:

  1. FpsUpdater: Monitors frame rate in frames per second (FpsUpdater), by listening for the frame start event and sends out FpsUpdated signals with the current FPS (frames per second).
  2. AutomaticGraphicsLevelManager : This is the central class that receives FPS updates and decides what decision to take. It works by determining how much graphics change is required when a drop or increase in frame rate occurs.
  3. IGraphicalAdapter: This is an interface class that interacts with all the graphics components by sending out a changeRequired signal. This acts as an interface between the AutomaticGraphicsLevelManager and the various graphics detail adjusting components.

Foliage Detail

Implementation class: Ember::OgreView::Environment::FoliageDetailManager

Factors that can be worked on:

  • Density i.e. number of plant and shrubbery entities.
  • Far distance i.e how far the entities are visible.
  • Shadow detail
  • Material techniques and lod.

The density was implemented by affecting the number of plants being loaded by the loader. There are two types of foliage loaders currently used by Ember, GrassLoader and FoliageLoader. Loaders are used to prepare pages utilized by the page managing component.

The GrassLoader is used to load grass into pages, by accessing the terrain and foliage definitions and adding the grass entities. This loader already had the density member. Due to Ember needing a custom implementation of how it fetches foliage definitions from the store, the density value was unimplemented. This affect was added by multiplying the density to the total plant count and then letting the loader only add plants till the count was reached.

The FoliageLoader is used to load miscellaneous Shrubbery into pages in a similar way to the GrassLoader. This is a completely custom made Loader. It was missing the ability to have and use density. This was added and then used in the same way as the GrassLoader density.

Far Distance
Far distance for foliage is changed by retrieving the distance details of the foliage page types added to the foliage PageManager and changing them.

For every detail level (eg. Batch page, Grass Page, etc.) there are three different distances defined: Far Distance (the maximum distance the page type is used at), Near Distance (the minimum distance from the camera the page type is used at) and the transition distance (the distance after the far distance that the page type melds into the next page type).

These details are retrieved and stored into a structure owned by the foliage (grass or shrubbery), and every time a distance factor is passed the new values for the page types are set by multiplying the factor to these stored values.

Shadow detail, Material techniques and lod These are left to their own managers instead of being managed in the foliage detail manager. If however changes are to be made only to foliage entities, all entities would have to be retrieved and the graphics settings set on them via available entity functions.

Material and Mesh LOD distances

Implementation class: Ember::OgreView::Lod::LodLevelManager

Factors that can be worked on:

  • Material lod distance.
  • Mesh lod distance.

By level of detail distance what is meant is, the distances at which the various lower or higher level meshes and materials are used on an entity. If a higher level mesh and material is used for a larger distance the detail is said to have been increased, while if a higher level mesh and material is used for a much smaller distance the detail is said to have decreased.

Originally in my project, this was done by directly affecting the material lod levels of every material loaded in ember by iterating through them. This led to a mismatch between the distances mesh and material lod were activated i.e. suppose an artist adds a new mesh lod with a specific texture to be used with it, then, with the earlier approach, the lower level material might have been used with a higher level mesh for which it might not at all be suited.

Therefore, the main camera's lod bias was used which affects both the material and mesh lod simultaneously.

NOTE Currently I think this is also affecting terrain lod as a side effect which results in changing of far away scenery very suddenly. Added an average fps calculation to smooth it over a period of time. Now the changes are a lot smoother and sudden changes in fps have much lesser effect.

Material Shader techniques

Implementation class: ShaderDetailManager

At the start of the work for this section the original planned approach was editing the shader techniques and shifting various rendering shader techniques into new run time created techniques and reloading them. I quickly realized that the only convenient non technique destroying way to do this was to use shader schemes as defined by the Ogre shader scripts. I have therefore used the “High”, “Medium”, “Low” shader schemes already defined in the material script files and shifted between them when a large performance shift is requested.

Texture Quality

Changing the texture size leads to positive but varied results from system to system. Texture quality is known to only directly affect performance when the total video memory is lesser than the required video memory by the program. This condition leads to textures being swapped in and out of memory as and when they are required. If this happens a lot it can lead to GPU memory thrashing. The textures are stored on disk, but when they are needed they are first read into memory and then sent on to the graphics card. Thus, it's possible to have code resize them in memory, before they are sent on to the graphics card. Changing texture size in Ogre has only one requirement and that the texture is in DDS format, in one of the DXT modes rather than PNG. This gives a major advantage of being able to select texture sizes on the fly and also reduces the total packed size of the textures.

Render Distance

Implementation class: Ember::OgreView::RenderDistanceManager

Render distance refers to the in game distance up till which 3D models are considered for rendering by the graphics engine. Objects further than the rendering distance are culled from rendering calculations. Therefore by affecting the render distance, a direct performance change can be seen. Ogre render distances can be changed by affecting the render distance of the main camera used for rendering a scene through Ogre::Camera::setRenderingDistance

Shadow Detail

Implementation class: Ember::OgreView::ShadowDetailManager

Factors that can be worked on:

  • Shadow Distance
  • Shadow level of detail

Shadow Distance Shadow distance is the maximum distance at which a shadow is rendered, whether it is of an object at that distance or a shadow that extends beyond this distance. Since shadows beyond this distance or not considered for rendering calculations, processing time is saved. This is done by setting the shadow distance of the Ogre scene manager being used via Ogre::SceneManager::setShadowFarDistance

Shadow level of detail Shadows can also be generated for lower level of detail meshes. This results in lower detail shadows. The lod can be affected by changing the lod bias of the shadow camera and is possible since Ember uses textured shadows. This is done using Ogre::Camera::setLodBias

Testing and status

As a general look at where the various components stand, at the present moment and how much performance gain each of them offers on my test system(s):

  • Shader detail:

High -> Medium = 15-16fps. Medium -> Low = Loss of 5fps. This varies from computer to computer, though on both my systems with newer graphics cards, this resulted in a loss of performance. On older systems this resulted in a gain in performance. This is due to the fact that low literally means low, i.e. no shaders. This helps older cards, but newer cards are more efficient at using shaders rather than the fixed function pipeline. "Low" also results in the terrain being handled in multiple passes. Detecting the card is not a sure shot way of determining whether the "Low" change will result in a gain. Therefore, for the purpose of performance gain, only "High" and "Medium" levels are used. Shader schemes are only switched when a large gain (or loss) of performance is required.

  • Foliage detail:

Every step of 20% foliage density and distance being removed results in a 1.5 - 2fps gain, for a total of around 8-8.5 fps when foliage is completely removed. This is used as the easiest way to provide small boosts in performance in steps.

  • Mesh and material lod:

This will actually come into effect when automatic mesh lod generation is implemented, since the performance is adjusted by switching between mesh and material lod levels. At the moment it results in a 1-1.5 fps gains in some cases by affecting far away terrain. The upper and lower limits for what mesh and material detail to use can only be determined once the models are available.

  • Shadow detail:

By affecting the lod bias of the shadow camera's, and because the client has textured shadows, it should be possible to generate shadows for lower level of detail models of entities. The functionality for this is added, but can only be tested once the lower lod meshes are added. The shadow distance is also affected. This only leads to a performance increase in older cards with lesser memory, at least in my tests.

  • Render Distance:

Because the server only sends the client entities that are close to it or in a defined view of it, the performance gain from reducing render distance (clipping distance) mostly comes only from terrain reduction, which is not much. Therefore for a reduction of 60% render distance, a performance gain of around 2 fps is seen on newer cards and around 4 fps on older cards.

  • Texture detail:

Reducing the texture size leads to positive but varied results from system to system. Assaf Raman from Ogre has a good forum post describing how to do it: It has only one requirement and that the texture be in DDS format, in one of the DXT modes rather than PNG. This gives us a major advantage of being able to select texture sizes on the fly and also reduces the total packed size. Ember’s textures are currently in the PNG format, and therefore a way must be found to convert these textures to a suitable DDS texture format before this feature can be implemented.