From bbc3303d7ce39cbbdd28311b200a9426ecb42b33 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 3 Mar 2024 20:30:45 -0800 Subject: [PATCH 1/2] fix: fix VR for SSS --- src/Bindings.cpp | 60 +++++++++++++-------------- src/Feature.cpp | 3 +- src/Features/SubsurfaceScattering.cpp | 27 +++++++----- src/Features/SubsurfaceScattering.h | 4 +- src/Util.h | 13 ++++++ 5 files changed, 63 insertions(+), 44 deletions(-) diff --git a/src/Bindings.cpp b/src/Bindings.cpp index 9a9ea38ba..98d4011e6 100644 --- a/src/Bindings.cpp +++ b/src/Bindings.cpp @@ -1,14 +1,12 @@ #include "Bindings.h" - -#define DEFINE_VALUE(a_value) \ - auto& a_value = !REL::Module::IsVR() ? state->GetRuntimeData().a_value : state->GetVRRuntimeData().a_value; +#include "Util.h" void Bindings::DepthStencilStateSetDepthMode(RE::BSGraphics::DepthStencilDepthMode a_mode) { auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - DEFINE_VALUE(depthStencilDepthMode) - DEFINE_VALUE(depthStencilDepthModePrevious) - DEFINE_VALUE(stateUpdateFlags) + GET_INSTANCE_MEMBER(depthStencilDepthMode, state) + GET_INSTANCE_MEMBER(depthStencilDepthModePrevious, state) + GET_INSTANCE_MEMBER(stateUpdateFlags, state) if (depthStencilDepthMode != a_mode) { depthStencilDepthMode = a_mode; @@ -22,8 +20,8 @@ void Bindings::DepthStencilStateSetDepthMode(RE::BSGraphics::DepthStencilDepthMo void Bindings::AlphaBlendStateSetMode(uint32_t a_mode) { auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - DEFINE_VALUE(alphaBlendMode) - DEFINE_VALUE(stateUpdateFlags) + GET_INSTANCE_MEMBER(alphaBlendMode, state) + GET_INSTANCE_MEMBER(stateUpdateFlags, state) if (alphaBlendMode != a_mode) { alphaBlendMode = a_mode; @@ -34,8 +32,8 @@ void Bindings::AlphaBlendStateSetMode(uint32_t a_mode) void Bindings::AlphaBlendStateSetAlphaToCoverage(uint32_t a_value) { auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - DEFINE_VALUE(alphaBlendAlphaToCoverage) - DEFINE_VALUE(stateUpdateFlags) + GET_INSTANCE_MEMBER(alphaBlendAlphaToCoverage, state) + GET_INSTANCE_MEMBER(stateUpdateFlags, state) if (alphaBlendAlphaToCoverage != a_value) { alphaBlendAlphaToCoverage = a_value; @@ -46,8 +44,8 @@ void Bindings::AlphaBlendStateSetAlphaToCoverage(uint32_t a_value) void Bindings::AlphaBlendStateSetWriteMode(uint32_t a_value) { auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - DEFINE_VALUE(alphaBlendWriteMode) - DEFINE_VALUE(stateUpdateFlags) + GET_INSTANCE_MEMBER(alphaBlendWriteMode, state) + GET_INSTANCE_MEMBER(stateUpdateFlags, state) if (alphaBlendWriteMode != a_value) { alphaBlendWriteMode = a_value; @@ -60,7 +58,7 @@ void Bindings::SetOverwriteTerrainMode(bool a_enable) if (overrideTerrain != a_enable) { overrideTerrain = a_enable; auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - DEFINE_VALUE(stateUpdateFlags) + GET_INSTANCE_MEMBER(stateUpdateFlags, state) stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_DEPTH_MODE); stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_ALPHA_BLEND); } @@ -71,7 +69,7 @@ void Bindings::SetOverwriteTerrainMaskingMode(TerrainMaskMode a_mode) if (terrainMask != a_mode) { terrainMask = a_mode; auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - DEFINE_VALUE(stateUpdateFlags) + GET_INSTANCE_MEMBER(stateUpdateFlags, state) stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); } } @@ -92,23 +90,23 @@ void Bindings::SetDirtyStates(bool) { auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; - DEFINE_VALUE(depthStencilStencilMode) - DEFINE_VALUE(depthStencilDepthMode) - DEFINE_VALUE(alphaBlendAlphaToCoverage) - DEFINE_VALUE(alphaBlendMode) - DEFINE_VALUE(alphaBlendModeExtra) - DEFINE_VALUE(alphaBlendWriteMode) - DEFINE_VALUE(cubeMapRenderTarget) - DEFINE_VALUE(cubeMapRenderTargetView) - DEFINE_VALUE(depthStencil) - DEFINE_VALUE(depthStencilSlice) - DEFINE_VALUE(renderTargets) - DEFINE_VALUE(setCubeMapRenderTargetMode) - DEFINE_VALUE(setDepthStencilMode) - DEFINE_VALUE(setRenderTargetMode) - DEFINE_VALUE(stateUpdateFlags) - DEFINE_VALUE(stencilRef) - DEFINE_VALUE(PSTexture) + GET_INSTANCE_MEMBER(depthStencilStencilMode, state) + GET_INSTANCE_MEMBER(depthStencilDepthMode, state) + GET_INSTANCE_MEMBER(alphaBlendAlphaToCoverage, state) + GET_INSTANCE_MEMBER(alphaBlendMode, state) + GET_INSTANCE_MEMBER(alphaBlendModeExtra, state) + GET_INSTANCE_MEMBER(alphaBlendWriteMode, state) + GET_INSTANCE_MEMBER(cubeMapRenderTarget, state) + GET_INSTANCE_MEMBER(cubeMapRenderTargetView, state) + GET_INSTANCE_MEMBER(depthStencil, state) + GET_INSTANCE_MEMBER(depthStencilSlice, state) + GET_INSTANCE_MEMBER(renderTargets, state) + GET_INSTANCE_MEMBER(setCubeMapRenderTargetMode, state) + GET_INSTANCE_MEMBER(setDepthStencilMode, state) + GET_INSTANCE_MEMBER(setRenderTargetMode, state) + GET_INSTANCE_MEMBER(stateUpdateFlags, state) + GET_INSTANCE_MEMBER(stencilRef, state) + GET_INSTANCE_MEMBER(PSTexture, state) auto rendererData = RE::BSGraphics::Renderer::GetSingleton(); diff --git a/src/Feature.cpp b/src/Feature.cpp index 75f45a9d1..ba38d4635 100644 --- a/src/Feature.cpp +++ b/src/Feature.cpp @@ -126,7 +126,8 @@ const std::vector& Feature::GetFeatureList() WetnessEffects::GetSingleton(), LightLimitFix::GetSingleton(), TerrainBlending::GetSingleton(), - WaterCaustics::GetSingleton() + WaterCaustics::GetSingleton(), + SubsurfaceScattering::GetSingleton() }; return REL::Module::IsVR() ? featuresVR : features; diff --git a/src/Features/SubsurfaceScattering.cpp b/src/Features/SubsurfaceScattering.cpp index c93f416ef..a4ec1d0b1 100644 --- a/src/Features/SubsurfaceScattering.cpp +++ b/src/Features/SubsurfaceScattering.cpp @@ -304,8 +304,8 @@ void SubsurfaceScattering::Draw(const RE::BSShader* a_shader, const uint32_t) { if (a_shader->shaderType.get() == RE::BSShader::Type::Lighting) { auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - - if (normalsMode == 0 && state->GetRuntimeData().alphaTestEnabled) { + GET_INSTANCE_MEMBER(alphaTestEnabled, state) + if (normalsMode == 0 && alphaTestEnabled) { auto renderer = RE::BSGraphics::Renderer::GetSingleton(); auto context = renderer->GetRuntimeData().context; @@ -460,12 +460,19 @@ void SubsurfaceScattering::PostPostLoad() void SubsurfaceScattering::OverrideFirstPersonRenderTargets() { auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - state->GetRuntimeData().renderTargets[2] = normalsMode == 1 ? RE::RENDER_TARGETS::kNORMAL_TAAMASK_SSRMASK : RE::RENDER_TARGETS::kNORMAL_TAAMASK_SSRMASK_SWAP; - state->GetRuntimeData().setRenderTargetMode[2] = RE::BSGraphics::SetRenderTargetMode::SRTM_NO_CLEAR; - state->GetRuntimeData().stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); - - state->GetRuntimeData().alphaBlendMode = 0; - state->GetRuntimeData().alphaBlendModeExtra = 0; - state->GetRuntimeData().alphaBlendWriteMode = 1; - state->GetRuntimeData().stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_ALPHA_BLEND); + GET_INSTANCE_MEMBER(renderTargets, state) + GET_INSTANCE_MEMBER(setRenderTargetMode, state) + GET_INSTANCE_MEMBER(stateUpdateFlags, state) + GET_INSTANCE_MEMBER(alphaBlendMode, state) + GET_INSTANCE_MEMBER(alphaBlendModeExtra, state) + GET_INSTANCE_MEMBER(alphaBlendWriteMode, state) + + renderTargets[2] = normalsMode == 1 ? RE::RENDER_TARGETS::kNORMAL_TAAMASK_SSRMASK : RE::RENDER_TARGETS::kNORMAL_TAAMASK_SSRMASK_SWAP; + setRenderTargetMode[2] = RE::BSGraphics::SetRenderTargetMode::SRTM_NO_CLEAR; + stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); + + alphaBlendMode = 0; + alphaBlendModeExtra = 0; + alphaBlendWriteMode = 1; + stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_ALPHA_BLEND); } diff --git a/src/Features/SubsurfaceScattering.h b/src/Features/SubsurfaceScattering.h index 4425c616e..557204f43 100644 --- a/src/Features/SubsurfaceScattering.h +++ b/src/Features/SubsurfaceScattering.h @@ -135,9 +135,9 @@ struct SubsurfaceScattering : Feature static void Install() { - stl::write_thunk_call(REL::RelocationID(99938, 106583).address() + REL::Relocate(0x3C5, 0x3B4)); + stl::write_thunk_call(REL::RelocationID(99938, 106583).address() + REL::Relocate(0x3C5, 0x3B4, 0x3d2)); stl::write_thunk_call(REL::RelocationID(99943, 106588).address() + REL::Relocate(0x70, 0x66)); - stl::write_thunk_call(REL::RelocationID(99943, 106588).address() + REL::Relocate(0x49C, 0x47E)); + stl::write_thunk_call(REL::RelocationID(99943, 106588).address() + REL::Relocate(0x49C, 0x47E, 0x4fc)); logger::info("[SSS] Installed hooks"); } }; diff --git a/src/Util.h b/src/Util.h index ab45133af..150a37461 100644 --- a/src/Util.h +++ b/src/Util.h @@ -1,5 +1,18 @@ #pragma once +/** + @def GET_INSTANCE_MEMBER + @brief Set variable in current namespace based on instance member from GetRuntimeData or GetVRRuntimeData. + + @warning The class must have both a GetRuntimeData() and GetVRRuntimeData() function. + + @param a_value The instance member value to access (e.g., renderTargets). + @param a_source The instance of the class (e.g., state). + @result The a_value will be set as a variable in the current namespace. (e.g., auto& renderTargets = state->renderTargets;) + */ +#define GET_INSTANCE_MEMBER(a_value, a_source) \ + auto& a_value = !REL::Module::IsVR() ? a_source->GetRuntimeData().a_value : a_source->GetVRRuntimeData().a_value; + namespace Util { void StoreTransform3x4NoScale(DirectX::XMFLOAT3X4& Dest, const RE::NiTransform& Source); From a9b5b57b403f71af3b14af85823c931fb55179f8 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 3 Mar 2024 20:31:08 -0800 Subject: [PATCH 2/2] fix: fix ctd on startup --- src/Features/TerrainBlending.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Features/TerrainBlending.cpp b/src/Features/TerrainBlending.cpp index b805854c3..b1e2d528e 100644 --- a/src/Features/TerrainBlending.cpp +++ b/src/Features/TerrainBlending.cpp @@ -73,8 +73,9 @@ void TerrainBlending::SetupGeometry(RE::BSRenderPass* a_pass) Bindings::GetSingleton()->SetOverwriteTerrainMaskingMode(Bindings::TerrainMaskMode::kRead); auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; - auto view = Bindings::GetSingleton()->terrainBlendingMask->srv.get(); - context->PSSetShaderResources(35, 1, &view); + auto view = Bindings::GetSingleton()->terrainBlendingMask ? Bindings::GetSingleton()->terrainBlendingMask->srv.get() : nullptr; + if (view) + context->PSSetShaderResources(35, 1, &view); } else { Bindings::GetSingleton()->SetOverwriteTerrainMode(false); Bindings::GetSingleton()->SetOverwriteTerrainMaskingMode(Bindings::TerrainMaskMode::kNone);