Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[Info]
Version = 3-0-2
Version = 3-0-3

[Nexus]
autoupload = false
3 changes: 2 additions & 1 deletion package/Shaders/Common/Permutation.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ namespace Permutation
static const uint IsBeastRace = (1 << 2);
static const uint GrassSphereNormal = (1 << 3);
static const uint IsSun = (1 << 4);
static const uint SuppressExternalEmittance = (1 << 5);
}

namespace ExtraFeatureFlags
Expand All @@ -98,4 +99,4 @@ namespace Permutation
};

}
#endif // __PERMUTATION_DEPENDENCY_HLSL__
#endif // __PERMUTATION_DEPENDENCY_HLSL__
67 changes: 54 additions & 13 deletions package/Shaders/Common/ShadowSampling.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ StructuredBuffer<DirectionalShadowLightData> DirectionalShadowLights : register(

namespace ShadowSampling
{
static const float MinDirectionalLightMultiplier = 1e-5;
static const float3 LightingSampleNormal = float3(0, 0, 1);
static const float3 ImageBasedLightingNormal = float3(0, 0, -1);

float GetWorldShadow(float3 positionWS, float3 offset, uint eyeIndex)
{
if (SharedData::InInterior || SharedData::HideSky || SharedData::InMapMenu)
Expand Down Expand Up @@ -117,26 +121,63 @@ namespace ShadowSampling
#endif
}

#if defined(SKYLIGHTING) && !defined(INTERIOR)
void ExtractLighting(float3 inputColor, out float3 dirColor, out float3 ambientColor, float skylightingDiffuse)
#else
void ExtractLighting(float3 inputColor, out float3 dirColor, out float3 ambientColor)
#endif
float3 GetRawAmbientLighting(float3 normal)
{
float3 ambientColorAmb = max(0, SharedData::GetAmbient(float3(0, 0, 1)));
return max(0, SharedData::GetAmbient(normal));
}

float3 GetAmbientLighting(float3 normal)
{
float3 ambientColor = GetRawAmbientLighting(normal);

#if defined(IBL)
if (SharedData::iblSettings.EnableIBL) {
# if defined(SKYLIGHTING) && !defined(INTERIOR)
ambientColorAmb = ImageBasedLighting::GetDiffuseIBLOccluded(ambientColorAmb, float3(0, 0, -1), skylightingDiffuse);
# else
ambientColorAmb = ImageBasedLighting::GetDiffuseIBL(ambientColorAmb, float3(0, 0, -1));
# endif
ambientColor = ImageBasedLighting::GetDiffuseIBL(ambientColor, ImageBasedLightingNormal);
}
#endif

return ambientColor;
}

#if defined(SKYLIGHTING) && !defined(INTERIOR)
float3 GetAmbientLighting(float3 normal, float skylightingDiffuse)
{
float3 ambientColor = GetRawAmbientLighting(normal);

# if defined(IBL)
if (SharedData::iblSettings.EnableIBL) {
ambientColor = ImageBasedLighting::GetDiffuseIBLOccluded(ambientColor, ImageBasedLightingNormal, skylightingDiffuse);
}
# endif

return ambientColor;
}
#endif

float3 GetDirectionalLighting()
{
float llDirLightMult = (SharedData::linearLightingSettings.enableLinearLighting && !SharedData::linearLightingSettings.isDirLightLinear) ? SharedData::linearLightingSettings.dirLightMult : 1.0f;
float3 dirLightColorDir = Color::DirectionalLight(SharedData::DirLightColor.xyz / max(llDirLightMult, 1e-5), SharedData::linearLightingSettings.isDirLightLinear) * llDirLightMult;
return Color::DirectionalLight(SharedData::DirLightColor.xyz / max(llDirLightMult, MinDirectionalLightMultiplier), SharedData::linearLightingSettings.isDirLightLinear) * llDirLightMult;
}

float3 GetSceneLightingColor()
{
return GetAmbientLighting(LightingSampleNormal) + GetDirectionalLighting();
}

#if defined(SKYLIGHTING) && !defined(INTERIOR)
void ExtractLighting(float3 inputColor, out float3 dirColor, out float3 ambientColor, float skylightingDiffuse)
#else
void ExtractLighting(float3 inputColor, out float3 dirColor, out float3 ambientColor)
#endif
{
#if defined(SKYLIGHTING) && !defined(INTERIOR)
float3 ambientColorAmb = GetAmbientLighting(LightingSampleNormal, skylightingDiffuse);
#else
float3 ambientColorAmb = GetAmbientLighting(LightingSampleNormal);
#endif

float3 dirLightColorDir = GetDirectionalLighting();

float inputLuma = Color::RGBToLuminance(inputColor);
float ambientLuma = Color::RGBToLuminance(ambientColorAmb);
Expand All @@ -155,4 +196,4 @@ namespace ShadowSampling
}
}

#endif // __SHADOW_SAMPLING_DEPENDENCY_HLSL__
#endif // __SHADOW_SAMPLING_DEPENDENCY_HLSL__
6 changes: 5 additions & 1 deletion package/Shaders/Effect.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,10 @@ cbuffer PerGeometry : register(b2)
float3 GetLightingColor(float3 msPosition, float3 worldPosition, float2 screenPosition, uint eyeIndex, inout float shadowVariance)
{
float3 color = DLightColor.xyz * Color::EffectLightingMult();
bool suppressExternalEmittance = SharedData::InInterior && (Permutation::ExtraShaderDescriptor & Permutation::ExtraFlags::SuppressExternalEmittance);
if (suppressExternalEmittance) {
color = ShadowSampling::GetSceneLightingColor();
}

# if defined(SKYLIGHTING)
# if defined(VR)
Expand Down Expand Up @@ -943,4 +947,4 @@ PS_OUTPUT main(PS_INPUT input)
# endif
return psout;
}
#endif
#endif
2 changes: 2 additions & 0 deletions src/Features/LightLimitFix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "LinearLighting.h"

#include "Menu/ThemeManager.h"
#include "Utils/ExternalEmittance.h"
#include "Shadercache.h"
#include "State.h"
#include "Util.h"
Expand Down Expand Up @@ -564,6 +565,7 @@ void LightLimitFix::Hooks::BSLightingShader_SetupGeometry::thunk(RE::BSShader* T
void LightLimitFix::Hooks::BSEffectShader_SetupGeometry::thunk(RE::BSShader* This, RE::BSRenderPass* Pass, uint32_t RenderFlags)
{
func(This, Pass, RenderFlags);
ExternalEmittance::UpdatePermutation(Pass);
auto& singleton = globals::features::lightLimitFix;
singleton.BSLightingShader_SetupGeometry_Before(Pass);
singleton.BSLightingShader_SetupGeometry_After(Pass);
Expand Down
2 changes: 2 additions & 0 deletions src/Hooks.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Hooks.h"

#include "ShaderTools/BSShaderHooks.h"
#include "Utils/ExternalEmittance.h"

#include "Feature.h"
#include "Globals.h"
Expand Down Expand Up @@ -168,6 +169,7 @@ namespace EffectExtensions
static void thunk(RE::BSShader* shader, RE::BSRenderPass* pass, uint32_t renderFlags)
{
func(shader, pass, renderFlags);
ExternalEmittance::UpdatePermutation(pass);
globals::state->permutationData.EffectRadius = pass->geometry->worldBound.radius;
}
static inline REL::Relocation<decltype(thunk)> func;
Expand Down
3 changes: 2 additions & 1 deletion src/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ class State
IsReflections = 1 << 1,
IsBeastRace = 1 << 2,
GrassSphereNormal = 1 << 3,
IsSun = 1 << 4
IsSun = 1 << 4,
SuppressExternalEmittance = 1 << 5
};

enum class ExtraFeatureDescriptors : uint32_t
Expand Down
57 changes: 57 additions & 0 deletions src/Utils/ExternalEmittance.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "ExternalEmittance.h"

#include "Globals.h"
#include "State.h"
#include "Util.h"

namespace ExternalEmittance
{
using ShaderPropertyFlag = RE::BSShaderProperty::EShaderPropertyFlag;
static constexpr auto ExternalEmittanceFlag = ShaderPropertyFlag::kExternalEmittance;
static constexpr auto SuppressionDescriptor = static_cast<std::uint32_t>(State::ExtraShaderDescriptors::SuppressExternalEmittance);

static RE::TESObjectREFR* GetReference(const RE::BSGeometry* a_geometry)
{
return a_geometry ? a_geometry->GetUserData() : nullptr;
}

static const RE::ExtraEmittanceSource* GetEmittanceSource(const RE::TESObjectREFR* a_ref)
{
return a_ref ? a_ref->extraList.GetByType<RE::ExtraEmittanceSource>() : nullptr;
}

static bool HasEmittanceSource(const RE::BSGeometry* a_geometry)
{
const auto* source = GetEmittanceSource(GetReference(a_geometry));
return source && source->source;
}

static bool HasExternalEmittance(const RE::BSShaderProperty* a_shaderProperty)
{
return a_shaderProperty && a_shaderProperty->flags.any(ExternalEmittanceFlag);
}

static bool ShouldSuppress(const RE::BSShaderProperty* a_shaderProperty, const RE::BSGeometry* a_geometry)
{
return Util::IsInterior() && HasExternalEmittance(a_shaderProperty) && !HasEmittanceSource(a_geometry);
}

bool ShouldSuppress(const RE::BSRenderPass* a_pass)
{
return a_pass && ShouldSuppress(a_pass->shaderProperty, a_pass->geometry);
}

void UpdatePermutation(const RE::BSRenderPass* a_pass)
{
assert(globals::state);
if (!globals::state) {
return;
}

auto& descriptor = globals::state->permutationData.ExtraShaderDescriptor;
descriptor &= ~SuppressionDescriptor;
if (ShouldSuppress(a_pass)) {
descriptor |= SuppressionDescriptor;
}
}
}
9 changes: 9 additions & 0 deletions src/Utils/ExternalEmittance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include <RE/B/BSRenderPass.h>

namespace ExternalEmittance
{
bool ShouldSuppress(const RE::BSRenderPass* a_pass);
void UpdatePermutation(const RE::BSRenderPass* a_pass);
}
Loading