Brightness and Gamma

Create Visual Effects with Gamma

Can I use gamma correction to create special effects like flashing lights or day/night transitions?

Abstract art representing computer programming

Gamma correction can create impressive visual effects, but we need to handle it carefully to avoid jarring changes. Here's how to implement some common effects:

Day/Night Cycle

A basic day/night cycle might look something like this:

#include <SDL.h>
#include <cmath>

class DayNightCycle {
  SDL_Window* Window;
  float TimeOfDay{0.0f}; // 0.0 to 24.0

public:
  DayNightCycle(SDL_Window* W) : Window{W} {}

  void Update(float DeltaTimeSeconds) {
    // Progress time (1 game hour per
    // real second)
    TimeOfDay += DeltaTimeSeconds;
    if (TimeOfDay >= 24.0f) TimeOfDay -= 24.0f;

    // Calculate brightness based on time
    float Brightness{CalculateBrightness()};
    SDL_SetWindowBrightness(Window, Brightness);
  }

private:
  float CalculateBrightness() {
    // Brightest at noon (12.0), darkest at
    // midnight (0.0/24.0)
    float NormalizedTime{
      std::abs(TimeOfDay - 12.0f) / 12.0f};

    // Smooth transition using cosine
    return 1.0f + 0.5f * std::cos(
      NormalizedTime * 3.14159f);
  }
};

Lightning Flash Effect

Below, we create a quick lighting flash effect using gamma correction:

#include <SDL.h>

class LightningEffect {
  SDL_Window* Window;
  float DefaultBrightness{1.0f};
  bool IsFlashing{false};
  Uint32 FlashStartTime{0};

 public:
  LightningEffect(SDL_Window* W) : Window{W} {}

  void TriggerLightning() {
    if (!IsFlashing) {
      IsFlashing = true;
      FlashStartTime = SDL_GetTicks();
      // Bright flash
      SDL_SetWindowBrightness(Window, 2.0f);
    }
  }

  void Update() {
    if (IsFlashing) {
      Uint32 ElapsedTime{
        SDL_GetTicks() - FlashStartTime};

      // Flash duration in ms
      if (ElapsedTime > 100) {
        IsFlashing = false;
        SDL_SetWindowBrightness(
          Window, DefaultBrightness);
      }
    }
  }
};

Color Temperature Shifts

In this program, we adjust the color temperature of our output using gamma curves:

#include <SDL.h>

class ColorTemperature {
  SDL_Window* Window;

 public:
  ColorTemperature(SDL_Window* W) : Window{W} {}

  void SetTemperature(float Temperature) {
    // Temperature range: 0.0 (cool) to 1.0 (warm)
    Uint16 RedRamp[256];
    Uint16 BlueRamp[256];

    // Warmer colors emphasize red, reduce blue
    // More red when warm
    float RedGamma{2.0f - Temperature};
    // Less blue when warm
    float BlueGamma{1.0f + Temperature};

    SDL_CalculateGammaRamp(RedGamma, RedRamp);
    SDL_CalculateGammaRamp(BlueGamma, BlueRamp);

    // Green stays neutral
    Uint16 GreenRamp[256];
    SDL_CalculateGammaRamp(1.0f, GreenRamp);

    SDL_SetWindowGammaRamp(
      Window, RedRamp, GreenRamp, BlueRamp);
  }
};

Remember to restore default settings when your effects end, and consider platform limitations discussed in the lesson. For critical gameplay elements, consider using rendering-based effects instead of gamma correction.

Answers to questions are automatically generated and may not have been reviewed.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 71 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved