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

fix: fix VR for SSS #198

Merged
merged 2 commits into from
Mar 4, 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
60 changes: 29 additions & 31 deletions src/Bindings.cpp
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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);
}
Expand All @@ -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);
}
}
Expand All @@ -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();

Expand Down
3 changes: 2 additions & 1 deletion src/Feature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ const std::vector<Feature*>& Feature::GetFeatureList()
WetnessEffects::GetSingleton(),
LightLimitFix::GetSingleton(),
TerrainBlending::GetSingleton(),
WaterCaustics::GetSingleton()
WaterCaustics::GetSingleton(),
SubsurfaceScattering::GetSingleton()
};

return REL::Module::IsVR() ? featuresVR : features;
Expand Down
27 changes: 17 additions & 10 deletions src/Features/SubsurfaceScattering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}
4 changes: 2 additions & 2 deletions src/Features/SubsurfaceScattering.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ struct SubsurfaceScattering : Feature

static void Install()
{
stl::write_thunk_call<BSShaderAccumulator_FinishAccumulating_Standard_PreResolveDepth_QPassesWithinRange_WaterStencil>(REL::RelocationID(99938, 106583).address() + REL::Relocate(0x3C5, 0x3B4));
stl::write_thunk_call<BSShaderAccumulator_FinishAccumulating_Standard_PreResolveDepth_QPassesWithinRange_WaterStencil>(REL::RelocationID(99938, 106583).address() + REL::Relocate(0x3C5, 0x3B4, 0x3d2));
stl::write_thunk_call<Main_RenderFirstPersonView_Start>(REL::RelocationID(99943, 106588).address() + REL::Relocate(0x70, 0x66));
stl::write_thunk_call<Main_RenderFirstPersonView_End>(REL::RelocationID(99943, 106588).address() + REL::Relocate(0x49C, 0x47E));
stl::write_thunk_call<Main_RenderFirstPersonView_End>(REL::RelocationID(99943, 106588).address() + REL::Relocate(0x49C, 0x47E, 0x4fc));
logger::info("[SSS] Installed hooks");
}
};
Expand Down
5 changes: 3 additions & 2 deletions src/Features/TerrainBlending.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
13 changes: 13 additions & 0 deletions src/Util.h
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
Loading