Deferred Rendering for OpenGL* ES3.0 on Android*

This is an article written by Kyle Weicht, Software Engineer with the Visual Computing Engineering team at Intel Corporation. Sample code to accompany the article can be downloaded from the GitHub repository here

Introduction

This article outlines how you can efficiently implement the following rendering techniques on mobile devices using OpenGL* ES:

  • forward rendering
  • deferred lighting (light pre-pass)
  • deferred shading

Definition

Forward rendering is conceptually the simplest rendering model. Lights are defined first and then objects in the scene are rendered in some order with light calculations done on each object as it is drawn. Although simple to implement, this technique slows down as more lights are introduced to the scene, and most realistic scenes require several lights.

Deferred lighting and deferred shading are techniques that efficiently render a scene with many more lights than traditional forward rendering. Both deferred techniques defer the lighting calculations until every object has been drawn, then applies all lighting in one pass. There are various trade-offs for each technique; however, both deferred rendering techniques can be used to achieve the same goal.

Note:

  • This article assumes familiarity with deferred rendering techniques. For a more in-depth description of deferred rendering, see Deferred Rendering in Killzone 2.

OpenGL ES rendering support in mobile OSes

Multiple render targets for full deferred shading are supported in OpenGL ES version 3.0 with Android 4.3 or iOS 7. Prior to version 3.0, OpenGL ES did not support multiple render targets, one of the requirements for deferred shading. This lack of support forced game developers to use either forward rendering or deferred lighting.

Rendering implementation processes

The following sections describe the implementation processes for

  • forward rendering
  • deferred lighting
  • deferred shading

The scene used in this sample is designed to show one of the largest advantages of deferred rendering – many lights. The scene consists of a lighthouse and beach with various colored lights floating around, lighting the scene.

Process for forward rendering

The following process outlines how the scene is rendered using forward rendering. The forward rendering technique is implemented with an RGBA8 back buffer and a 24-bit depth buffer.

  • For each mesh
    • For each light
      • Accumulate lighting

 

Process for deferred lighting/light pre-pass

The following process outlines how the scene is rendered using deferred lighting. The deferred lighting technique is implemented with two 32-bit color buffers and a 24-bit depth buffer.

This three-pass approach uses only one color buffer at a time, meaning it will work on an OpenGL ES 2.0 device. The normals are encoded in pass 1, allowing the X and Y components to be stored with 16-bit precision in the 32-bit buffer. The final pass does the actual lighting by reading the lighting value from the lighting buffer and using the value as the light color.

Note: The lights are rendered as world-space cubes. In order to perform the lighting, the pixel’s world position is calculated from its screen position and depth at that pixel.

Pass 1

  • For each mesh
    • Render mesh’s normal into 1st color buffer (normal buffer)

Pass 2

  • Render each light as world-space bounding volume
    • Read normal from normal buffer and accumulate lighting into 2nd color buffer (lighting buffer)

Pass 3

  • For each mesh
    • Render object again, using lighting from the lighting buffer

Process for deferred shading

The following process outlines how the scene is rendered using deferred shading.

This two-phase rendering approach uses multiple render targets to make up the G-buffer. The first RGBA8, color buffer, is used for storing the albedo color. The second RG16, color buffer, is used for storing the encoded normals. The depth buffer is a 24-bit buffer.

The deferred shading approach is slightly simpler than the deferred lighting technique; however, it requires multiple render targets, which is only supported in OpenGL ES 3.0 and beyond. The lights are rendered the same way as they are in the deferred lighting approach, as world-space bounding boxes. As well, the normal encoding and position reconstruction are the same as deferred lighting.

Geometry

  • For each mesh
    • Render albedo color into G-buffer
    • Render normal into G-buffer

Lighting

  • Render each light as world-space bounding box
    • Read normal and albedo from G-buffer
      • Accumulate lighting into back buffer

References

https://en.wikipedia.org/wiki/Deferred_shading

http://www.codinglabs.net/tutorial_simple_def_rendering.aspx

http://www.leadwerks.com/files/Deferred_Rendering_in_Leadwerks_Engine.pdf

http://gamedevelopment.tutsplus.com/articles/forward-rendering-vs-deferred-rendering--gamedev-12342

http://diaryofagraphicsprogrammer.blogspot.com/2008/03/light-pre-pass-renderer.html

http://www.catalinzima.com/xna/tutorials/deferred-rendering-in-xna/

http://aras-p.info/texts/CompactNormalStorage.html

Для получения подробной информации о возможностях оптимизации компилятора обратитесь к нашему Уведомлению об оптимизации.
Теги: