Skip to content

Commit

Permalink
feat: complete skylighting during loadscreen (#433)
Browse files Browse the repository at this point in the history
* feat: complete skylighting during loadscreen

* style: 🎨 apply clang-format changes

* fix: forceFrames subtraction

* chore: removed doPrecip since unused

* style: 🎨 apply clang-format changes

* fix: fadein set to 64

* fix: force skylighting frames correct values

* style: 🎨 apply clang-format changes

* fix: reduce skylighting max zenith to fix inconsistency

* style: 🎨 apply clang-format changes

---------

Co-authored-by: doodlum <doodlum@users.noreply.github.com>
  • Loading branch information
doodlum and doodlum authored Aug 21, 2024
1 parent 5ed5ce1 commit 55deae6
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 23 deletions.
8 changes: 5 additions & 3 deletions features/Skylighting/Shaders/Skylighting/Skylighting.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ struct SkylightingSettings
row_major float4x4 OcclusionViewProj;
float4 OcclusionDir;

float4 PosOffset; // xyz: cell origin in camera model space
uint4 ArrayOrigin; // xyz: array origin, w: max accum frames
float3 PosOffset; // xyz: cell origin in camera model space
uint pad0;
uint3 ArrayOrigin; // xyz: array origin, w: max accum frames
uint pad1;
int4 ValidMargin;

float4 MixParams; // x: min diffuse visibility, y: diffuse mult, z: min specular visibility, w: specular mult

uint DirectionalDiffuse;
float3 _pad1;
uint3 pad2;
};

#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ SamplerState samplerPointClamp : register(s0);

[numthreads(8, 8, 1)] void main(uint3 dtid
: SV_DispatchThreadID) {
const float fadeInThreshold = settings.ArrayOrigin.w;
const float fadeInThreshold = 255;
const static sh2 unitSH = float4(sqrt(4.0 * shPI), 0, 0, 0);

uint3 cellID = (int3(dtid) - settings.ArrayOrigin.xyz) % ARRAY_DIM;
Expand Down
8 changes: 5 additions & 3 deletions package/Shaders/Common/SharedData.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,16 @@ struct SkylightingSettings
row_major float4x4 OcclusionViewProj;
float4 OcclusionDir;

float4 PosOffset; // xyz: cell origin in camera model space
uint4 ArrayOrigin; // xyz: array origin, w: max accum frames
float3 PosOffset; // xyz: cell origin in camera model space
uint pad0;
uint3 ArrayOrigin; // xyz: array origin, w: max accum frames
uint pad1;
int4 ValidMargin;

float4 MixParams; // x: min diffuse visibility, y: diffuse mult, z: min specular visibility, w: specular mult

uint DirectionalDiffuse;
float3 pad0;
uint3 pad2;
};

struct PBRSettings
Expand Down
15 changes: 5 additions & 10 deletions src/Features/Skylighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
Skylighting::Settings,
DirectionalDiffuse,
MaxZenith,
MaxFrames,
MinDiffuseVisibility,
DiffusePower,
MinSpecularVisibility,
Expand Down Expand Up @@ -44,14 +43,11 @@ void Skylighting::DrawSettings()
auto& context = State::GetSingleton()->context;
UINT clr[1] = { 0 };
context->ClearUnorderedAccessViewUint(texAccumFramesArray->uav.get(), clr);
forceFrames = 255 * 4;
}
if (auto _tt = Util::HoverTooltipWrapper())
ImGui::Text("Changes below require rebuilding, a loading screen, or moving away from the current location to apply.");

ImGui::SliderInt("Update Frames", &settings.MaxFrames, 0, 255, "%d", ImGuiSliderFlags_AlwaysClamp);
if (auto _tt = Util::HoverTooltipWrapper())
ImGui::Text("Aggregating over how many frames to build up skylighting.");

