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
8 changes: 8 additions & 0 deletions package/Shaders/Common/SharedData.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,13 @@ namespace SharedData
float3 pad;
};

struct InteriorSunSettings
{
float EffectMeshSunInfluence;
uint IsInteriorWithSun;
float2 pad0;
};

cbuffer FeatureData : register(b6)
{
GrassLightingSettings grassLightingSettings;
Expand All @@ -285,6 +292,7 @@ namespace SharedData
LinearLightingSettings linearLightingSettings;
TerrainBlendingSettings terrainBlendingSettings;
ExponentialHeightFogSettings exponentialHeightFogSettings;
InteriorSunSettings interiorSunSettings;
};

Texture2D<float4> DepthTexture : register(t17);
Expand Down
27 changes: 23 additions & 4 deletions package/Shaders/Effect.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -562,13 +562,15 @@ float3 GetLightingColor(float3 msPosition, float3 worldPosition, float2 screenPo
float dirShadow = 1.0;

const bool inWorld = (Permutation::ExtraShaderDescriptor & Permutation::ExtraFlags::InWorld);
const bool isInteriorSun = SharedData::interiorSunSettings.IsInteriorWithSun;

if (inWorld && !SharedData::InInterior)
if (inWorld && (!SharedData::InInterior || isInteriorSun))
dirShadow = ShadowSampling::Get3DFilteredShadow(worldPosition.xyz, viewDirection, screenPosition, eyeIndex, unusedSurfaceShadow);

shadowVariance = 1.0 - sqrt(saturate(fwidth(dirShadow)));

dirColor *= dirShadow;
if (!isInteriorSun)
dirColor *= dirShadow;

# if defined(EXP_HEIGHT_FOG)
if (SharedData::exponentialHeightFogSettings.enabled) {
Expand All @@ -584,6 +586,11 @@ float3 GetLightingColor(float3 msPosition, float3 worldPosition, float2 screenPo

color = dirColor + ambientColor;

if (isInteriorSun) {
float influence = SharedData::interiorSunSettings.EffectMeshSunInfluence;
color *= lerp(1.0, dirShadow, influence);
}

# if defined(LIGHT_LIMIT_FIX)
if (!(Permutation::ExtraShaderDescriptor & Permutation::ExtraFlags::InWorld))
# endif
Expand Down Expand Up @@ -628,6 +635,7 @@ float3 GetLightingShadow(float3 color, float3 worldPosition, float2 screenPositi
float shadow = 1.0;

const bool inWorld = (Permutation::ExtraShaderDescriptor & Permutation::ExtraFlags::InWorld);
const bool isInteriorSun = SharedData::interiorSunSettings.IsInteriorWithSun;

if (inWorld && !SharedData::InInterior) {
shadow = 0.0;
Expand All @@ -637,19 +645,30 @@ float3 GetLightingShadow(float3 color, float3 worldPosition, float2 screenPositi
shadow += ShadowSampling::GetWorldShadow(samplePositionWS, FrameBuffer::CameraPosAdjust[eyeIndex].xyz, eyeIndex);
}
shadow *= rcpSampleCount;
} else if (inWorld && isInteriorSun) {
float unusedSurfaceShadow;
shadow = ShadowSampling::Get3DFilteredShadow(worldPosition, viewDirection, screenPosition, eyeIndex, unusedSurfaceShadow);
}

shadowVariance = 1.0 - sqrt(saturate(fwidth(shadow)));

dirColor *= shadow;
if (!isInteriorSun)
dirColor *= shadow;

# if defined(EXP_HEIGHT_FOG)
if (SharedData::exponentialHeightFogSettings.enabled) {
dirColor *= ExponentialHeightFog::GetSunlightFogAttenuation(worldPosition.xyz, FrameBuffer::CameraPosAdjust[eyeIndex].xyz);
}
# endif

return dirColor + ambientColor;
color = dirColor + ambientColor;

if (isInteriorSun) {
float influence = SharedData::interiorSunSettings.EffectMeshSunInfluence;
color *= lerp(1.0, shadow, influence);
}

return color;
}
# endif

Expand Down
2 changes: 1 addition & 1 deletion package/Shaders/ISVolumetricLightingGenerateCS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ cbuffer PerTechnique : register(b0)

float shadowMapDepth = positionCSShifted.z;

bool noShadow = !SharedData::InInterior;
bool noShadow = !SharedData::InInterior || SharedData::interiorSunSettings.IsInteriorWithSun;
if (EndSplitDistances.z >= shadowMapDepth) {
uint cascadeIndex = ShadowMapCount >= 3.0f && shadowMapDepth > EndSplitDistances.y ? 2 : shadowMapDepth > EndSplitDistances.x ? 1 :
0;
Expand Down
2 changes: 1 addition & 1 deletion package/Shaders/Lighting.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -2496,7 +2496,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace)
float dirVSMDetailedShadow = 1.0;

# if defined(VOLUMETRIC_SHADOWS)
if (inWorld && !inReflection && !SharedData::InInterior)
if (inWorld && !inReflection)
dirSoftShadow = ShadowSampling::GetLightingShadow(input.WorldPosition.xyz, eyeIndex, dirVSMDetailedShadow);
# endif

Expand Down
13 changes: 9 additions & 4 deletions package/Shaders/RunGrass.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,14 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace)
float4 shadowColor = TexShadowMaskSampler.Load(int3(input.HPosition.xy, 0));

// Apply world shadow (terrain shadows, cloud shadows) directly to light color
if (!SharedData::InInterior)
dirLightColor *= ShadowSampling::GetWorldShadow(input.WorldPosition.xyz, FrameBuffer::CameraPosAdjust[eyeIndex].xyz, eyeIndex);
dirLightColor *= ShadowSampling::GetWorldShadow(input.WorldPosition.xyz, FrameBuffer::CameraPosAdjust[eyeIndex].xyz, eyeIndex);

float dirSoftShadow = 1.0;
float dirVSMDetailedShadow = 1.0;

# if defined(VOLUMETRIC_SHADOWS)
dirSoftShadow = ShadowSampling::GetLightingShadow(input.WorldPosition.xyz, eyeIndex, dirVSMDetailedShadow);
# endif

float dirDetailedShadow = 1.0;

Expand Down Expand Up @@ -832,8 +838,7 @@ PS_OUTPUT main(PS_INPUT input)
float3 dirLightColor = Color::DirectionalLight(SharedData::DirLightColor.xyz / max(llDirLightMult, 1e-5), SharedData::linearLightingSettings.isDirLightLinear) * llDirLightMult;

// Apply world shadow (terrain shadows, cloud shadows) directly to light color
if (!SharedData::InInterior)
dirLightColor *= ShadowSampling::GetWorldShadow(input.WorldPosition.xyz, FrameBuffer::CameraPosAdjust[eyeIndex].xyz, eyeIndex);
dirLightColor *= ShadowSampling::GetWorldShadow(input.WorldPosition.xyz, FrameBuffer::CameraPosAdjust[eyeIndex].xyz, eyeIndex);

float dirDetailedShadow = 1.0;

Expand Down
4 changes: 3 additions & 1 deletion src/FeatureBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "Features/GrassLighting.h"
#include "Features/HairSpecular.h"
#include "Features/IBL.h"
#include "Features/InteriorSun.h"
#include "Features/LODBlending.h"
#include "Features/LightLimitFix.h"
#include "Features/LinearLighting.h"
Expand Down Expand Up @@ -51,5 +52,6 @@ std::pair<unsigned char*, size_t> 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::interiorSun.GetShaderSettings());
}
18 changes: 17 additions & 1 deletion src/Features/InteriorSun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
InteriorSun::Settings,
ForceDoubleSidedRendering,
InteriorShadowDistance)
InteriorShadowDistance,
EffectMeshSunInfluence)

