Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/Features/LinearLighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
LinearLighting::Settings,
enableLinearLighting,
enableGammaCorrection,
clearRenderGamma,
lightGamma,
colorGamma,
emitColorGamma,
Expand Down Expand Up @@ -48,6 +49,7 @@ void LinearLighting::DrawSettings()
ImGui::SliderFloat("Effect Gamma", &settings.effectGamma, 0.1f, 3.0f, "%.2f");
ImGui::SliderFloat("Effect Transparency Gamma", &settings.effectAlphaGamma, 0.1f, 3.0f, "%.2f");
ImGui::SliderFloat("Sky Gamma", &settings.skyGamma, 0.1f, 3.0f, "%.2f");
ImGui::SliderFloat("Clear Render Gamma", &settings.clearRenderGamma, 0.1f, 3.0f, "%.2f");
ImGui::SliderFloat("Water Gamma", &settings.waterGamma, 0.1f, 3.0f, "%.2f");
ImGui::SliderFloat("Volumetric Lighting Gamma", &settings.vlGamma, 0.1f, 3.0f, "%.2f");

Expand Down Expand Up @@ -93,6 +95,61 @@ void LinearLighting::SetupResources()
PerGeometryCB = new ConstantBuffer(ConstantBufferDesc<PerGeometryData>());
}

void LinearLighting::EarlyPrepass()
{
ConvertClearColor();
}

void LinearLighting::ReflectionsPrepass()
{
ConvertClearColor();
}

void LinearLighting::ConvertClearColor()
{
bool isMainLoadingMenu = globals::game::ui && (globals::game::ui->IsMenuOpen(RE::MainMenu::MENU_NAME) || globals::game::ui->IsMenuOpen(RE::LoadingMenu::MENU_NAME));
if (!settings.enableLinearLighting || isMainLoadingMenu)
return;

// Convert clear color from gamma space to linear space at the source
// This affects the background color visible at worldspace edges and in water reflections
auto renderer = globals::game::renderer;
if (renderer) {
auto& rendererData = renderer->GetRendererData();

const bool isAlreadyConverted =
rendererData.clearColor[0] == lastConvertedClearColor[0] &&
rendererData.clearColor[1] == lastConvertedClearColor[1] &&
rendererData.clearColor[2] == lastConvertedClearColor[2];

// Only refresh the source color when the engine has changed it
if (!isAlreadyConverted &&
(rendererData.clearColor[0] != lastOriginalClearColor[0] ||
rendererData.clearColor[1] != lastOriginalClearColor[1] ||
rendererData.clearColor[2] != lastOriginalClearColor[2])) {
lastOriginalClearColor[0] = rendererData.clearColor[0];
lastOriginalClearColor[1] = rendererData.clearColor[1];
lastOriginalClearColor[2] = rendererData.clearColor[2];
}

float gamma = std::clamp(settings.clearRenderGamma, 0.1f, 3.0f);
if (isAlreadyConverted && gamma == lastConvertedClearGamma) {
return;
}

rendererData.clearColor[0] = std::pow(lastOriginalClearColor[0], gamma);
rendererData.clearColor[1] = std::pow(lastOriginalClearColor[1], gamma);
rendererData.clearColor[2] = std::pow(lastOriginalClearColor[2], gamma);
// Alpha (clearColor[3]) typically doesn't need gamma correction

// Remember what we converted to
lastConvertedClearColor[0] = rendererData.clearColor[0];
lastConvertedClearColor[1] = rendererData.clearColor[1];
lastConvertedClearColor[2] = rendererData.clearColor[2];
Comment thread
coderabbitai[bot] marked this conversation as resolved.
lastConvertedClearGamma = gamma;
}
}

void LinearLighting::Prepass()
{
bool isMainLoadingMenu = globals::game::ui && (globals::game::ui->IsMenuOpen(RE::MainMenu::MENU_NAME) || globals::game::ui->IsMenuOpen(RE::LoadingMenu::MENU_NAME));
Expand Down
8 changes: 8 additions & 0 deletions src/Features/LinearLighting.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct LinearLighting : Feature
{
uint enableLinearLighting = false;
uint enableGammaCorrection = true;
float clearRenderGamma = 1.62f;
float lightGamma = 1.8f;
float colorGamma = 1.8f;
float emitColorGamma = 1.8f;
Expand Down Expand Up @@ -108,6 +109,9 @@ struct LinearLighting : Feature

uint isDirLightLinear = false;
float dirLightMult = 1.0f;
float lastConvertedClearColor[3] = { -1.0f, -1.0f, -1.0f }; // Track to avoid double conversion
float lastOriginalClearColor[3] = { -1.0f, -1.0f, -1.0f }; // Source gamma-space color
float lastConvertedClearGamma = -1.0f;

virtual void DrawSettings() override;

Expand All @@ -116,6 +120,8 @@ struct LinearLighting : Feature

virtual void RestoreDefaultSettings() override;

virtual void EarlyPrepass() override;
virtual void ReflectionsPrepass() override;
virtual void Prepass() override;
virtual void PostPostLoad() override;

Expand All @@ -127,5 +133,7 @@ struct LinearLighting : Feature

void BSLightingShader_SetupGeometry(RE::BSRenderPass* a_pass);

void ConvertClearColor();

struct Hooks;
};