ImGui::SliderAngle("Max Zenith Angle", &settings.MaxZenith, 0, 90);
if (auto _tt = Util::HoverTooltipWrapper())
ImGui::Text("Smaller angles creates more focused top-down shadow.");
Expand Down Expand Up @@ -228,8 +224,7 @@ void Skylighting::Prepass()
.ArrayOrigin = {
((int)cellID.x - probeArrayDims[0] / 2) % probeArrayDims[0],
((int)cellID.y - probeArrayDims[1] / 2) % probeArrayDims[1],
((int)cellID.z - probeArrayDims[2] / 2) % probeArrayDims[2],
(uint)settings.MaxFrames },
((int)cellID.z - probeArrayDims[2] / 2) % probeArrayDims[2] },
.ValidMargin = { (int)cellIDDiff.x, (int)cellIDDiff.y, (int)cellIDDiff.z },
.MixParams = { settings.MinDiffuseVisibility, settings.DiffusePower, settings.MinSpecularVisibility, settings.SpecularPower },
.DirectionalDiffuse = settings.DirectionalDiffuse,
Expand Down Expand Up @@ -283,6 +278,7 @@ void Skylighting::PostPostLoad()
stl::write_thunk_call<Main_Precipitation_RenderOcclusion>(REL::RelocationID(35560, 36559).address() + REL::Relocate(0x3A1, 0x3A1, 0x2FA));
stl::write_thunk_call<SetViewFrustum>(REL::RelocationID(25643, 26185).address() + REL::Relocate(0x5D9, 0x59D, 0x5DC));
stl::write_vfunc<0x6, BSUtilityShader_SetupGeometry>(RE::VTABLE_BSUtilityShader[0]);
MenuOpenCloseEventHandler::Register();
}

//////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -435,12 +431,11 @@ void Skylighting::Main_Precipitation_RenderOcclusion::thunk()
}

{
doPrecip = true;

std::chrono::time_point<std::chrono::system_clock> currentTimer = std::chrono::system_clock::now();
auto timePassed = std::chrono::duration_cast<std::chrono::milliseconds>(currentTimer - singleton->lastUpdateTimer).count();

if (timePassed >= (1000.0f / 30.0f)) {
if (singleton->forceFrames || timePassed >= (1000.0f / 30.0f)) {
singleton->forceFrames = (uint)std::max(0, (int)singleton->forceFrames - 1);
singleton->lastUpdateTimer = currentTimer;

auto renderer = RE::BSGraphics::Renderer::GetSingleton();
Expand Down
46 changes: 40 additions & 6 deletions src/Features/Skylighting.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ struct Skylighting : Feature
struct Settings
{
bool DirectionalDiffuse = false;
float MaxZenith = 3.1415926f / 3.f; // 60 deg
int MaxFrames = 64;
float MaxZenith = 3.1415926f / 4.f; // 45 deg
float MinDiffuseVisibility = 0.1f;
float DiffusePower = 1.f;
float MinSpecularVisibility = 0.f;
Expand All @@ -56,14 +55,15 @@ struct Skylighting : Feature
float4 OcclusionDir;

float3 PosOffset; // cell origin in camera model space
float _pad0;
uint ArrayOrigin[4]; // xyz: array origin, w: max accum frames
uint _pad0;
uint ArrayOrigin[3]; // xyz: array origin, w: max accum frames
uint _pad1;
int ValidMargin[4];

float4 MixParams; // x: min diffuse visibility, y: diffuse mult, z: min specular visibility, w: specular mult

uint DirectionalDiffuse;
float3 _pad1;
uint _pad2[3];
} cbData;
static_assert(sizeof(SkylightingCB) % 16 == 0);
eastl::unique_ptr<ConstantBuffer> skylightingCB = nullptr;
Expand All @@ -90,6 +90,7 @@ struct Skylighting : Feature
bool foliage = false;
REX::W32::XMFLOAT4X4 OcclusionTransform;
float4 OcclusionDir;
uint forceFrames = 255 * 4;

std::chrono::time_point<std::chrono::system_clock> lastUpdateTimer = std::chrono::system_clock::now();

Expand Down Expand Up @@ -119,4 +120,37 @@ struct Skylighting : Feature
static void thunk(RE::NiCamera* a_camera, RE::NiFrustum* a_frustum);
static inline REL::Relocation<decltype(thunk)> func;
};
};

// Event handler
class MenuOpenCloseEventHandler : public RE::BSTEventSink<RE::MenuOpenCloseEvent>
{
public:
virtual RE::BSEventNotifyControl ProcessEvent(const RE::MenuOpenCloseEvent* a_event, RE::BSTEventSource<RE::MenuOpenCloseEvent>*)
{
// When entering a new cell through a loadscreen, update every frame until completion
if (a_event->menuName == RE::LoadingMenu::MENU_NAME) {
if (!a_event->opening)
Skylighting::GetSingleton()->forceFrames = 255 * 4;
}

return RE::BSEventNotifyControl::kContinue;
}

static bool Register()
{
static MenuOpenCloseEventHandler singleton;
auto ui = RE::UI::GetSingleton();

if (!ui) {
logger::error("UI event source not found");
return false;
}

ui->GetEventSource<RE::MenuOpenCloseEvent>()->AddEventSink(&singleton);

logger::info("Registered {}", typeid(singleton).name());

return true;
}
};
};

0 comments on commit 55deae6

Please sign in to comment.