Gamma Correction

Helmet: Gamma Correct / Gamma Correct + Tone Mapping / No Gamma or Tone Mapping
Damaged Helmet: Gamma Corrected / Not Corrected
Specular Highlight: Gamma Corrected / Not Corrected
Teapot: Gamma Corrected / Not Corrected

1. What is Gamma Correction

Gamma Correction in 3D graphics means that the lighting is calculated in more correct way.

The idea is like this: The images you prepare on your computer, and photos you take with your camera, have colors automatically adjusted to look good on a typical monitor. Using these colors directly for the lighting calculation (e.g. as diffuse or base colors) is not entirely correct.

Using gamma correction means that the graphic engine (like Castle Game Engine):

  1. Adjusts the values from the color images (like textures you provide to X3D PhysicalMaterial.baseTexture, Material.diffuseTexture, UnlitMaterial.emissiveTexture) into more correct values, before using them in any calculations.

  2. Calculates the lighting using the correct color values.

  3. At the end, applies the gamma to the final pixel color, to make it look good on your monitor.

More details, with more links, and analysis what other standards/engines do, is here.

More description of gamma correction is here, here, and here.

2. Using Gamma Correction in CGE

In Castle Game Engine you control this using a simple global variable GammaCorrection.

  • By default it is gcPhysicalMaterial which means that gamma correction is performed for materials using PBR (Physically Based Rendering) equations. This includes standard materials defined in glTF models, and materials defined in X3D 4.0 using explicit PhysicalMaterial node. So we assume that you prepare PBR materials and their textures taking gamma into account.

  • You can change it to gcNone to never do gamma correction.

  • You can change it to gcAlways to always do gamma correction.

Another way of explaining it is by looking at the material node (used by each X3D Shape):

  • PhysicalMaterial: Gamma correction is used if GammaCorrection equals gcPhysicalMaterial or gcAlways.

    This material type is the standard glTF material type. You can also use it explicitly by PhysicalMaterial X3Dv4 node.

  • Material and UnlitMaterial: Gamma correction is used if GammaCorrection equals gcAlways.

    Material is the standard X3D 3.x material type, practically used by all existing X3D exporters right now.

    UnlitMaterial is the new X3Dv4 node. It can also be used by glTF models that use KHR_materials_unlit material type (e.g. Blender can export such materials in glTF).

What you should do?

  • In most cases, the default does what you expect.

    If you use glTF models with PBR, then gammma correction is used.

    Otherwise gamma correction is not used. So unlit materials (e.g. with cartoon rendering) have no gamma correction. Older models with Phong lighting have no gamma correction.

  • If you want gamma correction always then turn GammaCorrection := gcAlways. Make sure you prepare your assets (textures) accordingly. This is also 100% compatible with glTF (that dictates one should use gamma correction always, for both PBR and unlit materials).

  • If you want maximum speed, set GammaCorrection := gcNone.

    If you want maximum speed, you should also consider using Phong lighting (maybe even with Gouraud shading) instead of PBR. IOW, using Material instead of PhysicalMaterial X3D nodes. And of course use UnlitMaterial for unrealistic rendering. But these decisions are independent of the gamma correction, that in principle makes sense with any lighting model (even unlit).

Note: Right now, gamma correction is only applied to things rendered using TCastleScene and TCastleViewport. It is not applied to other things. In particular user-interface elements (like TCastleButton or TCastleImageControl) or low-level 2D APIs (like TDrawableImage or TSprite) do not use gamma correction, ever.

3. Tone Mapping

Tone Mapping is another feature you can use to adjust the colors of your scene. Contrary to gamma correction, tone mapping is not about realism. It's just about changing all colors using some visually-pleasing equation.

While tone mapping is technically independent of the gamma correction (using one of them is unrelated to using another) the decision about using them is often considered at the same time, as they both affect the general "look of colors" on your scene. That is also why we document tone mapping here.

Simply set the ToneMapping global variable to apply tone mapping to everything you render. (Just as with gamma correction, it is applied to TCastleScene rendering. It doesn't affect UI rendering.)

Do you want to implement your own color-changing operation? The ToneMapping variable in CGE allows to only choose from built-in operators. But you can trivially define your own color processing using our compositing shaders, by using PLUG_fog_apply to process your colors using GLSL code. See tone_mapping.x3dv (you may want to download it with complete demo models) for demo. You can also use screen effects to apply post-processing in screen space.