Urho3D
Rendering

Much of the rendering functionality in Urho3D is built on two subsystems, Graphics and Renderer, contained within the Graphics library.

Graphics

Graphics implements the low-level functionality:

Screen resolution, fullscreen/windowed, vertical sync and hardware multisampling level are all set at once by calling Graphics's SetMode() function. There is also an experimental option of rendering to an existing window by passing its OS-specific handle to SetExternalWindow() before setting the initial screen mode.

When setting the initial screen mode, Graphics does a few checks:

Renderer

Renderer implements the actual rendering of 3D views each frame, and controls global settings such as texture quality, material quality, specular lighting and shadow map base resolution.

To render, it needs a Scene with an Octree component, and a Camera that does not necessarily have to belong to the scene. The octree stores all visible components (derived from Drawable) to allow querying for them in an accelerated manner. The needed information is collected in a Viewport object, which can be assigned with Renderer's SetViewport() function.

By default there is one viewport, but the amount can be increased with the function SetNumViewports(). The viewport(s) should cover the entire screen or otherwise hall-of-mirrors artifacts may occur. By specifying a zero screen rectangle the whole window will be used automatically. The viewports will be rendered in ascending order, so if you want for example to have a small overlay window on top of the main viewport, use viewport index 0 for the main view, and 1 for the overlay.

Each viewport defines a command sequence for rendering the scene, the render path. By default there exist forward, light pre-pass and deferred render paths in the Bin/CoreData/RenderPaths directory, see SetDefaultRenderPath() to set the default for new viewports. If not overridden from the command line, forward rendering is the default. Deferred rendering modes will be advantageous once there is a large number of per-pixel lights affecting each object, but their disadvantages are the lack of hardware multisampling and inability to choose the lighting model per material. In place of multisample antialiasing, a FXAA post-processing edge filter can be used, see the TestScene script application for an example of how to use.

The steps for rendering each viewport on each frame are roughly the following:

In the default render paths, the rendering operations proceed in the following order:

Rendering components

The rendering-related components defined by the Graphics library are:

Optimizations

The following techniques will be used to reduce the amount of CPU and GPU work when rendering. By default they are all on:

Note that many more optimization opportunities are possible at the content level, for example using geometry & material LOD, grouping many static objects into one object for less draw calls, minimizing the amount of subgeometries (submeshes) per object for less draw calls, using texture atlases to avoid render state changes, using compressed (and smaller) textures, and setting maximum draw distances for objects, lights and shadows.

Handling GPU resource loss

On Direct3D9 and Android OpenGL ES 2.0 it is possible to lose the rendering context (and therefore GPU resources) due to the application window being minimized to the background. Also, to work around possible GPU driver bugs the desktop OpenGL context will be voluntarily destroyed and recreated when changing screen mode or toggling between fullscreen and windowed. Therefore, on all graphics APIs one must be prepared for losing GPU resources.

Textures that have been loaded from a file, as well as vertex & index buffers that have shadowing enabled will restore their contents automatically, the rest have to be restored manually. On Direct3D9 non-dynamic (managed) textures and buffers will never be lost, as the runtime automatically backs them up to system memory.

See IsDataLost() function in VertexBuffer, IndexBuffer, Texture2D and TextureCube classes for detecting data loss. Inbuilt classes such as Model, BillboardSet and Font already handle data loss for their internal GPU resources, so checking for it is only necessary for custom buffers and textures. Watch out especially for trying to render with an index buffer that has uninitialized data after a loss, as this can cause a crash inside the GPU driver due to referencing non-existent (garbage) vertices.

Further details

See also Materials, Lights and shadows, Render path, Skeletal animation, Particle systems, Zones, and Auxiliary views.

See Rendering modes for detailed discussion on the forward, light pre-pass and deferred rendering modes.

See Differences between Direct3D9 and OpenGL for what to watch out for when using the low-level rendering functionality directly.