From 3daf665a57c54078dcb376a1c2a055409798b7ff Mon Sep 17 00:00:00 2001 From: FlayaN Date: Thu, 4 Jul 2024 18:47:32 +0200 Subject: [PATCH 01/20] fix: fix VR offsets --- extern/CommonLibSSE-NG | 2 +- src/Deferred.cpp | 2 +- src/Features/Skylighting.h | 2 +- src/Features/TerrainBlending.cpp | 25 +++++++++++++------------ src/Features/TerrainBlending.h | 2 +- src/Hooks.cpp | 16 ++++++++++------ src/XSEPlugin.cpp | 4 ++++ 7 files changed, 31 insertions(+), 22 deletions(-) diff --git a/extern/CommonLibSSE-NG b/extern/CommonLibSSE-NG index e83b23bdd..735fa6dae 160000 --- a/extern/CommonLibSSE-NG +++ b/extern/CommonLibSSE-NG @@ -1 +1 @@ -Subproject commit e83b23bddb893d44b8f3cf3e6379b9087ad25cc9 +Subproject commit 735fa6dae8ec72966ee02673dd689c6516d49f71 diff --git a/src/Deferred.cpp b/src/Deferred.cpp index da2db23f0..bc481e4c4 100644 --- a/src/Deferred.cpp +++ b/src/Deferred.cpp @@ -524,7 +524,7 @@ void Deferred::EndDeferred() } for (uint i = 4; i < 8; i++) { - shadowState->GetRuntimeData().renderTargets[i] = RE::RENDER_TARGET::kNONE; + renderTargets[i] = RE::RENDER_TARGET::kNONE; } auto& context = State::GetSingleton()->context; diff --git a/src/Features/Skylighting.h b/src/Features/Skylighting.h index c89a03d8e..64340d601 100644 --- a/src/Features/Skylighting.h +++ b/src/Features/Skylighting.h @@ -452,7 +452,7 @@ struct Skylighting : Feature { logger::info("[SKYLIGHTING] Hooking BSLightingShaderProperty::GetPrecipitationOcclusionMapRenderPassesImp"); stl::write_vfunc<0x2D, BSLightingShaderProperty_GetPrecipitationOcclusionMapRenderPassesImpl>(RE::VTABLE_BSLightingShaderProperty[0]); - stl::write_thunk_call(REL::RelocationID(35560, 36559).address() + REL::Relocate(0x3A1, 0x3A1)); + stl::write_thunk_call(REL::RelocationID(35560, 36559).address() + REL::Relocate(0x3A1, 0x3A1, 0x2FA)); stl::write_vfunc<0x4, BSWaterShader_SetupMaterial>(RE::VTABLE_BSWaterShader[0]); } }; diff --git a/src/Features/TerrainBlending.cpp b/src/Features/TerrainBlending.cpp index 710fbe1ab..ca68bc4d4 100644 --- a/src/Features/TerrainBlending.cpp +++ b/src/Features/TerrainBlending.cpp @@ -1,7 +1,7 @@ #include "TerrainBlending.h" #include "State.h" -#include +#include "Util.h" void TerrainBlending::DrawSettings() { @@ -160,9 +160,6 @@ struct BlendStates ID3D11BlendState* a[7][2][13][2]; }; -#define GET_INSTANCE_MEMBER(a_value, a_source) \ - auto& a_value = !REL::Module::IsVR() ? a_source->GetRuntimeData().a_value : a_source->GetVRRuntimeData().a_value; - void TerrainBlending::TerrainShaderHacks() { if (renderTerrainDepth) { @@ -176,7 +173,8 @@ void TerrainBlending::TerrainShaderHacks() auto dsv = terrainDepth.views[0]; context->OMSetRenderTargets(0, nullptr, dsv); auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); - context->VSSetShader((ID3D11VertexShader*)shadowState->GetRuntimeData().currentVertexShader->shader, NULL, NULL); + GET_INSTANCE_MEMBER(currentVertexShader, shadowState) + context->VSSetShader((ID3D11VertexShader*)currentVertexShader->shader, NULL, NULL); } renderAltTerrain = !renderAltTerrain; } @@ -239,11 +237,12 @@ void TerrainBlending::ResetTerrainDepth() auto& mainDepth = renderer->GetDepthStencilData().depthStencils[RE::RENDER_TARGETS_DEPTHSTENCIL::kMAIN]; - auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - state->GetRuntimeData().stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); - auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); - context->VSSetShader((ID3D11VertexShader*)shadowState->GetRuntimeData().currentVertexShader->shader, NULL, NULL); + GET_INSTANCE_MEMBER(stateUpdateFlags, shadowState) + stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); + + GET_INSTANCE_MEMBER(currentVertexShader, shadowState) + context->VSSetShader((ID3D11VertexShader*)currentVertexShader->shader, NULL, NULL); context->CopyResource(terrainDepthTexture->resource.get(), mainDepth.texture); } @@ -289,14 +288,16 @@ void TerrainBlending::BlendPrepassDepths() context->CSSetShader(shader, nullptr, 0); auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - state->GetRuntimeData().stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); + GET_INSTANCE_MEMBER(stateUpdateFlags, state) + stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); } void TerrainBlending::ResetTerrainWorld() { auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - state->GetRuntimeData().stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_ALPHA_BLEND); - state->GetRuntimeData().stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_DEPTH_MODE); + GET_INSTANCE_MEMBER(stateUpdateFlags, state) + stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_ALPHA_BLEND); + stateUpdateFlags.set(RE::BSGraphics::ShaderFlags::DIRTY_DEPTH_MODE); } void TerrainBlending::ClearShaderCache() diff --git a/src/Features/TerrainBlending.h b/src/Features/TerrainBlending.h index d6f73237f..a6408b14b 100644 --- a/src/Features/TerrainBlending.h +++ b/src/Features/TerrainBlending.h @@ -181,7 +181,7 @@ struct TerrainBlending : Feature static void Install() { // To know when we are rendering z-prepass depth vs shadows depth - stl::write_thunk_call(REL::Relocation(REL::RelocationID(35560, 36559), 0x395).address()); + stl::write_thunk_call(REL::RelocationID(35560, 36559).address() + REL::Relocate(0x395, 0x395, 0x2EE)); // To manipulate the depth buffer write, depth testing, alpha blending stl::write_thunk_call(REL::RelocationID(100852, 107642).address() + REL::Relocate(0x29E, 0x28F)); diff --git a/src/Hooks.cpp b/src/Hooks.cpp index e4a3bee5c..b135538db 100644 --- a/src/Hooks.cpp +++ b/src/Hooks.cpp @@ -5,6 +5,7 @@ #include "Menu.h" #include "ShaderCache.h" #include "State.h" +#include "Util.h" #include "ShaderTools/BSShaderHooks.h" @@ -395,7 +396,8 @@ namespace Hooks if (vertexShader) { state->context->VSSetShader(reinterpret_cast(vertexShader->shader), NULL, NULL); auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); - shadowState->GetRuntimeData().currentVertexShader = a_vertexShader; + GET_INSTANCE_MEMBER(currentVertexShader, shadowState) + currentVertexShader = a_vertexShader; return; } } @@ -421,12 +423,14 @@ namespace Hooks if (pixelShader) { state->context->PSSetShader(reinterpret_cast(pixelShader->shader), NULL, NULL); auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); - shadowState->GetRuntimeData().currentPixelShader = a_pixelShader; + GET_INSTANCE_MEMBER(currentPixelShader, shadowState) + currentPixelShader = a_pixelShader; return; } } else { auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); - shadowState->GetRuntimeData().currentPixelShader = a_pixelShader; + GET_INSTANCE_MEMBER(currentPixelShader, shadowState) + currentPixelShader = a_pixelShader; return; } } @@ -462,8 +466,8 @@ namespace Hooks logger::info("Hooking BSShader::BeginTechnique"); *(uintptr_t*)&ptr_BSShader_BeginTechnique = Detours::X64::DetourFunction(REL::RelocationID(101341, 108328).address(), (uintptr_t)&hk_BSShader_BeginTechnique); - stl::write_thunk_call(REL::RelocationID(101341, 101341).address() + REL::Relocate(0xC3, 0x3F3, 0x548)); - stl::write_thunk_call(REL::RelocationID(101341, 101341).address() + REL::Relocate(0xD7, 0x3F3, 0x548)); + stl::write_thunk_call(REL::RelocationID(101341, 101341).address() + REL::Relocate(0xC3, 0x3F3)); + stl::write_thunk_call(REL::RelocationID(101341, 101341).address() + REL::Relocate(0xD7, 0x3F3)); logger::info("Hooking BSGraphics::SetDirtyStates"); *(uintptr_t*)&ptr_BSGraphics_SetDirtyStates = Detours::X64::DetourFunction(REL::RelocationID(75580, 77386).address(), (uintptr_t)&hk_BSGraphics_SetDirtyStates); @@ -489,6 +493,6 @@ namespace Hooks stl::write_thunk_call(REL::RelocationID(100458, 107175).address() + REL::Relocate(0x406, 0x409)); stl::write_thunk_call(REL::RelocationID(100458, 107175).address() + REL::Relocate(0x555, 0x554, 0x6b9)); - stl::write_thunk_call(REL::RelocationID(100458, 107175).address() + REL::Relocate(0x1245, 0x554, 0x6b9)); + stl::write_thunk_call(REL::RelocationID(100458, 107175).address() + REL::Relocate(0x1245, 0x554, 0x1917)); } } \ No newline at end of file diff --git a/src/XSEPlugin.cpp b/src/XSEPlugin.cpp index bc09fc393..35d890bc4 100644 --- a/src/XSEPlugin.cpp +++ b/src/XSEPlugin.cpp @@ -148,6 +148,10 @@ bool Load() return true; } + if (REL::Module::IsVR()) { + REL::IDDatabase::get().IsVRAddressLibraryAtLeastVersion("0.138.0", true); + } + auto messaging = SKSE::GetMessagingInterface(); messaging->RegisterListener("SKSE", MessageHandler); From 20ea02cccc7a09ddc0031c13a12511e0ee16c117 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sat, 6 Jul 2024 02:34:32 -0700 Subject: [PATCH 02/20] fix: prevent extra init of State --- src/State.cpp | 4 ++++ src/State.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/State.cpp b/src/State.cpp index f5d7828f4..8da8f92f3 100644 --- a/src/State.cpp +++ b/src/State.cpp @@ -72,16 +72,20 @@ void State::Reset() lastModifiedVertexDescriptor = 0; lastPixelDescriptor = 0; lastVertexDescriptor = 0; + initialized = false; } void State::Setup() { + if (initialized) + return; SetupResources(); for (auto* feature : Feature::GetFeatureList()) if (feature->loaded) feature->SetupResources(); Deferred::GetSingleton()->SetupResources(); VariableRateShading::GetSingleton()->Setup(); + initialized = true; } static const std::string& GetConfigPath(State::ConfigMode a_configMode) diff --git a/src/State.h b/src/State.h index 8437e2cf5..a3a820f5c 100644 --- a/src/State.h +++ b/src/State.h @@ -141,4 +141,5 @@ class State private: std::shared_ptr pPerf; + bool initialized = false; }; From 5cfc61fe02e1e4378410115afe2cac0e6ebbde18 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sat, 6 Jul 2024 02:35:13 -0700 Subject: [PATCH 03/20] fix: fix enumeration of renderTargets Total will change based on Skyrim version. --- src/VariableRateShading.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VariableRateShading.cpp b/src/VariableRateShading.cpp index d682880b2..4fd83f992 100644 --- a/src/VariableRateShading.cpp +++ b/src/VariableRateShading.cpp @@ -218,7 +218,7 @@ void VariableRateShading::Setup() } { - for (uint i = 0; i < 114; i++) { + for (uint i = 0; i < static_cast(REL::Relocate(RE::RENDER_TARGET::kTOTAL, RE::RENDER_TARGET::k116, RE::RENDER_TARGET::kVRTOTAL)); i++) { auto& target = renderer->GetRuntimeData().renderTargets[i]; if (target.texture) { D3D11_TEXTURE2D_DESC texDesc{}; From 9986bd9304932f8a8378a64929cea3daad895321 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sat, 6 Jul 2024 02:36:14 -0700 Subject: [PATCH 04/20] chore: add more info in vrs logs --- src/VariableRateShading.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VariableRateShading.cpp b/src/VariableRateShading.cpp index 4fd83f992..355555824 100644 --- a/src/VariableRateShading.cpp +++ b/src/VariableRateShading.cpp @@ -239,7 +239,7 @@ void VariableRateShading::SetupSingleEyeVRS(int eye, int width, int height) int vrsWidth = width / NV_VARIABLE_PIXEL_SHADING_TILE_WIDTH; int vrsHeight = height / NV_VARIABLE_PIXEL_SHADING_TILE_HEIGHT; - logger::info("Creating VRS pattern texture for eye"); + logger::info("Creating VRS pattern texture for eye {} at {} x {}", eye, width, height); D3D11_TEXTURE2D_DESC texDesc = {}; texDesc.Width = vrsWidth; @@ -266,7 +266,7 @@ void VariableRateShading::SetupSingleEyeVRS(int eye, int width, int height) uavDesc.Texture2D.MipSlice = 0; DX::ThrowIfFailed(device->CreateUnorderedAccessView(singleEyeVRSTex[eye], &uavDesc, &singleEyeVRSUAV[eye])); - logger::info("Creating shading rate resource view for eye"); + logger::info("Creating shading rate resource view for eye {}", eye); NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC vd = {}; vd.version = NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC_VER; vd.Format = texDesc.Format; @@ -274,7 +274,7 @@ void VariableRateShading::SetupSingleEyeVRS(int eye, int width, int height) vd.Texture2D.MipSlice = 0; NvAPI_Status status = NvAPI_D3D11_CreateShadingRateResourceView(device, singleEyeVRSTex[eye], &vd, &singleEyeVRSView[eye]); if (status != NVAPI_OK) { - logger::info("Failed to create VRS pattern view for eye"); + logger::info("Failed to create VRS pattern view for eye {}", eye); return; } } From 893e8b6aab4d3cdafae107000e51f20104afc985 Mon Sep 17 00:00:00 2001 From: FlayaN Date: Sat, 6 Jul 2024 12:36:13 +0200 Subject: [PATCH 05/20] fix: add SKYLIGHTING defintion check around GetSkylightOcclusion --- package/Shaders/Lighting.hlsl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index 67e1ff2a2..336537e48 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -1503,9 +1503,11 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace float maxOcclusion = 1; float minWetnessAngle = 0; minWetnessAngle = saturate(max(minWetnessValue, worldSpaceNormal.z)); - +# if defined(SKYLIGHTING) float skylight = GetSkylightOcclusion(input.WorldPosition + worldSpaceNormal, screenNoise); - +# else + float skylight = 1.0; +# endif // SKYLIGHTING bool raindropOccluded = false; float4 raindropInfo = float4(0, 0, 1, 0); From 36811dd59a611406de01fac064123420efc93dd3 Mon Sep 17 00:00:00 2001 From: FlayaN Date: Sat, 6 Jul 2024 12:36:34 +0200 Subject: [PATCH 06/20] fix: bump vr-address-library requirement to 0.140.0 --- src/XSEPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XSEPlugin.cpp b/src/XSEPlugin.cpp index 35d890bc4..86e259893 100644 --- a/src/XSEPlugin.cpp +++ b/src/XSEPlugin.cpp @@ -149,7 +149,7 @@ bool Load() } if (REL::Module::IsVR()) { - REL::IDDatabase::get().IsVRAddressLibraryAtLeastVersion("0.138.0", true); + REL::IDDatabase::get().IsVRAddressLibraryAtLeastVersion("0.140.0", true); } auto messaging = SKSE::GetMessagingInterface(); From b489ea7a79959544d18534eb8cc0084eb129dd4b Mon Sep 17 00:00:00 2001 From: FlayaN Date: Sat, 6 Jul 2024 16:13:49 +0200 Subject: [PATCH 07/20] fix: fix debug view in deferred VR --- package/Shaders/DeferredCompositeCS.hlsl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/package/Shaders/DeferredCompositeCS.hlsl b/package/Shaders/DeferredCompositeCS.hlsl index 9db41eba7..d824c6dc8 100644 --- a/package/Shaders/DeferredCompositeCS.hlsl +++ b/package/Shaders/DeferredCompositeCS.hlsl @@ -100,14 +100,17 @@ Texture2D SkylightingTexture : register(t9); #if defined(DEBUG) - half2 texCoord = half2(dispatchID.xy) / BufferDim.xy; +# if defined(VR) + uv = ConvertFromStereoUV(uv, eyeIndex); + uv.x += (eyeIndex ? 0.1 : -0.1); +# endif // VR - if (texCoord.x < 0.5 && texCoord.y < 0.5) { + if (uv.x < 0.5 && uv.y < 0.5) { color = color; - } else if (texCoord.x < 0.5) { + } else if (uv.x < 0.5) { color = albedo; - } else if (texCoord.y < 0.5) { - color = normalWS; + } else if (uv.y < 0.5) { + color = normalVS; } else { color = glossiness; } From feaa383ca9dc78ba32015bba2b80c4731391fe48 Mon Sep 17 00:00:00 2001 From: FlayaN Date: Sat, 6 Jul 2024 19:03:24 +0200 Subject: [PATCH 08/20] fix: deferred rendering ambient issue --- src/State.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/State.cpp b/src/State.cpp index 8da8f92f3..c698c722e 100644 --- a/src/State.cpp +++ b/src/State.cpp @@ -77,13 +77,13 @@ void State::Reset() void State::Setup() { - if (initialized) - return; SetupResources(); for (auto* feature : Feature::GetFeatureList()) if (feature->loaded) feature->SetupResources(); Deferred::GetSingleton()->SetupResources(); + if (initialized) + return; VariableRateShading::GetSingleton()->Setup(); initialized = true; } From 95fed48b3f60ed56525eb7c27e88858971e484e1 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sat, 6 Jul 2024 16:11:03 -0700 Subject: [PATCH 09/20] feat(VR): enable skylighting --- .../Shaders/Skylighting/SkylightingCS.hlsl | 10 ++++----- package/Shaders/Common/ShadowSampling.hlsli | 21 ++++++++++--------- .../Shaders/ShadowTest/CopyShadowData.hlsl | 15 ++++++------- package/Shaders/Water.hlsl | 4 ++-- src/Deferred.h | 5 +++-- src/Features/Skylighting.h | 2 +- 6 files changed, 29 insertions(+), 28 deletions(-) diff --git a/features/Skylighting/Shaders/Skylighting/SkylightingCS.hlsl b/features/Skylighting/Shaders/Skylighting/SkylightingCS.hlsl index ca90c636a..053248ebc 100644 --- a/features/Skylighting/Shaders/Skylighting/SkylightingCS.hlsl +++ b/features/Skylighting/Shaders/Skylighting/SkylightingCS.hlsl @@ -17,13 +17,9 @@ struct PerGeometry float4 AlphaTestRef; float4 ShadowLightParam; // Falloff in x, ShadowDistance squared in z float4x3 FocusShadowMapProj[4]; -#if !defined(VR) - float4x3 ShadowMapProj[1][3]; - float4x4 CameraViewProjInverse2[1]; -#else + // Since PerGeometry is passed between c++ and hlsl, can't have different defines due to strong typing float4x3 ShadowMapProj[2][3]; - float4x4 CameraViewProjInverse2[2]; -#endif // VR + float4x4 CameraViewProjInverse[2]; }; Texture2DArray TexShadowMapSampler : register(t1); @@ -61,6 +57,7 @@ half GetScreenDepth(half depth) : SV_DispatchThreadID) { float2 uv = float2(globalId.xy + 0.5) * BufferDim.zw * DynamicResolutionParams2.xy; uint eyeIndex = GetEyeIndexFromTexCoord(uv); + uv = ConvertFromStereoUV(uv, eyeIndex); half3 normalGlossiness = NormalRoughnessTexture[globalId.xy]; half3 normalVS = DecodeNormal(normalGlossiness.xy); @@ -165,6 +162,7 @@ half GetScreenDepth(half depth) : SV_DispatchThreadID) { float2 uv = float2(globalId.xy + 0.5) * BufferDim.zw * DynamicResolutionParams2.xy; uint eyeIndex = GetEyeIndexFromTexCoord(uv); + uv = ConvertFromStereoUV(uv, eyeIndex); half3 normalGlossiness = NormalRoughnessTexture[globalId.xy]; half3 normalVS = DecodeNormal(normalGlossiness.xy); diff --git a/package/Shaders/Common/ShadowSampling.hlsli b/package/Shaders/Common/ShadowSampling.hlsli index e588ab3f2..61803d7ce 100644 --- a/package/Shaders/Common/ShadowSampling.hlsli +++ b/package/Shaders/Common/ShadowSampling.hlsli @@ -14,8 +14,9 @@ struct PerGeometry float4 AlphaTestRef; float4 ShadowLightParam; // Falloff in x, ShadowDistance squared in z float4x3 FocusShadowMapProj[4]; - float4x3 ShadowMapProj[4]; - float4x4 CameraViewProjInverse; + // Since PerGeometry is passed between c++ and hlsl, can't have different defines due to strong typing + float4x3 ShadowMapProj[2][3]; + float4x4 CameraViewProjInverse[2]; }; Texture2DArray TexShadowMapSampler : register(t25); @@ -31,7 +32,7 @@ cbuffer PerWaterType : register(b7) uint pad1water; }; -float3 GetShadow(float3 positionWS) +float3 GetShadow(float3 positionWS, uint a_eyeIndex = 0) { PerGeometry sD = perShadow[0]; sD.EndSplitDistances.x = GetScreenDepth(sD.EndSplitDistances.x); @@ -42,18 +43,18 @@ float3 GetShadow(float3 positionWS) float shadowMapDepth = length(positionWS.xyz); half cascadeIndex = 0; - half4x3 lightProjectionMatrix = sD.ShadowMapProj[0]; + half4x3 lightProjectionMatrix = sD.ShadowMapProj[a_eyeIndex][0]; half shadowMapThreshold = sD.AlphaTestRef.y; [flatten] if (2.5 < sD.EndSplitDistances.w && sD.EndSplitDistances.y < shadowMapDepth) { - lightProjectionMatrix = sD.ShadowMapProj[2]; + lightProjectionMatrix = sD.ShadowMapProj[a_eyeIndex][2]; shadowMapThreshold = sD.AlphaTestRef.z; cascadeIndex = 2; } else if (sD.EndSplitDistances.x < shadowMapDepth) { - lightProjectionMatrix = sD.ShadowMapProj[1]; + lightProjectionMatrix = sD.ShadowMapProj[a_eyeIndex][1]; shadowMapThreshold = sD.AlphaTestRef.z; cascadeIndex = 1; } @@ -74,7 +75,7 @@ float3 GetShadow(float3 positionWS) return shadow; } -float GetVL(float3 startPosWS, float3 endPosWS, float2 screenPosition) +float GetVL(float3 startPosWS, float3 endPosWS, float2 screenPosition, uint a_eyeIndex = 0) { const static uint nSteps = 16; const static float step = 1.0 / float(nSteps); @@ -125,21 +126,21 @@ float GetVL(float3 startPosWS, float3 endPosWS, float2 screenPosition) float shadowMapDepth = length(samplePositionWS.xyz); half cascadeIndex = 0; - half4x3 lightProjectionMatrix = sD.ShadowMapProj[0]; + half4x3 lightProjectionMatrix = sD.ShadowMapProj[a_eyeIndex][0]; half shadowMapThreshold = sD.AlphaTestRef.y; half shadowRange = sD.EndSplitDistances.x; [flatten] if (2.5 < sD.EndSplitDistances.w && sD.EndSplitDistances.y < shadowMapDepth) { - lightProjectionMatrix = sD.ShadowMapProj[2]; + lightProjectionMatrix = sD.ShadowMapProj[a_eyeIndex][2]; shadowMapThreshold = sD.AlphaTestRef.z; cascadeIndex = 2; shadowRange = sD.EndSplitDistances.z - sD.EndSplitDistances.y; } else if (sD.EndSplitDistances.x < shadowMapDepth) { - lightProjectionMatrix = sD.ShadowMapProj[1]; + lightProjectionMatrix = sD.ShadowMapProj[a_eyeIndex][1]; shadowMapThreshold = sD.AlphaTestRef.z; cascadeIndex = 1; shadowRange = sD.EndSplitDistances.y - sD.EndSplitDistances.x; diff --git a/package/Shaders/ShadowTest/CopyShadowData.hlsl b/package/Shaders/ShadowTest/CopyShadowData.hlsl index 69073a7d1..e7aa91af0 100644 --- a/package/Shaders/ShadowTest/CopyShadowData.hlsl +++ b/package/Shaders/ShadowTest/CopyShadowData.hlsl @@ -11,13 +11,9 @@ struct PerGeometry float4 AlphaTestRef; float4 ShadowLightParam; // Falloff in x, ShadowDistance squared in z float4x3 FocusShadowMapProj[4]; -#if !defined(VR) - float4x3 ShadowMapProj[1][3]; - float4x4 CameraViewProjInverse[1]; -#else + // Since PerGeometry is passed between c++ and hlsl, can't have different defines due to strong typing float4x3 ShadowMapProj[2][3]; float4x4 CameraViewProjInverse[2]; -#endif // VR }; cbuffer PerFrame : register(b0) @@ -101,9 +97,14 @@ RWStructuredBuffer copiedData : register(u0); perGeometry.AlphaTestRef = AlphaTestRef; perGeometry.ShadowLightParam = ShadowLightParam; perGeometry.FocusShadowMapProj = FocusShadowMapProj; - perGeometry.ShadowMapProj = ShadowMapProj; + perGeometry.ShadowMapProj[0] = ShadowMapProj[0]; + + perGeometry.CameraViewProjInverse[0] = CameraViewProjInverse[0]; +#if defined(VR) + perGeometry.ShadowMapProj[1] = ShadowMapProj[1]; - perGeometry.CameraViewProjInverse = CameraViewProjInverse; + perGeometry.CameraViewProjInverse[1] = CameraViewProjInverse[1]; +#endif perGeometry.VPOSOffset = VPOSOffset; perGeometry.ShadowSampleParam = ShadowSampleParam; diff --git a/package/Shaders/Water.hlsl b/package/Shaders/Water.hlsl index 502ee6661..73989c9a7 100644 --- a/package/Shaders/Water.hlsl +++ b/package/Shaders/Water.hlsl @@ -611,7 +611,7 @@ float3 GetWaterDiffuseColor(PS_INPUT input, float3 normal, float3 viewDirection, float3 refractionDiffuseColor = lerp(ShallowColor.xyz, DeepColor.xyz, distanceMul.y); if (!(PixelShaderDescriptor & _Interior)) { - float vl = GetVL(input.WPosition.xyz, refractionWorldPosition.xyz, screenPosition) * (dot(viewDirection, SunDir.xyz) * 0.5 + 0.5); + float vl = GetVL(input.WPosition.xyz, refractionWorldPosition.xyz, screenPosition) * (dot(viewDirection, SunDir.xyz) * 0.5 + 0.5, a_eyeIndex); float3 refractionDiffuseColorSunlight = refractionDiffuseColor * vl * SunColor.xyz * SunDir.w; # if defined(SKYLIGHTING) @@ -781,7 +781,7 @@ PS_OUTPUT main(PS_INPUT input) float3 sunColor = GetSunColor(normal, viewDirection); if (!(PixelShaderDescriptor & _Interior)) - sunColor *= GetShadow(input.WPosition + normal * 32); + sunColor *= GetShadow(input.WPosition + normal * 32, eyeIndex); float specularFraction = lerp(1, fresnel * depthControl.x, distanceFactor); float3 finalColorPreFog = lerp(diffuseColor, specularColor, specularFraction) + sunColor * depthControl.w; diff --git a/src/Deferred.h b/src/Deferred.h index f9018b2db..bd1dd04ec 100644 --- a/src/Deferred.h +++ b/src/Deferred.h @@ -79,8 +79,9 @@ class Deferred float4 AlphaTestRef; float4 ShadowLightParam; // Falloff in x, ShadowDistance squared in z DirectX::XMFLOAT4X3 FocusShadowMapProj[4]; - DirectX::XMFLOAT4X3 ShadowMapProj[4]; - DirectX::XMFLOAT4X4 CameraViewProjInverse; + // Since PerGeometry is passed between c++ and hlsl, can't have different defines due to strong typing + DirectX::XMFLOAT4X3 ShadowMapProj[2][3]; + DirectX::XMFLOAT4X3 CameraViewProjInverse[2]; }; ID3D11ComputeShader* copyShadowCS = nullptr; diff --git a/src/Features/Skylighting.h b/src/Features/Skylighting.h index 64340d601..62d71c0ba 100644 --- a/src/Features/Skylighting.h +++ b/src/Features/Skylighting.h @@ -457,5 +457,5 @@ struct Skylighting : Feature } }; - bool SupportsVR() override { return false; }; + bool SupportsVR() override { return true; }; }; From 0530fb8146d1d0e36db1ef98a47fd8b925d863d1 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sat, 6 Jul 2024 16:59:46 -0700 Subject: [PATCH 10/20] fix: fix sky compilation error in VR --- package/Shaders/Sky.hlsl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/Shaders/Sky.hlsl b/package/Shaders/Sky.hlsl index 79ad2c75c..59e637398 100644 --- a/package/Shaders/Sky.hlsl +++ b/package/Shaders/Sky.hlsl @@ -142,10 +142,12 @@ cbuffer PerGeometry : register(b2) float2 PParams : packoffset(c0); }; +# if !defined(VR) cbuffer AlphaTestRefCB : register(b11) { float AlphaTestRefRS : packoffset(c0); } +# endif # include "Common/FrameBuffer.hlsl" # include "Common/MotionBlur.hlsl" From 9ada13e685e32475c2e50e655d9e0dd34d2df1c2 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 7 Jul 2024 00:45:08 -0700 Subject: [PATCH 11/20] fix: fix water rendering --- package/Shaders/Common/ShadowSampling.hlsli | 2 +- .../Shaders/ShadowTest/CopyShadowData.hlsl | 24 +++++++++++++------ package/Shaders/Water.hlsl | 18 +++++++++++--- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/package/Shaders/Common/ShadowSampling.hlsli b/package/Shaders/Common/ShadowSampling.hlsli index 61803d7ce..7df614507 100644 --- a/package/Shaders/Common/ShadowSampling.hlsli +++ b/package/Shaders/Common/ShadowSampling.hlsli @@ -159,7 +159,7 @@ float GetVL(float3 startPosWS, float3 endPosWS, float2 screenPosition, uint a_ey if (shadow > 0.0) { float terrainShadow = 1; float terrainAo = 1; - GetTerrainOcclusion(samplePositionWS + CameraPosAdjust[0], length(samplePositionWS), LinearSampler, terrainShadow, terrainAo); + GetTerrainOcclusion(samplePositionWS + CameraPosAdjust[a_eyeIndex], length(samplePositionWS), LinearSampler, terrainShadow, terrainAo); shadow *= terrainShadow; } # endif diff --git a/package/Shaders/ShadowTest/CopyShadowData.hlsl b/package/Shaders/ShadowTest/CopyShadowData.hlsl index e7aa91af0..57ee7dc87 100644 --- a/package/Shaders/ShadowTest/CopyShadowData.hlsl +++ b/package/Shaders/ShadowTest/CopyShadowData.hlsl @@ -16,17 +16,27 @@ struct PerGeometry float4x4 CameraViewProjInverse[2]; }; +// copied from UtilShader(b2). Assume RENDER_SHADOWMASK cbuffer PerFrame : register(b0) { - float4 DebugColor; - float4 PropertyColor; - float4 AlphaTestRef; - float4 ShadowLightParam; // Falloff in x, ShadowDistance squared in z - float4x3 FocusShadowMapProj[4]; + float4 DebugColor : packoffset(c0); + float4 PropertyColor : packoffset(c1); + float4 AlphaTestRef : packoffset(c2); + float4 ShadowLightParam : packoffset(c3); // Falloff in x, ShadowDistance squared in z #if !defined(VR) - float4x3 ShadowMapProj[1][3]; + float4x3 FocusShadowMapProj[4] : packoffset(c4); + float4x3 ShadowMapProj[1][3] : packoffset(c16); // 16, 19, 22 #else - float4x3 ShadowMapProj[2][3]; + float4 VRUnknown : packoffset(c4); // used to multiply by identity matrix, see e.g., 4202499.ps.bin.hlsl + /* + r1.x = dot(cb2[4].xz, icb[r0.w+0].xz); + r1.x = r0.x * cb12[86].x + -r1.x; + r0.w = (int)r0.w + 1; + r0.w = (int)r0.w + -1; + r0.w = dot(cb2[4].yw, icb[r0.w+0].xz); + */ + float4x3 FocusShadowMapProj[4] : packoffset(c5); + float4x3 ShadowMapProj[2][3] : packoffset(c29); // VR has a couple of offsets of 3, e.g., {29, 32, 35} and {38, 41, 44}, compare to Flat which does [16, 19, 22] #endif // VR } diff --git a/package/Shaders/Water.hlsl b/package/Shaders/Water.hlsl index 73989c9a7..bddbd9c5e 100644 --- a/package/Shaders/Water.hlsl +++ b/package/Shaders/Water.hlsl @@ -583,13 +583,25 @@ float3 GetWaterDiffuseColor(PS_INPUT input, float3 normal, float3 viewDirection, refractionUvRaw = ConvertToStereoUV(refractionUvRaw, a_eyeIndex); // need to convert here for VR due to refractionNormal values float2 screenPosition = DynamicResolutionParams1.xy * (DynamicResolutionParams2.xy * input.HPosition.xy); - float depth = GetScreenDepthWater(screenPosition); + float depth = GetScreenDepthWater(screenPosition, +# if defined(VR) + 1 +# else + 0 +# endif + ); float2 refractionScreenPosition = DynamicResolutionParams1.xy * (refractionUvRaw / VPOSOffset.xy); float4 refractionWorldPosition = float4(input.WPosition.xyz * depth / viewPosition.z, 0); # if defined(DEPTH) && !defined(VERTEX_ALPHA_DEPTH) - float refractionDepth = GetScreenDepthWater(refractionScreenPosition); + float refractionDepth = GetScreenDepthWater(refractionScreenPosition, +# if defined(VR) + 1 +# else + 0 +# endif + ); float refractionDepthMul = length(float3((((VPOSOffset.zw + refractionUvRaw) * 2 - 1)) * refractionDepth / ProjData.xy, refractionDepth)); float3 refractionDepthAdjustedViewDirection = -viewDirection * refractionDepthMul; @@ -611,7 +623,7 @@ float3 GetWaterDiffuseColor(PS_INPUT input, float3 normal, float3 viewDirection, float3 refractionDiffuseColor = lerp(ShallowColor.xyz, DeepColor.xyz, distanceMul.y); if (!(PixelShaderDescriptor & _Interior)) { - float vl = GetVL(input.WPosition.xyz, refractionWorldPosition.xyz, screenPosition) * (dot(viewDirection, SunDir.xyz) * 0.5 + 0.5, a_eyeIndex); + float vl = GetVL(input.WPosition.xyz, refractionWorldPosition.xyz, screenPosition, a_eyeIndex) * (dot(viewDirection, SunDir.xyz) * 0.5 + 0.5); float3 refractionDiffuseColorSunlight = refractionDiffuseColor * vl * SunColor.xyz * SunDir.w; # if defined(SKYLIGHTING) From 58e3e554ca0b31c2c886829513697bfd409bb950 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 7 Jul 2024 03:00:20 -0700 Subject: [PATCH 12/20] fix(VR): fix screen space shadows Fix loading of ScreenSpaceShadowsTexture stereo buffer using a non stereo uv coordinate. --- .../Shaders/ScreenSpaceShadows/ScreenSpaceShadows.hlsli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/Screen-Space Shadows/Shaders/ScreenSpaceShadows/ScreenSpaceShadows.hlsli b/features/Screen-Space Shadows/Shaders/ScreenSpaceShadows/ScreenSpaceShadows.hlsli index 98ccd927f..b5c402357 100644 --- a/features/Screen-Space Shadows/Shaders/ScreenSpaceShadows/ScreenSpaceShadows.hlsli +++ b/features/Screen-Space Shadows/Shaders/ScreenSpaceShadows/ScreenSpaceShadows.hlsli @@ -37,7 +37,7 @@ float GetScreenSpaceShadow(float2 a_uv, float a_noise, float3 a_viewPosition, ui if (weight > 0.0) shadow /= weight; else - shadow = ScreenSpaceShadowsTexture.Load(int3(a_uv * BufferDim.xy, 0)).x; + shadow = ScreenSpaceShadowsTexture.Load(int3(GetDynamicResolutionAdjustedScreenPosition(ConvertToStereoUV(a_uv, a_eyeIndex)) * BufferDim.xy, 0)).x; return shadow; } \ No newline at end of file From 3b478a724113656328ba193fc13cda70bd953d89 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 7 Jul 2024 10:14:44 -0700 Subject: [PATCH 13/20] fix: fix bad uv conversion Typically dtid is in stereo so needs to be corrected to nonstereo. --- .../Screen Space GI/Shaders/ScreenSpaceGI/blur.cs.hlsl | 6 +++--- .../Screen Space GI/Shaders/ScreenSpaceGI/common.hlsli | 6 ------ features/Screen Space GI/Shaders/ScreenSpaceGI/gi.cs.hlsl | 8 ++++---- .../Shaders/ScreenSpaceGI/radianceDisocc.cs.hlsl | 8 ++++---- package/Shaders/DeferredCompositeCS.hlsl | 2 +- 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/features/Screen Space GI/Shaders/ScreenSpaceGI/blur.cs.hlsl b/features/Screen Space GI/Shaders/ScreenSpaceGI/blur.cs.hlsl index a4ab05fe5..9589288b8 100644 --- a/features/Screen Space GI/Shaders/ScreenSpaceGI/blur.cs.hlsl +++ b/features/Screen Space GI/Shaders/ScreenSpaceGI/blur.cs.hlsl @@ -45,8 +45,8 @@ float HistoryRadiusScaling(float accumFrames) const uint numSamples = 8; const float2 uv = (dtid + .5) * RcpOutFrameDim; - uint eyeIndex = GET_EYE_IDX(uv); - const float2 screenPos = ConvertToStereoUV(uv, eyeIndex); + uint eyeIndex = GetEyeIndexFromTexCoord(uv); + const float2 screenPos = ConvertFromStereoUV(uv, eyeIndex); float depth = READ_DEPTH(srcDepth, dtid); float3 pos = ScreenToViewPosition(screenPos, depth, eyeIndex); @@ -63,7 +63,7 @@ float HistoryRadiusScaling(float accumFrames) float2 pxOffset = radius * g_Poisson8[i].xy; float2 pxSample = dtid + .5 + pxOffset; float2 uvSample = pxSample * RcpOutFrameDim; - float2 screenPosSample = ConvertToStereoUV(uvSample, eyeIndex); + float2 screenPosSample = ConvertFromStereoUV(uvSample, eyeIndex); if (any(screenPosSample < 0) || any(screenPosSample > 1)) continue; diff --git a/features/Screen Space GI/Shaders/ScreenSpaceGI/common.hlsli b/features/Screen Space GI/Shaders/ScreenSpaceGI/common.hlsli index a833df7fe..b34bdf6e3 100644 --- a/features/Screen Space GI/Shaders/ScreenSpaceGI/common.hlsli +++ b/features/Screen Space GI/Shaders/ScreenSpaceGI/common.hlsli @@ -82,12 +82,6 @@ SamplerState samplerLinearClamp : register(s1); # define FULLRES_LOAD(tex, px, texCoord, samp) tex[px] #endif -#ifdef VR -# define GET_EYE_IDX(uv) (uv.x > 0.5) -#else -# define GET_EYE_IDX(uv) (0) -#endif - /////////////////////////////////////////////////////////////////////////////// #define ISNAN(x) (!(x < 0.f || x > 0.f || x == 0.f)) diff --git a/features/Screen Space GI/Shaders/ScreenSpaceGI/gi.cs.hlsl b/features/Screen Space GI/Shaders/ScreenSpaceGI/gi.cs.hlsl index 645b7434b..f24b8ac3e 100644 --- a/features/Screen Space GI/Shaders/ScreenSpaceGI/gi.cs.hlsl +++ b/features/Screen Space GI/Shaders/ScreenSpaceGI/gi.cs.hlsl @@ -83,8 +83,8 @@ void CalculateGI( const float2 srcScale = SrcFrameDim * RcpTexDim; const float2 outScale = OutFrameDim * RcpTexDim; - uint eyeIndex = GET_EYE_IDX(uv); - float2 normalizedScreenPos = ConvertToStereoUV(uv, eyeIndex); + uint eyeIndex = GetEyeIndexFromTexCoord(uv); + float2 normalizedScreenPos = ConvertFromStereoUV(uv, eyeIndex); const float rcpNumSlices = rcp(NumSlices); const float rcpNumSteps = rcp(NumSteps); @@ -171,7 +171,7 @@ void CalculateGI( float2 samplePxCoord = dtid + .5 + sampleOffset * sideSign; float2 sampleUV = samplePxCoord * RcpOutFrameDim; - float2 sampleScreenPos = ConvertToStereoUV(sampleUV, eyeIndex); + float2 sampleScreenPos = ConvertFromStereoUV(sampleUV, eyeIndex); [branch] if (any(sampleScreenPos > 1.0) || any(sampleScreenPos < 0.0)) break; float sampleOffsetLength = length(sampleOffset); @@ -358,7 +358,7 @@ void CalculateGI( const float2 outScale = OutFrameDim * RcpTexDim; float2 uv = (dtid + .5f) * RcpOutFrameDim; - uint eyeIndex = GET_EYE_IDX(uv); + uint eyeIndex = GetEyeIndexFromTexCoord(uv); float viewspaceZ = READ_DEPTH(srcWorkingDepth, dtid); diff --git a/features/Screen Space GI/Shaders/ScreenSpaceGI/radianceDisocc.cs.hlsl b/features/Screen Space GI/Shaders/ScreenSpaceGI/radianceDisocc.cs.hlsl index 2be912044..213fadce4 100644 --- a/features/Screen Space GI/Shaders/ScreenSpaceGI/radianceDisocc.cs.hlsl +++ b/features/Screen Space GI/Shaders/ScreenSpaceGI/radianceDisocc.cs.hlsl @@ -27,7 +27,7 @@ void readHistory( const float2 srcScale = SrcFrameDim * RcpTexDim; const float2 uv = (pixCoord + .5) * RcpOutFrameDim; - const float2 screen_pos = ConvertToStereoUV(uv, eyeIndex); + const float2 screen_pos = ConvertFromStereoUV(uv, eyeIndex); if (any(screen_pos < 0) || any(screen_pos > 1)) return; @@ -62,14 +62,14 @@ void readHistory( const float2 outScale = OutFrameDim * RcpTexDim; const float2 uv = (pixCoord + .5) * RcpOutFrameDim; - uint eyeIndex = GET_EYE_IDX(uv); - const float2 screen_pos = ConvertToStereoUV(uv, eyeIndex); + uint eyeIndex = GetEyeIndexFromTexCoord(uv); + const float2 screen_pos = ConvertFromStereoUV(uv, eyeIndex); float2 prev_uv = uv; #ifdef REPROJECTION prev_uv += FULLRES_LOAD(srcMotionVec, pixCoord, uv * srcScale, samplerLinearClamp).xy; #endif - float2 prev_screen_pos = ConvertToStereoUV(prev_uv, eyeIndex); + float2 prev_screen_pos = ConvertFromStereoUV(prev_uv, eyeIndex); half4 prev_gi_albedo = 0; half4 prev_gi = 0; diff --git a/package/Shaders/DeferredCompositeCS.hlsl b/package/Shaders/DeferredCompositeCS.hlsl index d824c6dc8..1cac186d1 100644 --- a/package/Shaders/DeferredCompositeCS.hlsl +++ b/package/Shaders/DeferredCompositeCS.hlsl @@ -32,6 +32,7 @@ Texture2D SkylightingTexture : register(t9); : SV_DispatchThreadID) { half2 uv = half2(dispatchID.xy + 0.5) * BufferDim.zw; uint eyeIndex = GetEyeIndexFromTexCoord(uv); + uv = ConvertFromStereoUV(uv, eyeIndex); half3 normalGlossiness = NormalRoughnessTexture[dispatchID.xy]; half3 normalVS = DecodeNormal(normalGlossiness.xy); @@ -101,7 +102,6 @@ Texture2D SkylightingTexture : register(t9); #if defined(DEBUG) # if defined(VR) - uv = ConvertFromStereoUV(uv, eyeIndex); uv.x += (eyeIndex ? 0.1 : -0.1); # endif // VR From 35c41928655805a5b2d7e86296453de79e219506 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 7 Jul 2024 15:17:06 -0700 Subject: [PATCH 14/20] feat(VR): enable sky and cloud shadows --- package/Shaders/Sky.hlsl | 62 +++++++++++++++++++++++++++++-------- src/Features/CloudShadows.h | 1 + src/ShaderCache.h | 3 +- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/package/Shaders/Sky.hlsl b/package/Shaders/Sky.hlsl index 59e637398..1cd314463 100644 --- a/package/Shaders/Sky.hlsl +++ b/package/Shaders/Sky.hlsl @@ -1,4 +1,6 @@ - +#include "Common/Constants.hlsli" +#include "Common/FrameBuffer.hlsl" +#include "Common/VR.hlsli" struct VS_INPUT { @@ -9,6 +11,9 @@ struct VS_INPUT #endif float4 Color : COLOR0; +#if defined(VR) + uint InstanceID : SV_INSTANCEID; +#endif // VR }; struct VS_OUTPUT @@ -37,23 +42,43 @@ struct VS_OUTPUT float4 WorldPosition : POSITION1; float4 PreviousWorldPosition : POSITION2; +#if defined(VR) + float ClipDistance : SV_ClipDistance0; // o11 + float CullDistance : SV_CullDistance0; // p11 + uint EyeIndex : EYEIDX0; +#endif // VR }; #ifdef VSHADER cbuffer PerGeometry : register(b2) { - row_major float4x4 WorldViewProj : packoffset(c0); - row_major float4x4 World : packoffset(c4); - row_major float4x4 PreviousWorld : packoffset(c8); - float3 EyePosition : packoffset(c12); +# if !defined(VR) + row_major float4x4 WorldViewProj[1] : packoffset(c0); + row_major float4x4 World[1] : packoffset(c4); + row_major float4x4 PreviousWorld[1] : packoffset(c8); + float3 EyePosition[1] : packoffset(c12); float VParams : packoffset(c12.w); float4 BlendColor[3] : packoffset(c13); float2 TexCoordOff : packoffset(c16); +# else + row_major float4x4 WorldViewProj[2] : packoffset(c0); + row_major float4x4 World[2] : packoffset(c8); + row_major float4x4 PreviousWorld[2] : packoffset(c16); + float3 EyePosition[2] : packoffset(c24); + float VParams : packoffset(c25.w); + float4 BlendColor[3] : packoffset(c26); + float2 TexCoordOff : packoffset(c29); +# endif // !VR }; VS_OUTPUT main(VS_INPUT input) { VS_OUTPUT vsout; + uint eyeIndex = GetEyeIndexVS( +# if defined(VR) + input.InstanceID +# endif + ); float4 inputPosition = float4(input.Position.xyz, 1.0); @@ -68,8 +93,8 @@ VS_OUTPUT main(VS_INPUT input) # elif defined(HORIZFADE) - float worldHeight = mul(World, inputPosition).z; - float eyeHeightDelta = -EyePosition.z + worldHeight; + float worldHeight = mul(World[eyeIndex], inputPosition).z; + float eyeHeightDelta = -EyePosition[eyeIndex].z + worldHeight; vsout.TexCoord0.xy = input.TexCoord; vsout.TexCoord2.x = saturate((1.0 / 17.0) * eyeHeightDelta); @@ -108,10 +133,17 @@ VS_OUTPUT main(VS_INPUT input) # endif // OCCLUSION MOONMASK HORIZFADE - vsout.Position = mul(WorldViewProj, inputPosition).xyww; - vsout.WorldPosition = mul(World, inputPosition); - vsout.PreviousWorldPosition = mul(PreviousWorld, inputPosition); - + vsout.Position = mul(WorldViewProj[eyeIndex], inputPosition).xyww; + vsout.WorldPosition = mul(World[eyeIndex], inputPosition); + vsout.PreviousWorldPosition = mul(PreviousWorld[eyeIndex], inputPosition); + +# ifdef VR + vsout.EyeIndex = eyeIndex; + VR_OUTPUT VRout = GetVRVSOutput(vsout.Position, eyeIndex); + vsout.Position = VRout.VRPosition; + vsout.ClipDistance.x = VRout.ClipDistance; + vsout.CullDistance.x = VRout.CullDistance; +# endif // VR return vsout; } #endif @@ -149,7 +181,6 @@ cbuffer AlphaTestRefCB : register(b11) } # endif -# include "Common/FrameBuffer.hlsl" # include "Common/MotionBlur.hlsl" # include "Common/SharedData.hlsli" @@ -160,6 +191,11 @@ cbuffer AlphaTestRefCB : register(b11) PS_OUTPUT main(PS_INPUT input) { PS_OUTPUT psout; +# if !defined(VR) + uint eyeIndex = 0; +# else + uint eyeIndex = input.EyeIndex; +# endif // !VR # ifndef OCCLUSION # ifndef TEXLERP @@ -205,7 +241,7 @@ PS_OUTPUT main(PS_INPUT input) psout.Color = float4(0, 0, 0, 1.0); # endif // OCCLUSION - float2 screenMotionVector = GetSSMotionVector(input.WorldPosition, input.PreviousWorldPosition, 0); + float2 screenMotionVector = GetSSMotionVector(input.WorldPosition, input.PreviousWorldPosition, eyeIndex); psout.MotionVectors = float4(screenMotionVector, 0, psout.Color.w); psout.Normal = float4(0.5, 0.5, 0, psout.Color.w); diff --git a/src/Features/CloudShadows.h b/src/Features/CloudShadows.h index 3c7246d8c..cab672fe0 100644 --- a/src/Features/CloudShadows.h +++ b/src/Features/CloudShadows.h @@ -62,4 +62,5 @@ struct CloudShadows : Feature logger::info("[Cloud Shadows] Installed hooks"); } }; + bool SupportsVR() override { return true; }; }; diff --git a/src/ShaderCache.h b/src/ShaderCache.h index a5fd67e31..0573574d7 100644 --- a/src/ShaderCache.h +++ b/src/ShaderCache.h @@ -117,8 +117,9 @@ namespace SIE type == RE::BSShader::Type::Utility; return type == RE::BSShader::Type::Lighting || type == RE::BSShader::Type::DistantTree || - type == RE::BSShader::Type::Water || + type == RE::BSShader::Type::Sky || type == RE::BSShader::Type::Grass || + type == RE::BSShader::Type::Water || type == RE::BSShader::Type::Effect || type == RE::BSShader::Type::Utility; } From 8bbb95775bea38b106ffd4304a2bbd8aad7727b4 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 7 Jul 2024 15:53:28 -0700 Subject: [PATCH 15/20] feat(VR): enable Terrain Blending --- src/Features/TerrainBlending.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Features/TerrainBlending.h b/src/Features/TerrainBlending.h index a6408b14b..bb04e866d 100644 --- a/src/Features/TerrainBlending.h +++ b/src/Features/TerrainBlending.h @@ -192,4 +192,5 @@ struct TerrainBlending : Feature logger::info("[Terrain Blending] Installed hooks"); } }; + bool SupportsVR() override { return true; }; }; From 7646af1e9e1d4f878a68cbc2ad986bdf53d5f369 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 7 Jul 2024 16:01:19 -0700 Subject: [PATCH 16/20] fix: fix flat compilation error --- package/Shaders/ShadowTest/CopyShadowData.hlsl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package/Shaders/ShadowTest/CopyShadowData.hlsl b/package/Shaders/ShadowTest/CopyShadowData.hlsl index 57ee7dc87..35f2f0942 100644 --- a/package/Shaders/ShadowTest/CopyShadowData.hlsl +++ b/package/Shaders/ShadowTest/CopyShadowData.hlsl @@ -114,6 +114,10 @@ RWStructuredBuffer copiedData : register(u0); perGeometry.ShadowMapProj[1] = ShadowMapProj[1]; perGeometry.CameraViewProjInverse[1] = CameraViewProjInverse[1]; +#else + perGeometry.ShadowMapProj[1] = ShadowMapProj[0]; + + perGeometry.CameraViewProjInverse[1] = CameraViewProjInverse[0]; #endif perGeometry.VPOSOffset = VPOSOffset; From f97c47f73b620ad04522f8c84ac07eae8db5f190 Mon Sep 17 00:00:00 2001 From: FlayaN Date: Mon, 8 Jul 2024 01:10:41 +0200 Subject: [PATCH 17/20] refactor: create util for eyePos and cameraData --- src/Features/DynamicCubemaps.cpp | 5 +---- src/Features/GrassCollision.cpp | 12 ++---------- src/Features/LightLimitFix.cpp | 22 ++++++---------------- src/Features/ScreenSpaceGI.cpp | 3 +-- src/Features/ScreenSpaceShadows.cpp | 7 ++----- src/Features/SubsurfaceScattering.cpp | 4 +--- src/Util.h | 25 +++++++++++++++++++++++++ 7 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/Features/DynamicCubemaps.cpp b/src/Features/DynamicCubemaps.cpp index 39843a919..a3df80d16 100644 --- a/src/Features/DynamicCubemaps.cpp +++ b/src/Features/DynamicCubemaps.cpp @@ -246,10 +246,7 @@ void DynamicCubemaps::UpdateCubemapCapture() static float3 cameraPreviousPosAdjust = { 0, 0, 0 }; updateData.CameraPreviousPosAdjust = cameraPreviousPosAdjust; - auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); - auto eyePosition = !REL::Module::IsVR() ? - shadowState->GetRuntimeData().posAdjust.getEye(0) : - shadowState->GetVRRuntimeData().posAdjust.getEye(0); + auto eyePosition = Util::GetEyePosition(0); cameraPreviousPosAdjust = { eyePosition.x, eyePosition.y, eyePosition.z }; diff --git a/src/Features/GrassCollision.cpp b/src/Features/GrassCollision.cpp index 312c0ac04..3b99af1b5 100644 --- a/src/Features/GrassCollision.cpp +++ b/src/Features/GrassCollision.cpp @@ -104,7 +104,6 @@ static bool GetShapeBound(RE::bhkNiCollisionObject* Colliedobj, RE::NiPoint3& ce void GrassCollision::UpdateCollisions(PerFrame& perFrameData) { - auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); actorList.clear(); // Actor query code from po3 under MIT @@ -126,11 +125,7 @@ void GrassCollision::UpdateCollisions(PerFrame& perFrameData) if (auto player = RE::PlayerCharacter::GetSingleton()) actorList.push_back(player); - RE::NiPoint3 cameraPosition; - if (!REL::Module::IsVR()) - cameraPosition = shadowState->GetRuntimeData().posAdjust.getEye(); - else - cameraPosition = (shadowState->GetVRRuntimeData().posAdjust.getEye(0) + shadowState->GetVRRuntimeData().posAdjust.getEye(1)) * 0.5f; + RE::NiPoint3 cameraPosition = Util::GetAverageEyePosition(); for (const auto actor : actorList) { if (currentCollisionCount == 256) @@ -149,10 +144,7 @@ void GrassCollision::UpdateCollisions(PerFrame& perFrameData) CollisionData data{}; RE::NiPoint3 eyePosition{}; for (int eyeIndex = 0; eyeIndex < eyeCount; eyeIndex++) { - if (!REL::Module::IsVR()) - eyePosition = shadowState->GetRuntimeData().posAdjust.getEye(); - else - eyePosition = shadowState->GetVRRuntimeData().posAdjust.getEye(eyeIndex); + eyePosition = Util::GetEyePosition(eyeIndex); data.centre[eyeIndex].x = centerPos.x - eyePosition.x; data.centre[eyeIndex].y = centerPos.y - eyePosition.y; data.centre[eyeIndex].z = centerPos.z - eyePosition.z; diff --git a/src/Features/LightLimitFix.cpp b/src/Features/LightLimitFix.cpp index bde424394..981da3835 100644 --- a/src/Features/LightLimitFix.cpp +++ b/src/Features/LightLimitFix.cpp @@ -328,7 +328,6 @@ void LightLimitFix::BSLightingShader_SetupGeometry_After(RE::BSRenderPass*) void LightLimitFix::SetLightPosition(LightLimitFix::LightData& a_light, RE::NiPoint3 a_initialPosition, bool a_cached) { - auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); for (int eyeIndex = 0; eyeIndex < eyeCount; eyeIndex++) { RE::NiPoint3 eyePosition; Matrix viewMatrix; @@ -337,12 +336,8 @@ void LightLimitFix::SetLightPosition(LightLimitFix::LightData& a_light, RE::NiPo eyePosition = eyePositionCached[eyeIndex]; viewMatrix = viewMatrixCached[eyeIndex]; } else { - eyePosition = eyeCount == 1 ? - shadowState->GetRuntimeData().posAdjust.getEye(eyeIndex) : - shadowState->GetVRRuntimeData().posAdjust.getEye(eyeIndex); - viewMatrix = eyeCount == 1 ? - shadowState->GetRuntimeData().cameraData.getEye(eyeIndex).viewMat : - shadowState->GetVRRuntimeData().cameraData.getEye(eyeIndex).viewMat; + eyePosition = Util::GetEyePosition(eyeIndex); + viewMatrix = Util::GetCameraData(eyeIndex).viewMat; } auto worldPos = a_initialPosition - eyePosition; @@ -672,17 +667,12 @@ void LightLimitFix::UpdateLights() lightsFar = std::min(16384.0f, accumulator->kCamera->GetRuntimeData2().viewFrustum.fFar); auto shadowSceneNode = RE::BSShaderManager::State::GetSingleton().shadowSceneNode[0]; - auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); // Cache data since cameraData can become invalid in first-person for (int eyeIndex = 0; eyeIndex < eyeCount; eyeIndex++) { - eyePositionCached[eyeIndex] = eyeCount == 1 ? - shadowState->GetRuntimeData().posAdjust.getEye(eyeIndex) : - shadowState->GetVRRuntimeData().posAdjust.getEye(eyeIndex); - viewMatrixCached[eyeIndex] = eyeCount == 1 ? - shadowState->GetRuntimeData().cameraData.getEye(eyeIndex).viewMat : - shadowState->GetVRRuntimeData().cameraData.getEye(eyeIndex).viewMat; + eyePositionCached[eyeIndex] = Util::GetEyePosition(eyeIndex); + viewMatrixCached[eyeIndex] = Util::GetCameraData(eyeIndex).viewMat; viewMatrixCached[eyeIndex].Invert(viewMatrixInverseCached[eyeIndex]); } @@ -865,7 +855,7 @@ void LightLimitFix::UpdateLights() static auto& context = State::GetSingleton()->context; { - auto projMatrixUnjittered = eyeCount == 1 ? shadowState->GetRuntimeData().cameraData.getEye().projMatrixUnjittered : shadowState->GetVRRuntimeData().cameraData.getEye().projMatrixUnjittered; + auto projMatrixUnjittered = Util::GetCameraData(0).projMatrixUnjittered; float fov = atan(1.0f / static_cast(projMatrixUnjittered).m[0][0]) * 2.0f * (180.0f / 3.14159265359f); static float _near = 0.0f, _far = 0.0f, _fov = 0.0f, _lightsNear = 0.0f, _lightsFar = 0.0f; @@ -875,7 +865,7 @@ void LightLimitFix::UpdateLights() if (eyeCount == 1) updateData.InvProjMatrix[1] = updateData.InvProjMatrix[0]; else - updateData.InvProjMatrix[1] = DirectX::XMMatrixInverse(nullptr, shadowState->GetVRRuntimeData().cameraData.getEye(1).projMatrixUnjittered); + updateData.InvProjMatrix[1] = DirectX::XMMatrixInverse(nullptr, Util::GetCameraData(1).projMatrixUnjittered); updateData.LightsNear = lightsNear; updateData.LightsFar = lightsFar; diff --git a/src/Features/ScreenSpaceGI.cpp b/src/Features/ScreenSpaceGI.cpp index deca534cd..96635554d 100644 --- a/src/Features/ScreenSpaceGI.cpp +++ b/src/Features/ScreenSpaceGI.cpp @@ -510,7 +510,6 @@ void ScreenSpaceGI::GenerateHilbertLUT() void ScreenSpaceGI::UpdateSB() { auto viewport = RE::BSGraphics::State::GetSingleton(); - auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); float2 res = { (float)texRadiance->desc.Width, (float)texRadiance->desc.Height }; float2 dynres = res * viewport->GetRuntimeData().dynamicResolutionCurrentWidthScale; @@ -523,7 +522,7 @@ void ScreenSpaceGI::UpdateSB() SSGICB data; { for (int eyeIndex = 0; eyeIndex < (1 + REL::Module::IsVR()); ++eyeIndex) { - auto eye = (!REL::Module::IsVR()) ? state->GetRuntimeData().cameraData.getEye(eyeIndex) : state->GetVRRuntimeData().cameraData.getEye(eyeIndex); + auto eye = Util::GetCameraData(eyeIndex); data.PrevInvViewMat[eyeIndex] = prevInvView[eyeIndex]; data.NDCToViewMul[eyeIndex] = { 2.0f / eye.projMat(0, 0), -2.0f / eye.projMat(1, 1) }; diff --git a/src/Features/ScreenSpaceShadows.cpp b/src/Features/ScreenSpaceShadows.cpp index 608680c29..396808c0f 100644 --- a/src/Features/ScreenSpaceShadows.cpp +++ b/src/Features/ScreenSpaceShadows.cpp @@ -90,7 +90,6 @@ void ScreenSpaceShadows::DrawShadows() auto renderer = RE::BSGraphics::Renderer::GetSingleton(); auto context = State::GetSingleton()->context; - auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); auto viewport = RE::BSGraphics::State::GetSingleton(); auto accumulator = RE::BSGraphics::BSShaderAccumulator::GetCurrentAccumulator(); @@ -103,9 +102,7 @@ void ScreenSpaceShadows::DrawShadows() light.Normalize(); float4 lightProjection = float4(-light.x, -light.y, -light.z, 0.0f); - Matrix viewProjMat = !REL::Module::IsVR() ? - shadowState->GetRuntimeData().cameraData.getEye().viewProjMat : - shadowState->GetVRRuntimeData().cameraData.getEye().viewProjMat; + Matrix viewProjMat = Util::GetCameraData(0).viewProjMat; lightProjection = DirectX::SimpleMath::Vector4::Transform(lightProjection, viewProjMat); float lightProjectionF[4] = { lightProjection.x, lightProjection.y, lightProjection.z, lightProjection.w }; @@ -164,7 +161,7 @@ void ScreenSpaceShadows::DrawShadows() if (REL::Module::IsVR()) { lightProjection = float4(-light.x, -light.y, -light.z, 0.0f); - viewProjMat = shadowState->GetVRRuntimeData().cameraData.getEye(1).viewProjMat; + viewProjMat = Util::GetCameraData(1).viewProjMat; lightProjection = DirectX::SimpleMath::Vector4::Transform(lightProjection, viewProjMat); diff --git a/src/Features/SubsurfaceScattering.cpp b/src/Features/SubsurfaceScattering.cpp index a01fe9b57..41c1d2625 100644 --- a/src/Features/SubsurfaceScattering.cpp +++ b/src/Features/SubsurfaceScattering.cpp @@ -169,9 +169,7 @@ void SubsurfaceScattering::DrawSSS() float resolutionY = blurHorizontalTemp->desc.Height * viewport->GetRuntimeData().dynamicResolutionCurrentHeightScale; { - auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); - auto cameraData = !REL::Module::IsVR() ? shadowState->GetRuntimeData().cameraData.getEye() : - shadowState->GetVRRuntimeData().cameraData.getEye(); + auto cameraData = Util::GetCameraData(0); blurCBData.SSSS_FOVY = atan(1.0f / cameraData.projMat.m[0][0]) * 2.0f * (180.0f / 3.14159265359f); diff --git a/src/Util.h b/src/Util.h index f00ac2c91..1ace3f0a8 100644 --- a/src/Util.h +++ b/src/Util.h @@ -28,6 +28,31 @@ namespace Util void DumpSettingsOptions(); float4 GetCameraData(); + inline RE::NiPoint3 GetAverageEyePosition() + { + auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); + if (!REL::Module::IsVR()) + return shadowState->GetRuntimeData().posAdjust.getEye(); + return (shadowState->GetVRRuntimeData().posAdjust.getEye(0) + shadowState->GetVRRuntimeData().posAdjust.getEye(1)) * 0.5f; + } + + inline RE::NiPoint3 GetEyePosition(int eyeIndex) + { + auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); + if (!REL::Module::IsVR()) + return shadowState->GetRuntimeData().posAdjust.getEye(); + return shadowState->GetVRRuntimeData().posAdjust.getEye(eyeIndex); + } + + inline RE::BSGraphics::ViewData GetCameraData(int eyeIndex) + { + auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton(); + if (!REL::Module::IsVR()) { + return shadowState->GetRuntimeData().cameraData.getEye(); + } + return shadowState->GetVRRuntimeData().cameraData.getEye(eyeIndex); + } + struct DispatchCount { uint x; From 096d5dbe00d871052e52a8e9d7abd9de314851fa Mon Sep 17 00:00:00 2001 From: Tim <15017472+doodlum@users.noreply.github.com> Date: Mon, 8 Jul 2024 01:16:33 +0100 Subject: [PATCH 18/20] fix: incorrect reflections --- package/Shaders/DeferredCompositeCS.hlsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/Shaders/DeferredCompositeCS.hlsl b/package/Shaders/DeferredCompositeCS.hlsl index 1cac186d1..6b5865891 100644 --- a/package/Shaders/DeferredCompositeCS.hlsl +++ b/package/Shaders/DeferredCompositeCS.hlsl @@ -16,7 +16,7 @@ RWTexture2D NormalTAAMaskSpecularMaskRW : register(u1); RWTexture2D SnowParametersRW : register(u2); #if defined(DYNAMIC_CUBEMAPS) -Texture2D DepthTexture : register(t5); +Texture2D DepthTexture : register(t5); Texture2D ReflectanceTexture : register(t6); TextureCube EnvTexture : register(t7); TextureCube EnvReflectionsTexture : register(t8); @@ -61,7 +61,7 @@ Texture2D SkylightingTexture : register(t9); half depth = DepthTexture[dispatchID.xy]; half4 positionCS = half4(2 * half2(uv.x, -uv.y + 1) - 1, depth, 1); - positionCS = mul(CameraViewInverse[eyeIndex], positionCS); + positionCS = mul(CameraViewProjInverse[eyeIndex], positionCS); positionCS.xyz = positionCS.xyz / positionCS.w; half3 positionWS = positionCS; From c25c931e11252f7b95ce1e667b1dac71aee6d0ea Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 7 Jul 2024 23:16:11 -0700 Subject: [PATCH 19/20] feat: add particle shader --- package/Shaders/Particle.hlsl | 75 ++++++++++++++++++++++++++--------- src/ShaderCache.h | 1 + 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/package/Shaders/Particle.hlsl b/package/Shaders/Particle.hlsl index a3562c0e1..45be05a3d 100644 --- a/package/Shaders/Particle.hlsl +++ b/package/Shaders/Particle.hlsl @@ -1,3 +1,7 @@ +#include "Common/Constants.hlsli" +#include "Common/FrameBuffer.hlsl" +#include "Common/VR.hlsli" + struct VS_INPUT { float4 Position : POSITION0; @@ -11,6 +15,9 @@ struct VS_INPUT int4 #endif TexCoord1 : TEXCOORD1; +#if defined(VR) + uint InstanceID : SV_INSTANCEID; +#endif // VR }; struct VS_OUTPUT @@ -21,6 +28,11 @@ struct VS_OUTPUT #if defined(ENVCUBE) float4 PrecipitationOcclusionTexCoord : TEXCOORD1; #endif +#if defined(VR) + float ClipDistance : SV_ClipDistance0; // o11 + float CullDistance : SV_CullDistance0; // p11 + uint EyeIndex : EYEIDX0; +#endif // VR }; #ifdef VSHADER @@ -31,22 +43,27 @@ cbuffer PerTechnique : register(b0) cbuffer PerGeometry : register(b2) { - row_major float4x4 WorldViewProj; - row_major float4x4 WorldView; +# if !defined(VR) + row_major float4x4 WorldViewProj[1]; // 0 + row_major float4x4 WorldView[1]; // 4 +# else + row_major float4x4 WorldViewProj[2]; // 0 + row_major float4x4 WorldView[2]; // 8 +# endif # if defined(ENVCUBE) - row_major float4x4 PrecipitationOcclusionWorldViewProj; + row_major float4x4 PrecipitationOcclusionWorldViewProj; // 8, 16 # endif - float4 fVars0; - float4 fVars1; - float4 fVars2; - float4 fVars3; - float4 fVars4; - float4 Color1; - float4 Color2; - float4 Color3; - float4 Velocity; - float4 Acceleration; - float4 Wind; + float4 fVars0; // 8, 16 ENVCUBE 12, 20 + float4 fVars1; // 9, 17 ENVCUBE 13, 21 + float4 fVars2; // 10, 18 ENVCUBE 14, 22 + float4 fVars3; // 11, 19 ENVCUBE 15, 23 + float4 fVars4; // 12, 20 ENVCUBE 16, 24 + float4 Color1; // 13, 21 ENVCUBE 17, 25 + float4 Color2; // 14, 22 ENVCUBE 18, 26 + float4 Color3; // 15, 23 ENVCUBE 19, 27 + float4 Velocity; // 16, 24 ENVCUBE 20, 28 + float4 Acceleration; // 17, 25 ENVCUBE 21, 29 + float4 Wind; // 18, 26 ENVCUBE 22, 30 } float2x2 GetRotationMatrix(float angle) @@ -61,6 +78,12 @@ VS_OUTPUT main(VS_INPUT input) { VS_OUTPUT vsout; + uint eyeIndex = GetEyeIndexVS( +# if defined(VR) + input.InstanceID +# endif + ); + # if defined(ENVCUBE) # if defined(RAIN) float2 positionOffset = input.TexCoord1.xy; @@ -77,11 +100,11 @@ VS_OUTPUT main(VS_INPUT input) msPosition.xyz = normalizedPosition * fVars2.xxx + (-(fVars2.x * 0.5).xxx + fVars1.xyz); msPosition.w = 1; - float4 viewPosition = mul(WorldViewProj, msPosition); + float4 viewPosition = mul(WorldViewProj[eyeIndex], msPosition); # if defined(RAIN) float4 adjustedMsPosition = msPosition - float4(Velocity.xyz, 0); float positionBlendParam = 0.5 * (1 + input.TexCoord1.y); - float4 adjustedViewPosition = mul(WorldViewProj, adjustedMsPosition); + float4 adjustedViewPosition = mul(WorldViewProj[eyeIndex], adjustedMsPosition); float4 finalViewPosition = lerp(adjustedViewPosition, viewPosition, positionBlendParam); # else float4 finalViewPosition = viewPosition; @@ -137,7 +160,7 @@ VS_OUTPUT main(VS_INPUT input) input.Position.xyz)); msPosition.w = 1; - float4 viewPosition = mul(WorldViewProj, msPosition); + float4 viewPosition = mul(WorldViewProj[eyeIndex], msPosition); vsout.Position.xy = positionOffset * ScaleAdjust + viewPosition.xy; vsout.Position.zw = viewPosition.zw; @@ -171,6 +194,13 @@ VS_OUTPUT main(VS_INPUT input) vsout.Color.xyz = color.xyz; # endif +# ifdef VR + vsout.EyeIndex = eyeIndex; + VR_OUTPUT VRout = GetVRVSOutput(vsout.Position, eyeIndex); + vsout.Position = VRout.VRPosition; + vsout.ClipDistance.x = VRout.ClipDistance; + vsout.CullDistance.x = VRout.CullDistance; +# endif // VR return vsout; } #endif @@ -212,8 +242,17 @@ PS_OUTPUT main(PS_INPUT input) { PS_OUTPUT psout; +# if !defined(VR) + uint eyeIndex = 0; +# else + uint eyeIndex = input.EyeIndex; +# endif // !VR + # if defined(ENVCUBE) - float2 precipitationOcclusionUv = input.PrecipitationOcclusionTexCoord.xy * 0.5 + 0.5; + float2 precipitationOcclusionUv = (input.PrecipitationOcclusionTexCoord.xy * 0.5 + 0.5) * TextureSize.x; +# ifdef VR + precipitationOcclusionUv *= DynamicResolutionParams1.x; // only difference in VR +# endif float precipitationOcclusion = -input.PrecipitationOcclusionTexCoord.z + TexPrecipitationOcclusionTexture.SampleLevel(SampSourceTexture, precipitationOcclusionUv, 0).x; float2 underwaterMaskUv = TextureSize.yz * input.Position.xy; float underwaterMask = TexUnderwaterMask.Sample(SampUnderwaterMask, underwaterMaskUv).x; diff --git a/src/ShaderCache.h b/src/ShaderCache.h index 0573574d7..47dd9a5f5 100644 --- a/src/ShaderCache.h +++ b/src/ShaderCache.h @@ -119,6 +119,7 @@ namespace SIE type == RE::BSShader::Type::DistantTree || type == RE::BSShader::Type::Sky || type == RE::BSShader::Type::Grass || + type == RE::BSShader::Type::Particle || type == RE::BSShader::Type::Water || type == RE::BSShader::Type::Effect || type == RE::BSShader::Type::Utility; From 1ffc047026c0ad2634dcf64beaba16ee952f1ac3 Mon Sep 17 00:00:00 2001 From: Alan Tse Date: Sun, 7 Jul 2024 23:47:30 -0700 Subject: [PATCH 20/20] feat: add bloodsplatter shader VR and Flat look identical in RE. With this we have parity across both. --- src/ShaderCache.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ShaderCache.h b/src/ShaderCache.h index 47dd9a5f5..5d942a839 100644 --- a/src/ShaderCache.h +++ b/src/ShaderCache.h @@ -116,6 +116,7 @@ namespace SIE type == RE::BSShader::Type::Effect || type == RE::BSShader::Type::Utility; return type == RE::BSShader::Type::Lighting || + type == RE::BSShader::Type::BloodSplatter || type == RE::BSShader::Type::DistantTree || type == RE::BSShader::Type::Sky || type == RE::BSShader::Type::Grass ||