Add support for runtime color/gamma correction and new color profiles. Drastically optimized color LUT generation.#187
Conversation
… profiles - Removed hardcoded static color LUT - Reworked ColorLut to calculate color correction LUT at runtime - Added precompiled gamma tables (0.3f – 0.7f range, 5 steps) - Introduced dynamic color profiles selectable at runtime - Preparations for configurable Color Profiles and [DISPLAY_GAMMA] steps
- Moved color profile definitions to Colorprofiles.h, ditched cpp - Simplified access to profiles in header files
- 5 precomputed DISPLAY_GAMMA curve steps for now
|
I see you changed the |
|
Is there a specific reason to use 1000-based fixed point? Usually power of 2 based is more performant. I already have this fixed point class you can use for that: https://github.com/Gericom/GBARunner3/blob/develop/code/core/arm9/source/Core/Math/fixed.h |
Ah I see, I was thinking in terms of general practice, but that makes sense given the DS hardware behavior. Thanks for pointing it out; I’ll revert the change.
Makes sense, I defaulted to 1000-based out of habit, but using your fixed-point class is clearly a better fit here. I’ll update the code accordingly. Planning to get both changes in before the weekend! |
- Since gamma is being precomputed, we don't need to optimize this using floats
- We don't need to increase linear gamma with the new color matrices
Done! I also updated the color matrices to the most recent ones from the libretro shaders. Feel free to ping me on Discord for your review! |
- Gamma value from settings is now passed in `GbaDisplayConfigurationService::SetupColorCorrection`
- ColorLut remains in VRAM for now due to performance reasons, future performance testing may justify moving ColorLut as well.
- Removed unnecessary parentheses. - Changed GammaLut values to u8. - Fixed gbarunner9.ld indentation for consistency.
This introduces a complete rewrite of the color correction LUT system in GBARunner3 with the following key improvements.
Summary of Changes
New runtime color correction system:
ColorProfiles.h.clut_generateColorLut(), and initialized at boot byclut_initColorCorrectionthroughGbaDisplayConfigurationService.cpp. This allows color profile switching without the need of recompiling.Gamma handling separated and optimized:
GammaLut.cppwith precomputed gammaencodeanddecodeLUTs for optimal speed.Pipeline:
Extract RGB channels → Gamma encode (linear gamma) → Apply Luminance→ Apply RGB color profile from matrix→ Gamma decode (non-linear gamma) → Pack back to RGB555 + GBA green bit.Improved precision:
New Features
Selectable color profiles:
Each profile contains:
clut_initColorCorrection(profile)passing a pointer to the desiredColorProfile.Agb001produces the same result as the previous color LUT precomputed method, and can now be changed at runtime.New gamma decode levels:
gamma decodetables are available:Decode Gammawas chosen as the tunable parameter because changing it yields the most perceptible difference to the human eye.GBARunner3.jsonconfiguration file, following this format:setDisplayGammaIndex(index)viaGbaDisplayConfigurationService.cpp.Technical
Old Behavior
std::pow()directly in the main process, making it difficult to replace with fixed point math.New Behavior
Fixed-point math:
Gamma LUTs:
Gamma is precomputed in smaller LUTs in a separate process:
Gamma Encode:
pow(r, TARGET_GAMMA + DARKEN_SCREEN).gamma_encode_table) for performance.Gamma Decode:
precomputed_decode_tables.pow(x, 1.0 / DISPLAY_GAMMA)calculation.Max steps for Gamma Decode can be changed in
GAMMA_STEPS, and the gamma range for those steps inGAMMA_MINGAMMA_MAX.TL;DR
Known Issues
Only 5 gamma decode LUTs can fit currently due to<-- More can fit now, but 5 is sufficient.VRAMlimitations.Since VRAM is full, future improvements may require:Due to the mentioned issues, this cannot be merged into<-- it fits now, I've moved the LUT cache buffer to main ram.hicodeyet.Updated Configuration File
Feel free to ping me on Discord when your review notes are ready!