void InteriorSun::DrawSettings()
{
Expand All @@ -26,6 +27,13 @@ void InteriorSun::DrawSettings()
"Sets the distance shadows are rendered at in interiors. "
"Lower values provide higher quality shadows and improved performance but may cause distant interior spaces to light up incorrectly. ");
}
ImGui::SliderFloat("Effect Mesh Sun Influence", &settings.EffectMeshSunInfluence, 0.0f, 100.0f, "%.0f%%", ImGuiSliderFlags_AlwaysClamp);
if (auto _tt = Util::HoverTooltipWrapper()) {
ImGui::Text(
"Controls how much sunlight and shadows affect effect meshes (particles, fires, etc.) in interiors. "
"At 100%%, effect meshes receive full sun shadow darkening. "
"At 0%%, effect meshes ignore sunlight entirely, matching vanilla interior behavior. ");
}
}

void InteriorSun::LoadSettings(json& o_json)
Expand Down Expand Up @@ -216,6 +224,14 @@ bool InteriorSun::IsInSunDirectionAndWithinShadowDistance(const RE::NiPointer<RE
return projection >= -radius && (distance - radius) <= *gShadowDistance;
}

InteriorSun::ShaderSettings InteriorSun::GetShaderSettings() const
{
ShaderSettings data;
data.EffectMeshSunInfluence = std::clamp(settings.EffectMeshSunInfluence, 0.0f, 100.0f) * 0.01f;
data.IsInteriorWithSun = isInteriorWithSun ? 1u : 0u;
return data;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

void InteriorSun::SetShadowDistance(bool inInterior)
{
using func_t = decltype(SetShadowDistance);
Expand Down
11 changes: 11 additions & 0 deletions src/Features/InteriorSun.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,21 @@ struct InteriorSun : Feature
{
bool ForceDoubleSidedRendering = true;
float InteriorShadowDistance = 5000;
float EffectMeshSunInfluence = 100.0f;
};

Settings settings;

struct alignas(16) ShaderSettings
{
float EffectMeshSunInfluence = 1.0f;
uint32_t IsInteriorWithSun = 0;
float pad[2] = {};
};
STATIC_ASSERT_ALIGNAS_16(ShaderSettings);

Comment thread
Dlizzio marked this conversation as resolved.
ShaderSettings GetShaderSettings() const;

std::atomic<bool> isInteriorWithSun = false;

struct GetWorldSpace
Expand Down
Loading