From f82766824d99700a2f7f73c21469eb83520e1cd7 Mon Sep 17 00:00:00 2001 From: Tim <15017472+doodlum@users.noreply.github.com> Date: Sat, 7 Oct 2023 18:03:19 +0100 Subject: [PATCH 1/5] feat: increased portal-strict light limit --- .../Shaders/Features/LightLimitFix.ini | 2 +- .../Shaders/LightLimitFix/LightLimitFix.hlsli | 10 +++ package/Shaders/Lighting.hlsl | 27 ++++-- src/Features/LightLimitFix.cpp | 85 ++++++++++++++++++- src/Features/LightLimitFix.h | 27 ++++++ 5 files changed, 139 insertions(+), 12 deletions(-) diff --git a/features/Light Limit Fix/Shaders/Features/LightLimitFix.ini b/features/Light Limit Fix/Shaders/Features/LightLimitFix.ini index 01aaedc093..312d7ff985 100644 --- a/features/Light Limit Fix/Shaders/Features/LightLimitFix.ini +++ b/features/Light Limit Fix/Shaders/Features/LightLimitFix.ini @@ -1,2 +1,2 @@ [Info] -Version = 1-0-2 \ No newline at end of file +Version = 1-1-0 \ No newline at end of file diff --git a/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli b/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli index e682c4e6e4..2a65563120 100644 --- a/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli +++ b/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli @@ -33,12 +33,22 @@ StructuredBuffer lights : register(t17); StructuredBuffer lightList : register(t18); //MAX_CLUSTER_LIGHTS * 16^3 StructuredBuffer lightGrid : register(t19); //16^3 + #if !defined(SCREEN_SPACE_SHADOWS) Texture2D TexDepthSampler : register(t20); #endif // SCREEN_SPACE_SHADOWS StructuredBuffer perPassLLF : register(t32); +struct StrictLightData +{ + uint NumLights; + float4 PointLightPosition[15]; + float4 PointLightColor[15]; +}; + +StructuredBuffer strictLightData : register(t37); + bool GetClusterIndex(in float2 uv, in float z, out uint clusterIndex) { if (z < perPassLLF[0].LightsNear || z > perPassLLF[0].LightsFar) diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index f05fee90ed..b24f02cb40 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -1570,17 +1570,27 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace # if !defined(LOD) if (numLights > 0) { - [loop] for (float lightIndex = 0; lightIndex < numLights; ++lightIndex) +# if defined(LIGHT_LIMIT_FIX) + [loop] for (uint lightIndex = 0; lightIndex < strictLightData[0].NumLights; lightIndex++) { - int intLightIndex = lightIndex; - float3 lightDirection = PointLightPosition[eyeIndex * numLights + intLightIndex].xyz - input.InputPosition.xyz; + float3 lightDirection = strictLightData[0].PointLightPosition[lightIndex].xyz - input.InputPosition.xyz; float lightDist = length(lightDirection); - float intensityFactor = saturate(lightDist / PointLightPosition[intLightIndex].w); + float intensityFactor = saturate(lightDist / strictLightData[0].PointLightPosition[lightIndex].w); if (intensityFactor == 1) continue; float intensityMultiplier = 1 - intensityFactor * intensityFactor; - - float3 lightColor = PointLightColor[intLightIndex].xyz; + float3 lightColor = strictLightData[0].PointLightColor[lightIndex].xyz; +# else + [loop] for (uint lightIndex = 0; lightIndex < numLights; ++lightIndex) + { + float3 lightDirection = PointLightPosition[eyeIndex * numLights + lightIndex].xyz - input.InputPosition.xyz; + float lightDist = length(lightDirection); + float intensityFactor = saturate(lightDist / PointLightPosition[lightIndex].w); + if (intensityFactor == 1) + continue; + float intensityMultiplier = 1 - intensityFactor * intensityFactor; + float3 lightColor = PointLightColor[lightIndex].xyz; +# endif float3 nsLightColor = lightColor; float shadowComponent = 1.0; @@ -1664,11 +1674,11 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace if (lightCount) { uint lightOffset = lightGrid[clusterIndex].offset; + float shadowQualityScale = saturate(1.0 - ((float)lightCount / 128.0)); + float3 worldSpaceNormal = normalize(mul(CameraViewInverse[eyeIndex], float4(screenSpaceNormal, 0))); float3 worldSpaceViewDirection = -normalize(input.WorldPosition.xyz); - float shadowQualityScale = saturate(1.0 - ((float)lightCount / 128.0)); - # if (defined(SKINNED) || !defined(MODELSPACENORMALS)) float3 worldSpaceVertexNormal = vertexNormal; # if (!defined(DRAW_IN_WORLDSPACE)) @@ -1690,6 +1700,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace } # endif # endif + [loop] for (uint i = 0; i < lightCount; i++) { uint light_index = lightList[lightOffset + i]; diff --git a/src/Features/LightLimitFix.cpp b/src/Features/LightLimitFix.cpp index 9938c794b2..9f7abaf032 100644 --- a/src/Features/LightLimitFix.cpp +++ b/src/Features/LightLimitFix.cpp @@ -178,6 +178,23 @@ void LightLimitFix::SetupResources() perPass->CreateSRV(srvDesc); } + { + D3D11_BUFFER_DESC sbDesc{}; + sbDesc.Usage = D3D11_USAGE_DYNAMIC; + sbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + sbDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + sbDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + sbDesc.StructureByteStride = sizeof(StrictLightData); + sbDesc.ByteWidth = sizeof(StrictLightData); + strictLightData = std::make_unique(sbDesc); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = DXGI_FORMAT_UNKNOWN; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + srvDesc.Buffer.FirstElement = 0; + srvDesc.Buffer.NumElements = 1; + strictLightData->CreateSRV(srvDesc); + } { clusterBuildingCS = (ID3D11ComputeShader*)Util::CompileShader(L"Data\\Shaders\\LightLimitFix\\ClusterBuildingCS.hlsl", {}, "cs_5_0"); clusterCullingCS = (ID3D11ComputeShader*)Util::CompileShader(L"Data\\Shaders\\LightLimitFix\\ClusterCullingCS.hlsl", {}, "cs_5_0"); @@ -272,8 +289,62 @@ void LightLimitFix::Save(json& o_json) void LightLimitFix::BSLightingShader_SetupGeometry_Before(RE::BSRenderPass* a_pass) { strictLightsCount = a_pass->numLights - 1; + strictLightDataTemp.NumLights = 0; +} + +void LightLimitFix::BSLightingShader_SetupGeometry_After(RE::BSRenderPass*) +{ + auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; + D3D11_MAPPED_SUBRESOURCE mapped; + DX::ThrowIfFailed(context->Map(strictLightData->resource.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); + size_t bytes = sizeof(StrictLightData); + memcpy_s(mapped.pData, bytes, &strictLightDataTemp, bytes); + context->Unmap(strictLightData->resource.get(), 0); +} + +void LightLimitFix::BSLightingShader_SetupGeometry_GeometrySetupConstantPointLights(RE::BSRenderPass* a_pass, DirectX::XMMATRIX& Transform, uint32_t, uint32_t, float WorldScale, Space RenderSpace) +{ + strictLightDataTemp.NumLights = a_pass->numLights - 1; + for (uint32_t i = 0; i < strictLightDataTemp.NumLights; i++) + { + auto bsLight = a_pass->sceneLights[i + 1]; + auto niLight = bsLight->light.get(); + + auto& runtimeData = niLight->GetLightRuntimeData(); + + float radius = runtimeData.radius.x; + float3 worldPos = { niLight->world.translate.x, niLight->world.translate.y, niLight->world.translate.z }; + + if (RenderSpace == Space::Model) { + auto position = DirectX::XMVector3TransformCoord(worldPos, Transform); + float3 position3; + XMStoreFloat3(&position3, position); + + strictLightDataTemp.PointLightPosition[i].x = position3.x; + strictLightDataTemp.PointLightPosition[i].y = position3.y; + strictLightDataTemp.PointLightPosition[i].z = position3.z; + strictLightDataTemp.PointLightPosition[i].w = radius / WorldScale; + } else { + auto posAdjust = RE::BSGraphics::RendererShadowState::GetSingleton()->GetRuntimeData().posAdjust.getEye(); + worldPos = worldPos - float3(posAdjust.x, posAdjust.y, posAdjust.z); + strictLightDataTemp.PointLightPosition[i].x = worldPos.x; + strictLightDataTemp.PointLightPosition[i].y = worldPos.y; + strictLightDataTemp.PointLightPosition[i].z = worldPos.z; + strictLightDataTemp.PointLightPosition[i].w = radius; + } + + float3 color = { runtimeData.diffuse.red, runtimeData.diffuse.green, runtimeData.diffuse.blue }; + color *= runtimeData.fade; + color *= bsLight->lodDimmer; + + strictLightDataTemp.PointLightColor[i].x = color.x; + strictLightDataTemp.PointLightColor[i].y = color.y; + strictLightDataTemp.PointLightColor[i].z = color.z; + strictLightDataTemp.PointLightColor[i].w = 0; + } } + void LightLimitFix::SetLightPosition(LightLimitFix::LightData& a_light, RE::NiPoint3& a_initialPosition) { auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); @@ -320,6 +391,7 @@ void LightLimitFix::AddParticleLightLuminance(RE::NiPoint3& targetPosition, int& numHits += particleLightsDetectionHits; } + void LightLimitFix::Bind() { auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; @@ -355,6 +427,7 @@ void LightLimitFix::Bind() { PerPass perPassData{}; + perPassData.CameraData.x = accumulator->kCamera->GetRuntimeData2().viewFrustum.fFar; perPassData.CameraData.y = accumulator->kCamera->GetRuntimeData2().viewFrustum.fNear; perPassData.CameraData.z = accumulator->kCamera->GetRuntimeData2().viewFrustum.fFar - accumulator->kCamera->GetRuntimeData2().viewFrustum.fNear; @@ -401,6 +474,12 @@ void LightLimitFix::Bind() views[0] = perPass->srv.get(); context->PSSetShaderResources(32, ARRAYSIZE(views), views); } + + { + ID3D11ShaderResourceView* views[1]{}; + views[0] = strictLightData->srv.get(); + context->PSSetShaderResources(37, ARRAYSIZE(views), views); + } } bool LightLimitFix::IsValidLight(RE::BSLight* a_light) @@ -605,7 +684,7 @@ bool LightLimitFix::AddCachedParticleLights(eastl::vector& lightsData dimmer = 0.0f; } - //light.color *= dimmer; + light.color *= dimmer; float distantLightFadeStart = lightsFar * lightsFar * (lightFadeStart / lightFadeEnd); float distantLightFadeEnd = lightsFar * lightsFar; @@ -618,7 +697,7 @@ bool LightLimitFix::AddCachedParticleLights(eastl::vector& lightsData dimmer = 0.0f; } - //light.color *= dimmer; + light.color *= dimmer; if ((light.color.x + light.color.y + light.color.z) > 1e-4 && light.radius > 1e-4) { if (a_geometry && a_config && a_config->flicker) { @@ -636,7 +715,7 @@ bool LightLimitFix::AddCachedParticleLights(eastl::vector& lightsData light.positionWS[eyeIndex].y += (float)perlin2.noise1D(scaledTimer) * a_config->flickerMovement; light.positionWS[eyeIndex].z += (float)perlin3.noise1D(scaledTimer) * a_config->flickerMovement; } - dimmer = std::max(0.0f, dimmer - ((float)perlin4.noise1D_01(scaledTimer) * a_config->flickerIntensity)); + dimmer = std::max(0.0f, dimmer - ((float)perlin4.noise1D_01(scaledTimer) * a_config->flickerIntensity)); // todo: this is wrong } CachedParticleLight cachedParticleLight{}; diff --git a/src/Features/LightLimitFix.h b/src/Features/LightLimitFix.h index 0e6e44643f..40e8ff502f 100644 --- a/src/Features/LightLimitFix.h +++ b/src/Features/LightLimitFix.h @@ -71,6 +71,15 @@ struct LightLimitFix : Feature uint FrameCount; }; + struct StrictLightData + { + uint NumLights; + float4 PointLightPosition[15]; + float4 PointLightColor[15]; + }; + + StrictLightData strictLightDataTemp; + struct CachedParticleLight { float grey; @@ -79,6 +88,7 @@ struct LightLimitFix : Feature }; std::unique_ptr perPass = nullptr; + std::unique_ptr strictLightData = nullptr; bool rendered = false; int eyeCount = !REL::Module::IsVR() ? 1 : 2; @@ -154,6 +164,7 @@ struct LightLimitFix : Feature bool CheckParticleLights(RE::BSRenderPass* a_pass, uint32_t a_technique); void BSLightingShader_SetupGeometry_Before(RE::BSRenderPass* a_pass); + void BSLightingShader_SetupGeometry_After(RE::BSRenderPass* a_pass); enum class Space { @@ -168,6 +179,9 @@ struct LightLimitFix : Feature float CalculateLuminance(CachedParticleLight& light, RE::NiPoint3& point); void AddParticleLightLuminance(RE::NiPoint3& targetPosition, int& numHits, float& lightLevel); + void BSLightingShader_SetupGeometry_GeometrySetupConstantPointLights(RE::BSRenderPass* a_pass, DirectX::XMMATRIX& Transform, uint32_t, uint32_t, float WorldScale, Space RenderSpace); + + struct Hooks { struct ValidLight1 @@ -233,6 +247,7 @@ struct LightLimitFix : Feature { GetSingleton()->BSLightingShader_SetupGeometry_Before(Pass); func(This, Pass, RenderFlags); + GetSingleton()->BSLightingShader_SetupGeometry_After(Pass); } static inline REL::Relocation func; }; @@ -247,6 +262,16 @@ struct LightLimitFix : Feature static inline REL::Relocation func; }; + struct BSLightingShader_SetupGeometry_GeometrySetupConstantPointLights + { + static void thunk(RE::BSGraphics::PixelShader* PixelShader, RE::BSRenderPass* Pass, DirectX::XMMATRIX& Transform, uint32_t LightCount, uint32_t ShadowLightCount, float WorldScale, Space RenderSpace) + { + GetSingleton()->BSLightingShader_SetupGeometry_GeometrySetupConstantPointLights(Pass, Transform, LightCount, ShadowLightCount, WorldScale, RenderSpace); + func(PixelShader, Pass, Transform, LightCount, ShadowLightCount, WorldScale, RenderSpace); + } + static inline REL::Relocation func; + }; + static void Install() { stl::write_thunk_call(REL::RelocationID(100994, 107781).address() + 0x92); @@ -262,6 +287,8 @@ struct LightLimitFix : Feature stl::write_vfunc<0x6, BSLightingShader_SetupGeometry>(RE::VTABLE_BSLightingShader[0]); logger::info("[LLF] Installed hooks"); + + stl::write_thunk_call(REL::RelocationID(100565, 107300).address() + REL::Relocate(0x523, 0xB0E)); } }; }; From 32cf1ab5e454981eedbd242100afc2305556dc6d Mon Sep 17 00:00:00 2001 From: Tim <15017472+doodlum@users.noreply.github.com> Date: Sat, 7 Oct 2023 18:30:46 +0100 Subject: [PATCH 2/5] refactor: portal light limit code --- .../Shaders/LightLimitFix/LightLimitFix.hlsli | 6 +- package/Shaders/Lighting.hlsl | 10 ++-- src/Features/LightLimitFix.cpp | 55 ++++++------------- src/Features/LightLimitFix.h | 17 +++--- 4 files changed, 34 insertions(+), 54 deletions(-) diff --git a/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli b/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli index 2a65563120..9d51d49364 100644 --- a/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli +++ b/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli @@ -21,7 +21,6 @@ struct PerPassLLF bool EnableContactShadows; bool EnableLightsVisualisation; uint LightsVisualisationMode; - uint StrictLightsCount; float LightsNear; float LightsFar; float4 CameraData; @@ -43,8 +42,9 @@ StructuredBuffer perPassLLF : register(t32); struct StrictLightData { uint NumLights; - float4 PointLightPosition[15]; - float4 PointLightColor[15]; + float3 PointLightPosition[15]; + float PointLightRadius[15]; + float3 PointLightColor[15]; }; StructuredBuffer strictLightData : register(t37); diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index b24f02cb40..45b3caf117 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -1573,13 +1573,13 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace # if defined(LIGHT_LIMIT_FIX) [loop] for (uint lightIndex = 0; lightIndex < strictLightData[0].NumLights; lightIndex++) { - float3 lightDirection = strictLightData[0].PointLightPosition[lightIndex].xyz - input.InputPosition.xyz; + float3 lightDirection = strictLightData[0].PointLightPosition[lightIndex] - input.InputPosition; float lightDist = length(lightDirection); - float intensityFactor = saturate(lightDist / strictLightData[0].PointLightPosition[lightIndex].w); + float intensityFactor = saturate(lightDist / strictLightData[0].PointLightRadius[lightIndex]); if (intensityFactor == 1) continue; float intensityMultiplier = 1 - intensityFactor * intensityFactor; - float3 lightColor = strictLightData[0].PointLightColor[lightIndex].xyz; + float3 lightColor = strictLightData[0].PointLightColor[lightIndex]; # else [loop] for (uint lightIndex = 0; lightIndex < numLights; ++lightIndex) { @@ -1934,9 +1934,9 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace # if defined(LIGHT_LIMIT_FIX) if (perPassLLF[0].EnableLightsVisualisation) { if (perPassLLF[0].LightsVisualisationMode == 0) { - psout.Albedo.xyz = TurboColormap(perPassLLF[0].StrictLightsCount > 7); + psout.Albedo.xyz = TurboColormap(strictLightData[0].NumLights >= 7.0); } else if (perPassLLF[0].LightsVisualisationMode == 1) { - psout.Albedo.xyz = TurboColormap((float)perPassLLF[0].StrictLightsCount / 7.0); + psout.Albedo.xyz = TurboColormap((float)strictLightData[0].NumLights / 15.0); } else { psout.Albedo.xyz = TurboColormap((float)lightCount / 128.0); } diff --git a/src/Features/LightLimitFix.cpp b/src/Features/LightLimitFix.cpp index 9f7abaf032..065c91a285 100644 --- a/src/Features/LightLimitFix.cpp +++ b/src/Features/LightLimitFix.cpp @@ -286,64 +286,46 @@ void LightLimitFix::Save(json& o_json) o_json[GetName()] = settings; } -void LightLimitFix::BSLightingShader_SetupGeometry_Before(RE::BSRenderPass* a_pass) +void LightLimitFix::BSLightingShader_SetupGeometry_Before(RE::BSRenderPass*) { - strictLightsCount = a_pass->numLights - 1; strictLightDataTemp.NumLights = 0; } -void LightLimitFix::BSLightingShader_SetupGeometry_After(RE::BSRenderPass*) -{ - auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; - D3D11_MAPPED_SUBRESOURCE mapped; - DX::ThrowIfFailed(context->Map(strictLightData->resource.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); - size_t bytes = sizeof(StrictLightData); - memcpy_s(mapped.pData, bytes, &strictLightDataTemp, bytes); - context->Unmap(strictLightData->resource.get(), 0); -} - void LightLimitFix::BSLightingShader_SetupGeometry_GeometrySetupConstantPointLights(RE::BSRenderPass* a_pass, DirectX::XMMATRIX& Transform, uint32_t, uint32_t, float WorldScale, Space RenderSpace) { strictLightDataTemp.NumLights = a_pass->numLights - 1; - for (uint32_t i = 0; i < strictLightDataTemp.NumLights; i++) - { + for (uint32_t i = 0; i < strictLightDataTemp.NumLights; i++) { auto bsLight = a_pass->sceneLights[i + 1]; auto niLight = bsLight->light.get(); auto& runtimeData = niLight->GetLightRuntimeData(); - float radius = runtimeData.radius.x; float3 worldPos = { niLight->world.translate.x, niLight->world.translate.y, niLight->world.translate.z }; if (RenderSpace == Space::Model) { - auto position = DirectX::XMVector3TransformCoord(worldPos, Transform); - float3 position3; - XMStoreFloat3(&position3, position); - - strictLightDataTemp.PointLightPosition[i].x = position3.x; - strictLightDataTemp.PointLightPosition[i].y = position3.y; - strictLightDataTemp.PointLightPosition[i].z = position3.z; - strictLightDataTemp.PointLightPosition[i].w = radius / WorldScale; + strictLightDataTemp.PointLightPosition[i] = DirectX::SimpleMath::Vector3::Transform(worldPos, Transform); + strictLightDataTemp.PointLightRadius[i] = runtimeData.radius.x / WorldScale; } else { auto posAdjust = RE::BSGraphics::RendererShadowState::GetSingleton()->GetRuntimeData().posAdjust.getEye(); - worldPos = worldPos - float3(posAdjust.x, posAdjust.y, posAdjust.z); - strictLightDataTemp.PointLightPosition[i].x = worldPos.x; - strictLightDataTemp.PointLightPosition[i].y = worldPos.y; - strictLightDataTemp.PointLightPosition[i].z = worldPos.z; - strictLightDataTemp.PointLightPosition[i].w = radius; + strictLightDataTemp.PointLightPosition[i] = worldPos - float3(posAdjust.x, posAdjust.y, posAdjust.z); + strictLightDataTemp.PointLightRadius[i] = runtimeData.radius.x; } - float3 color = { runtimeData.diffuse.red, runtimeData.diffuse.green, runtimeData.diffuse.blue }; - color *= runtimeData.fade; - color *= bsLight->lodDimmer; - - strictLightDataTemp.PointLightColor[i].x = color.x; - strictLightDataTemp.PointLightColor[i].y = color.y; - strictLightDataTemp.PointLightColor[i].z = color.z; - strictLightDataTemp.PointLightColor[i].w = 0; + strictLightDataTemp.PointLightColor[i] = { runtimeData.diffuse.red, runtimeData.diffuse.green, runtimeData.diffuse.blue }; + strictLightDataTemp.PointLightColor[i] *= runtimeData.fade; + strictLightDataTemp.PointLightColor[i] *= bsLight->lodDimmer; } } +void LightLimitFix::BSLightingShader_SetupGeometry_After(RE::BSRenderPass*) +{ + auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; + D3D11_MAPPED_SUBRESOURCE mapped; + DX::ThrowIfFailed(context->Map(strictLightData->resource.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); + size_t bytes = sizeof(StrictLightData); + memcpy_s(mapped.pData, bytes, &strictLightDataTemp, bytes); + context->Unmap(strictLightData->resource.get(), 0); +} void LightLimitFix::SetLightPosition(LightLimitFix::LightData& a_light, RE::NiPoint3& a_initialPosition) { @@ -459,7 +441,6 @@ void LightLimitFix::Bind() perPassData.EnableContactShadows = settings.EnableContactShadows; perPassData.EnableLightsVisualisation = settings.EnableLightsVisualisation; perPassData.LightsVisualisationMode = settings.LightsVisualisationMode; - perPassData.StrictLightsCount = strictLightsCount; D3D11_MAPPED_SUBRESOURCE mapped; DX::ThrowIfFailed(context->Map(perPass->resource.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); diff --git a/src/Features/LightLimitFix.h b/src/Features/LightLimitFix.h index 40e8ff502f..63011b4a05 100644 --- a/src/Features/LightLimitFix.h +++ b/src/Features/LightLimitFix.h @@ -63,7 +63,6 @@ struct LightLimitFix : Feature uint EnableContactShadows; uint EnableLightsVisualisation; uint LightsVisualisationMode; - uint StrictLightsCount; float LightsNear; float LightsFar; float4 CameraData; @@ -74,8 +73,9 @@ struct LightLimitFix : Feature struct StrictLightData { uint NumLights; - float4 PointLightPosition[15]; - float4 PointLightColor[15]; + float3 PointLightPosition[15]; + float PointLightRadius[15]; + float3 PointLightColor[15]; }; StrictLightData strictLightDataTemp; @@ -117,8 +117,6 @@ struct LightLimitFix : Feature eastl::hash_map queuedParticleLights; eastl::hash_map particleLights; - std::uint32_t strictLightsCount = 0; - virtual void SetupResources(); virtual void Reset(); @@ -163,8 +161,8 @@ struct LightLimitFix : Feature Settings settings; bool CheckParticleLights(RE::BSRenderPass* a_pass, uint32_t a_technique); + void BSLightingShader_SetupGeometry_Before(RE::BSRenderPass* a_pass); - void BSLightingShader_SetupGeometry_After(RE::BSRenderPass* a_pass); enum class Space { @@ -172,6 +170,10 @@ struct LightLimitFix : Feature Model = 1, }; + void BSLightingShader_SetupGeometry_GeometrySetupConstantPointLights(RE::BSRenderPass* a_pass, DirectX::XMMATRIX& Transform, uint32_t, uint32_t, float WorldScale, Space RenderSpace); + + void BSLightingShader_SetupGeometry_After(RE::BSRenderPass* a_pass); + std::shared_mutex cachedParticleLightsMutex; eastl::vector cachedParticleLights; uint32_t particleLightsDetectionHits = 0; @@ -179,9 +181,6 @@ struct LightLimitFix : Feature float CalculateLuminance(CachedParticleLight& light, RE::NiPoint3& point); void AddParticleLightLuminance(RE::NiPoint3& targetPosition, int& numHits, float& lightLevel); - void BSLightingShader_SetupGeometry_GeometrySetupConstantPointLights(RE::BSRenderPass* a_pass, DirectX::XMMATRIX& Transform, uint32_t, uint32_t, float WorldScale, Space RenderSpace); - - struct Hooks { struct ValidLight1 From ee2c7ddbf423fc867231ba48984d31680c718984 Mon Sep 17 00:00:00 2001 From: Tim <15017472+doodlum@users.noreply.github.com> Date: Sat, 7 Oct 2023 20:32:02 +0100 Subject: [PATCH 3/5] fix: dark effect shaders --- src/Features/LightLimitFix.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Features/LightLimitFix.h b/src/Features/LightLimitFix.h index 63011b4a05..c3db15202f 100644 --- a/src/Features/LightLimitFix.h +++ b/src/Features/LightLimitFix.h @@ -187,7 +187,7 @@ struct LightLimitFix : Feature { static bool thunk(RE::BSShaderProperty* a_property, RE::BSLight* a_light) { - return func(a_property, a_light) && (a_light->portalStrict || !a_light->portalGraph || skyrim_cast(a_light)); + return func(a_property, a_light) && (!netimmerse_cast(a_property) || (a_light->portalStrict || !a_light->portalGraph || skyrim_cast(a_light))); } static inline REL::Relocation func; }; @@ -196,7 +196,7 @@ struct LightLimitFix : Feature { static bool thunk(RE::BSShaderProperty* a_property, RE::BSLight* a_light) { - return func(a_property, a_light) && (a_light->portalStrict || !a_light->portalGraph || skyrim_cast(a_light)); + return func(a_property, a_light) && (!netimmerse_cast(a_property) || (a_light->portalStrict || !a_light->portalGraph || skyrim_cast(a_light))); } static inline REL::Relocation func; }; @@ -205,7 +205,7 @@ struct LightLimitFix : Feature { static bool thunk(RE::BSShaderProperty* a_property, RE::BSLight* a_light) { - return func(a_property, a_light) && (a_light->portalStrict || !a_light->portalGraph || skyrim_cast(a_light)); + return func(a_property, a_light) && (!netimmerse_cast(a_property) || (a_light->portalStrict || !a_light->portalGraph || skyrim_cast(a_light))); } static inline REL::Relocation func; }; From 12c25f07dd6d3ddb34128e735a5d506866a9d5ac Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sat, 7 Oct 2023 20:24:52 -0700 Subject: [PATCH 4/5] fix: add vr offset for llf hook --- src/Features/LightLimitFix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Features/LightLimitFix.h b/src/Features/LightLimitFix.h index c3db15202f..e079f855d5 100644 --- a/src/Features/LightLimitFix.h +++ b/src/Features/LightLimitFix.h @@ -287,7 +287,7 @@ struct LightLimitFix : Feature logger::info("[LLF] Installed hooks"); - stl::write_thunk_call(REL::RelocationID(100565, 107300).address() + REL::Relocate(0x523, 0xB0E)); + stl::write_thunk_call(REL::RelocationID(100565, 107300).address() + REL::Relocate(0x523, 0xB0E, 0x5fe)); } }; }; From cfd79d8c028abcd50f3242c5278f8aa6872ab35e Mon Sep 17 00:00:00 2001 From: doodlum Date: Sun, 8 Oct 2023 03:32:16 +0000 Subject: [PATCH 5/5] =?UTF-8?q?style:=20=F0=9F=8E=A8=20apply=20clang-forma?= =?UTF-8?q?t=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli | 1 - package/Shaders/Lighting.hlsl | 4 ++-- src/Features/LightLimitFix.cpp | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli b/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli index 9d51d49364..67becf8b81 100644 --- a/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli +++ b/features/Light Limit Fix/Shaders/LightLimitFix/LightLimitFix.hlsli @@ -32,7 +32,6 @@ StructuredBuffer lights : register(t17); StructuredBuffer lightList : register(t18); //MAX_CLUSTER_LIGHTS * 16^3 StructuredBuffer lightGrid : register(t19); //16^3 - #if !defined(SCREEN_SPACE_SHADOWS) Texture2D TexDepthSampler : register(t20); #endif // SCREEN_SPACE_SHADOWS diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index 45b3caf117..081dbfb267 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -1590,7 +1590,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace continue; float intensityMultiplier = 1 - intensityFactor * intensityFactor; float3 lightColor = PointLightColor[lightIndex].xyz; -# endif +# endif float3 nsLightColor = lightColor; float shadowComponent = 1.0; @@ -1675,7 +1675,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace uint lightOffset = lightGrid[clusterIndex].offset; float shadowQualityScale = saturate(1.0 - ((float)lightCount / 128.0)); - + float3 worldSpaceNormal = normalize(mul(CameraViewInverse[eyeIndex], float4(screenSpaceNormal, 0))); float3 worldSpaceViewDirection = -normalize(input.WorldPosition.xyz); diff --git a/src/Features/LightLimitFix.cpp b/src/Features/LightLimitFix.cpp index 065c91a285..a473de0c67 100644 --- a/src/Features/LightLimitFix.cpp +++ b/src/Features/LightLimitFix.cpp @@ -373,7 +373,6 @@ void LightLimitFix::AddParticleLightLuminance(RE::NiPoint3& targetPosition, int& numHits += particleLightsDetectionHits; } - void LightLimitFix::Bind() { auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; @@ -696,7 +695,7 @@ bool LightLimitFix::AddCachedParticleLights(eastl::vector& lightsData light.positionWS[eyeIndex].y += (float)perlin2.noise1D(scaledTimer) * a_config->flickerMovement; light.positionWS[eyeIndex].z += (float)perlin3.noise1D(scaledTimer) * a_config->flickerMovement; } - dimmer = std::max(0.0f, dimmer - ((float)perlin4.noise1D_01(scaledTimer) * a_config->flickerIntensity)); // todo: this is wrong + dimmer = std::max(0.0f, dimmer - ((float)perlin4.noise1D_01(scaledTimer) * a_config->flickerIntensity)); // todo: this is wrong } CachedParticleLight cachedParticleLight{};