Blog! Team! Forum! About Apricot! Press! Gallery! Development! Yo Frankie! Apricot Open Game Project mee!
Mar 29

Post processing, HDR

icon1 res | icon2 Crystal Space, Development, Screenshots | icon4 03 29th, 2008

Here a few words what I’ve been doing (less) recently. In the general, I worked on the render manager, and more specifically, I did some work on the postprocessing system.

Using post processing is quite simple, even for Crystal Space. In the implementation of a render manager, you need some boilerplate to declare and setup the manager:

// A class member for the manager
CS::RenderManager::PostEffectManager postEffects;
// Initialization
postEffects.Initialize (objectReg);

That’s it, you’re ready to add post processing effects.
(Note: While I’m talking about setting up post processing effects from code throughout this article, I’m aware that for practical purposes there should be a way to set things up from some sort of configuration file. Be patient.)

Now a simple example for postprocessing. But even before that, as a simple reminder, the “baseline” image without effects:

This is just a shot from the miniscule graphics prototype level shown before, nothing new here.

Let’s add a simple effect:

// Add shader to use for postprocessing
csRef<iShader> desaturate = loader->LoadShader ("/shader/postproc/desaturate.xml");
// Add to postproc manager
postEffects.AddLayer (desaturate);

The result:crystal001.png
Some blur:

csRef<iShader> blur = loader->LoadShader ("/shader/postproc/blur.xml");
postEffects.AddLayer (blur);

The result:crystal002.png

You can also “stack” layers, e.g. add a blur and desaturate effect and see everything blurred and desaturated. But the postproc manager can do more: it actually is a simple node-based system.

So for something more complex, let’s do a bloom-ish effect where we threshold the rendered scene, blur it a few times, and add it back to the initial image:

// Shaders we want
csRef<iShader> threshold = loader->LoadShader ("/shader/postproc/threshold.xml");
csRef<iShader> blur = loader->LoadShader ("/shader/postproc/blur.xml");
csRef<iShader> add =loader->LoadShader ("/shader/postproc/add_squared.xml");
// Set up nodes. See how connections are done
PostEffectManager::Layer* thresholded = postEffects.AddLayer (threshold);
PostEffectManager::Layer* lastBlur = postEffects.AddLayer (blur, 1, thresholded, "tex diffuse");
lastBlur = postEffects.AddLayer (blur, 1, lastBlur, "tex diffuse");
lastBlur = postEffects.AddLayer (blur, 1, lastBlur, "tex diffuse");
PostEffectManager::Layer* bloomed = postEffects.AddLayer (add, 2,
postEffects.GetScreenLayer(), "tex diffuse",
lastBlur, "tex diffuse 2");

Result: crystal003.png

However, that doesn’t look very bloomy. The highlights wash out, but not as much as they could in all places.

The solution is to render to a buffer with higher precision than the framebuffer before doing the final displaying on the screen (this is a part of what’s commonly called HDR).
Enabling HDR rendering is pretty simple:

HDRHelper hdr;
hdr.Setup (objectReg, HDRHelper::qualFloat16, 1, postEffects, false);

Now all the rendering is done into a floating point buffer before going to the screen:  crystal004.png

While the difference is faint, it’s noticeable: look at the big highlight of the stone and the grass blades in front of it.

With HDR we can also do some funny tone mapping, here with a very simple log mapping:

csRef<iShader> logmap = loader->LoadShader ("/shader/postproc/hdr/simple-log.xml");
postEffects.AddLayer (logmap, 1, bloomed, "tex diffuse");

Some results with varying parameters:  crystal006.png crystal007.png crystal008.png

There are still a number of things left to be done – e.g. render to integer textures for older hardware, automatic tonemapping adjustment for the authentic HDR feel, and more effects in general – but the foundation is there, flexible, powerful an, most important, a breeze to use.

