diff --git a/package/Shaders/Common/SharedData.hlsli b/package/Shaders/Common/SharedData.hlsli index cae68835fe..8168507571 100644 --- a/package/Shaders/Common/SharedData.hlsli +++ b/package/Shaders/Common/SharedData.hlsli @@ -20,7 +20,7 @@ namespace SharedData float Timer; uint FrameCount; uint FrameCountAlwaysActive; - bool InInterior; // If the current cell is an interior + bool InInterior; // If the current cell is an interior bool HasDirectionalShadows; bool InMapMenu; // If the world/local map is open (note that the renderer is still deferred here) bool HideSky; // HideSky flag in WorldSpace, e.g. Blackreach @@ -269,6 +269,12 @@ namespace SharedData float3 pad; }; + struct TruePBRSettings + { + float VertexAOStrength; + uint3 pad; + }; + cbuffer FeatureData : register(b6) { GrassLightingSettings grassLightingSettings; @@ -287,6 +293,7 @@ namespace SharedData LinearLightingSettings linearLightingSettings; TerrainBlendingSettings terrainBlendingSettings; ExponentialHeightFogSettings exponentialHeightFogSettings; + TruePBRSettings truePBRSettings; }; Texture2D DepthTexture : register(t17); diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index 802507bccf..bcc82bb865 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -2155,6 +2155,8 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) // Apply vertex color to base color so PBR metals use it float3 pbrVertexColor = Color::SrgbToLinear(input.Color.xyz); + float pbrVertexAO = max(max(pbrVertexColor.x, pbrVertexColor.y), pbrVertexColor.z); + pbrVertexColor = pbrVertexAO == 0.0f ? 1.0f : pbrVertexColor * lerp(1 / max(pbrVertexAO, 0.001), 1, SharedData::truePBRSettings.VertexAOStrength); if (!SharedData::linearLightingSettings.enableLinearLighting) { baseColor.xyz = Color::SrgbToLinear(baseColor.xyz) * pbrVertexColor; @@ -2814,17 +2816,19 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) float3 glowColor = Color::Glowmap(TexGlowSampler.Sample(SampGlowSampler, uv).xyz); # if defined(TRUE_PBR) - float3 vertexColor = Color::SrgbToLinear(input.Color.xyz); + float3 emitVertexColor = Color::SrgbToLinear(input.Color.xyz); + float emitVertexAO = max(max(emitVertexColor.r, emitVertexColor.g), emitVertexColor.b); + emitVertexColor = emitVertexAO == 0.0f ? 1.0f : emitVertexColor * lerp(1 / max(emitVertexAO, 1e-4), 1, SharedData::truePBRSettings.VertexAOStrength); if (!SharedData::linearLightingSettings.enableLinearLighting) { emitColor = Color::SrgbToLinear(emitColor); glowColor = Color::SrgbToLinear(glowColor); emitColor *= glowColor; - emitColor *= vertexColor; + emitColor *= emitVertexColor; emitColor = Color::LinearToSrgb(emitColor); } else { emitColor *= glowColor; - emitColor *= vertexColor; + emitColor *= emitVertexColor; } # else if (!SharedData::linearLightingSettings.enableLinearLighting) { @@ -2889,11 +2893,12 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # elif defined(SKYLIGHTING) float3 vertexColor = input.Color.xyz; float vertexAO = max(max(vertexColor.r, vertexColor.g), vertexColor.b); - // Modify skylightingDiffuse such that skylightingDiffuse * vertexAO = min(skylightingDiffuse, vertexAO) - skylightingDiffuse = saturate(skylightingDiffuse / max(vertexAO, 1e-5)); # if defined(TRUE_PBR) + vertexAO = lerp(1, vertexAO, SharedData::truePBRSettings.VertexAOStrength); vertexColor = 1; # endif + // Modify skylightingDiffuse such that skylightingDiffuse * vertexAO = min(skylightingDiffuse, vertexAO) + skylightingDiffuse = saturate(skylightingDiffuse / max(vertexAO, 1e-5)); # else # if defined(TRUE_PBR) float3 vertexColor = 1; diff --git a/src/FeatureBuffer.cpp b/src/FeatureBuffer.cpp index f876879095..98f5aa834b 100644 --- a/src/FeatureBuffer.cpp +++ b/src/FeatureBuffer.cpp @@ -16,6 +16,7 @@ #include "Features/TerrainShadows.h" #include "Features/TerrainVariation.h" #include "Features/WetnessEffects.h" +#include "TruePBR.h" template std::pair _GetFeatureBufferData(Ts... feat_datas) @@ -51,5 +52,6 @@ std::pair GetFeatureBufferData(bool a_inWorld) globals::features::extendedTranslucency.GetCommonBufferData(), globals::features::linearLighting.GetCommonBufferData(), globals::features::terrainBlending.settings, - globals::features::exponentialHeightFog.settings); + globals::features::exponentialHeightFog.settings, + globals::features::truePBR.settings); } \ No newline at end of file diff --git a/src/TruePBR.cpp b/src/TruePBR.cpp index 1b8d6e3870..5bb1e2f8d9 100644 --- a/src/TruePBR.cpp +++ b/src/TruePBR.cpp @@ -40,6 +40,10 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT( specularLevel, glintParameters); +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT( + TruePBR::Settings, + VertexAOStrength); + #define CHECK_PBR_TEXTURE(textureName) \ if (!(pbrMaterial->textureName)) { \ logger::warn("[TruePBR] {} missing {}; treating as nonPBR", pbrMaterial->inputFilePath, #textureName); \ @@ -106,6 +110,11 @@ void SetupPBRLandscapeTextureParameters(BSLightingShaderMaterialPBRLandscape& ma void TruePBR::DrawSettings() { + if (ImGui::TreeNodeEx("Global Settings", ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::SliderFloat("Vertex AO Strength", &settings.VertexAOStrength, 0.f, 1.f, "%.2f", ImGuiSliderFlags_AlwaysClamp); + ImGui::TreePop(); + } + if (ImGui::TreeNodeEx("Texture Set Settings", ImGuiTreeNodeFlags_DefaultOpen)) { if (Util::SearchableCombo("Texture Set", selectedPbrTextureSetName, pbrTextureSets)) { selectedPbrTextureSet = &pbrTextureSets[selectedPbrTextureSetName]; @@ -300,6 +309,21 @@ void TruePBR::DrawSettings() } } +void TruePBR::SaveSettings(json& o_json) +{ + o_json = settings; +} + +void TruePBR::LoadSettings(json& o_json) +{ + settings = o_json; +} + +void TruePBR::RestoreDefaultSettings() +{ + settings = {}; +} + void TruePBR::SetupResources() { SetupTextureSetData(); diff --git a/src/TruePBR.h b/src/TruePBR.h index 782d9a9498..3bf5d73e64 100644 --- a/src/TruePBR.h +++ b/src/TruePBR.h @@ -42,6 +42,19 @@ struct TruePBR : Feature virtual void Prepass() override; virtual void PostPostLoad() override; virtual void DataLoaded() override; + + virtual void SaveSettings(json& o_json) override; + virtual void LoadSettings(json& o_json) override; + virtual void RestoreDefaultSettings() override; + + struct alignas(16) Settings + { + float VertexAOStrength = 1.0f; + uint pad[3]; + }; + STATIC_ASSERT_ALIGNAS_16(Settings); + + Settings settings; bool TESObjectLAND_SetupMaterial(RE::TESObjectLAND* land); bool BSLightingShader_SetupMaterial(RE::BSLightingShader* shader, RE::BSLightingShaderMaterialBase const* material);