Using a deferred renderer
In Using a renderer you have learnt about renderers, what benefits do they bring compared to the submit method and how to use the default renderer. In this tutorial we are going to have a look at a new type of a renderer - the deferred renderer.
Contents
Forward versus deferred rendering
The default renderer implements a so-called forward rendering pipeline. In this tutorial we will not go into technical details, but feel free to do your own research about forward and deferred rendering. Here you can have a look at the following table of key differences between the default and the deferred renderer, which should help you decide which one of the two is more suitable for your project. A 🟢 means given renderer has the upper hand and a 🔴 means a disadvantage.
Default renderer (forward) | Deferred renderer | |
---|---|---|
Special requirements: | 🟢 None | 🔴 Multiple render targets (MRT) and floating point textures |
Suitable for platforms: | 🟢 All | 🔴 Desktop and consoles* |
Material properties supported: | 🟢 All | 🔴 Cheap subsurface scattering and lightmaps not supported |
Maximum no. of lights: | 🔴 1 directional, 8 punctual | 🟢 1 directional, unlimited punctual |
Maximum no. of shadow-casting lights: | 🔴 1 | 🟢 Unlimited |
SSAO supported: | 🔴 With G-buffer enabled** | 🟢 Yes |
Post-processing: | 🔴 SDR (exposure, tone mapping and gamma correction pre-applied) | 🟢 HDR |
* - Consoles can be powerful enough but GameMaker might not implement required features for all of them.
** - This causes the scene to be rendered an extra time, which negatively affects performance!
Additionally, you can draw models with the default material when using a deferred renderer. These will be rendered in a separate forward render pass, which means limitations of the forward renderer still apply to them! Please note that this does not work the other way around, i.e. you cannot use deferred materials in the default renderer!
Adding a deferred renderer
Before creating a deferred render, you can check if the current platform has all the required features using function bbmod_deferred_renderer_is_supported (you do not have to if you know your platforms). If it returns true
, you can proceed, otherwise you can fallback to the default one. Creating a deferred renderer is then mostly the same as the default one, you just need to use BBMOD_DeferredRenderer instead of BBMOD_DefaultRenderer:
/// @desc Create event
renderer = new BBMOD_DeferredRenderer();
Additionally, since the deferred renderer outputs an HDR image without exposure, tone mapping and gamma correction, you need to use a post-processor and add the following effects in this specific order (though there can be other effects in between them), otherwise your game will not be displayed correctly!
postProcessor = new BBMOD_PostProcessor();
postProcessor.add_effect(new BBMOD_ExposureEffect());
postProcessor.add_effect(new BBMOD_ReinhardTonemapEffect());
postProcessor.add_effect(new BBMOD_GammaCorrectEffect());
renderer.PostProcessor = postProcessor;
Creating deferred materials
As it was mentioned previously, the deferred renderer can draw models using the default material too, but these will not benefit from its capabilities. If you want to draw a model using the deferred rendering path, you will need to use BBMOD_MATERIAL_DEFERRED instead:
materialDeferred = BBMOD_MATERIAL_DEFERRED.clone();
materialDeferred.BaseOpacity = sprite_get_texture(SprBaseColor, 0);
// Your regular material setup follows here...
model.set_material("Material", materialDeferred); // Apply the material to a model
WARNING: You should not add shaders for the DepthOnly render pass to deferred materials! This would cause models using them to be rendered an extra time unnecessarily!
There is also a special variation of the deferred material for drawing terrain - BBMOD_MATERIAL_TERRAIN_DEFERRED - which can be used like so:
/// @desc Create event
terrain = new BBMOD_Terrain();
terrain.Material = BBMOD_MATERIAL_TERRAIN_DEFERRED;
And that's it for the setup! The rest of the code stays the same.