19 Responses

  1. RH2 on

    is it possible to link those effects to the
    node/composite rendering for the same effect?

  2. YoYoFargo on

    I was hoping you were going to write your own GLSL shaders and effects.

    It would be wrong of me to link you to illegal gaming activities, but do an image search for “glsl pete’s”

    Some of the shaders there look pretty amazing. (click the first result)

    Maybe you could add an interface for custom/different shaders in the end product?

  3. Kirado on

    So how will this integrated with blender..? Pretty nice post process effects. Thanks for the posts keep them coming. What are you using for the post processing behind the scenes? GLSL, HLSL?

    Excellent to know that you’ve got HDR. For shadow casting will you be using less detailed shadow proxies to cast any shadows..?

  4. deynord on

    Excellentee! We like any kind of this screen-shoot, yes for bloomy effect need some improvement but looks very nice!
    Cant wait screen-shoots for water reflect shader that mirrored the trees with some ripple 🙂

  5. res on

    All the “LoadShader” calls read effect shaders from disk. You can trivially drop in custom effects. Look at for some simple examples.

  6. Hamed Zaghaghi on

    Hi, it’s very nice!
    there are some postprocessing actuators on bge too 😉

  7. Bmud on

    will we be able to interpret the exposure level of the image for different slices of the screen. I remember fondly the first HDR demonstration of the HL2 Source engine where they took logarithmically more exposure information from the center and allowed the edges of the screen to be more and more ignored.

    I really like the desaturated look 🙂 I look forward to this game having some different “film types”.

    I also like the way the code looks. It’s clean. Trying to write my own GLSL shaders I noticed that the code got really messy really fast.

    Thanks for all your efforts

  8. jonny on

    looks nice. Will there be a sky with volumetric clouds and dynamic light for all lights and shadows (inclusive sun), and real time walk of the sun (and shadows) like in cryengine2 (you promised industry-standard 😉 )?


  9. Francisco Ortiz on

    Which is the minimum hardware requirements to see all Apricot’s features?

  10. Alex "MistaED" on

    Francisco: Minimum hardware requirements I would say for all the features would be a video chip which supports all of OpenGL 2.1, like programmable fragment and vertex programs (Nvidia’s Cg support of them in particular), Vertex Buffer Object (VBO), and Frame Buffer Object (FBO) support. Minimum Geforce FX or 6 series (FX might work but not too well performance-wise), and minimum Radeon 9xxx, X8xx, X1xxx and up support these features afaik, and intel GMA965/X3100 and up with the latest drivers, (if you run ubuntu, hardy will have opengl2.1 support for the intel chips which have the hardware capable).

    This doesn’t mean they can’t get the game to look nice on older hardware, crystalspace is more than capable of scaling back to fixed function or ARB fragment/vertex programs as the shaders can be written to drop down if the hardware doesn’t support some of the later features.

    I am not on the team but this is my estimate of it, as for CPU/RAM I am not sure, maybe no less than 512mb ram or a 2ghz single core cpu?

  11. caedes on

    We dont know yet about the minimum hardware (too early), but these are the computers we have at the studio where the game must run with highest detail:

    cpu: dual core 2.33ghz
    mem: 2gb
    gfx: nvidia 8800 GTS 512

    XD i know, theyre too good… but mistaed is right about gfx requirements in general, so expect it to still have most features there in older hardware.

  12. Anthoni C on

    It’s missing ambient occlusion. AA would give greater detail and make it look better. Maybe better texture blending on terrain.

  13. Francisco Ortiz on

    Thank you very much for the Info, MistaED and Caedes.

  14. Alex "MistaED" on

    Anthoni C: Hmm yeah you bring up a point, I saw crysis uses a fast ambient occlusion post-process effect which looked nice 🙂 but looking at it now it doesn’t really need one, maybe just a lightmap-baked one? With lighter2 getting global illumination it should look really stunning, and have moving objects with shadowmaps, sort of like how team fortress renders out 🙂

  15. darek on

    It has ambient-occ already. Just colors of this are not saturated too much. But we like subtle effects not blinking blooms and 1000 other effects into player’s eyes.

  16. Anthoni_C on

    Thats a good Idea MistaED to save performance, the ambient-occ could be baked into the light maps but then again that would require a compile process in blender.

    Maybe only a baked ambient-occ for environments. Approx. Ambient occlusion is used in the Unreal Engine for real-time rendering so maybe it can be used in Crystal Space.

  17. joeri on

    Just poking my nose in to see what happening. Great stuff !!! This will be so cool to own. Glad I ordered my copy ages ago. Just a general “Hooray!”



  18. 3DMAN on

    Hello, I’m french and I am making a little game with blender.

    I have a question:
    Do you use real time lights ? Because I had many problems with real time lights and UV mapping in blender GameEngine 🙁 .

    I won’t explain all my problems here because it’s too long…

  19. jositux on

    como se nota la influencia de venomgfx!!!! (lo digo por el sitio)

    mil felicitaciones por el trabajo desde Argentina