Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: complete skylighting during loadscreen #433

Merged
merged 14 commits into from
Aug 21, 2024
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
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;
}
};
};
Loading