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(VR): fix eye mismatch for screenspacegi #666

Merged
merged 5 commits into from
Nov 12, 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
21 changes: 19 additions & 2 deletions package/Shaders/AmbientCompositeCS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ Texture2D<unorm float> DepthTexture : register(t2);
Texture3D<sh2> SkylightingProbeArray : register(t3);
#endif

#if !defined(SKYLIGHTING) && defined(VR) // VR also needs a depthbuffer
Texture2D<unorm float> DepthTexture : register(t2);
#endif

#if defined(SSGI)
Texture2D<half4> SSGITexture : register(t4);
#endif
Expand All @@ -28,8 +32,9 @@ RWTexture2D<half3> DiffuseAmbientRW : register(u1);

[numthreads(8, 8, 1)] void main(uint3 dispatchID
: SV_DispatchThreadID) {
half2 uv = half2(dispatchID.xy + 0.5) * BufferDim.zw * DynamicResolutionParams2.xy;
half2 uv = half2(dispatchID.xy + 0.5) * BufferDim.zw;
uint eyeIndex = Stereo::GetEyeIndexFromTexCoord(uv);
uv *= DynamicResolutionParams2.xy; // adjust for dynamic res
uv = Stereo::ConvertFromStereoUV(uv, eyeIndex);

half3 normalGlossiness = NormalRoughnessTexture[dispatchID.xy];
Expand Down Expand Up @@ -58,7 +63,7 @@ RWTexture2D<half3> DiffuseAmbientRW : register(u1);
float4 positionMS = mul(CameraViewProjInverse[eyeIndex], positionCS);
positionMS.xyz = positionMS.xyz / positionMS.w;
# if defined(VR)
positionMS.xyz += CameraPosAdjust[eyeIndex] - CameraPosAdjust[0];
positionMS.xyz += CameraPosAdjust[eyeIndex].xyz - CameraPosAdjust[0].xyz;
# endif

sh2 skylighting = Skylighting::sample(skylightingSettings, SkylightingProbeArray, positionMS.xyz, normalWS);
Expand All @@ -69,7 +74,19 @@ RWTexture2D<half3> DiffuseAmbientRW : register(u1);
#endif

#if defined(SSGI)
# if defined(VR)
float3 uvF = float3((dispatchID.xy + 0.5) * BufferDim.zw, DepthTexture[dispatchID.xy]); // calculate high precision uv of initial eye
float3 uv2 = Stereo::ConvertStereoUVToOtherEyeStereoUV(uvF, eyeIndex, false); // calculate other eye uv
float3 uv1Mono = Stereo::ConvertFromStereoUV(uvF, eyeIndex);
float3 uv2Mono = Stereo::ConvertFromStereoUV(uv2, (1 - eyeIndex));
uint2 pixCoord2 = (uint2)(uv2.xy / BufferDim.zw - 0.5);
# endif

half4 ssgiDiffuse = SSGITexture[dispatchID.xy];
# if defined(VR)
half4 ssgiDiffuse2 = SSGITexture[pixCoord2];
ssgiDiffuse = Stereo::BlendEyeColors(uv1Mono, (float4)ssgiDiffuse, uv2Mono, (float4)ssgiDiffuse2);
# endif
ssgiDiffuse.rgb *= linAlbedo;
ssgiDiffuse.a = 1 - ssgiDiffuse.a;

Expand Down
34 changes: 21 additions & 13 deletions package/Shaders/Common/VR.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# include "Common/Math.hlsli"
# endif // VSHADER

# if !defined(COMPUTESHADER) && !defined(CSHADER)
# if (!defined(COMPUTESHADER) && !defined(CSHADER)) || defined(FRAMEBUFFER)
# include "Common/FrameBuffer.hlsli"
# endif
cbuffer VRValues : register(b13)
Expand Down Expand Up @@ -150,7 +150,8 @@ namespace Stereo
return normalizedCoord;
}

#ifdef PSHADER
#if defined(PSHADER) || defined(FRAMEBUFFER)
// These functions require the framebuffer which is typically provided with the PSHADER
/**
Gets the eyeIndex for PSHADER
@returns eyeIndex (0 left, 1 right)
Expand Down Expand Up @@ -192,32 +193,39 @@ namespace Stereo
* @brief Converts mono UV coordinates from one eye to the corresponding mono UV coordinates of the other eye.
*
* This function is used to transition UV coordinates from one eye's perspective to the other eye in a stereo rendering setup.
* It works by converting the mono UV to clip space, transforming it into view space, and then reprojecting it into the other eye's
* clip space before converting back to UV coordinates. It also supports dynamic resolution.
* It operates by converting the mono UV to clip space, transforming it into world space, and then reprojecting it
* into the other eye's clip space before converting back to UV coordinates. It supports dynamic resolution adjustments
* and applies eye offset adjustments for correct stereo separation.
*
* The function considers the aspect of VR by modifying the NDC to view space conversion based on the stereo setup,
* ensuring accurate rendering across both eyes.
*
* @param[in] monoUV The UV coordinates and depth value (Z component) for the current eye, in the range [0,1].
* @param[in] eyeIndex Index of the source/current eye (0 or 1).
* @param[in] eyeIndex Index of the source/current eye (0 for left, 1 for right).
* @param[in] dynamicres Optional flag indicating whether dynamic resolution is applied. Default is false.
* @return UV coordinates adjusted to the other eye, with depth.
*/
float3 ConvertMonoUVToOtherEye(float3 monoUV, uint eyeIndex, bool dynamicres = false)
{
// Convert from dynamic res to true UV space
// Convert from dynamic res to true UV space if necessary
if (dynamicres)
monoUV.xy *= DynamicResolutionParams2.xy;

// Step 1: Convert UV to Clip Space
// Convert UV to Clip Space
float4 clipPos = float4(monoUV.xy * float2(2, -2) - float2(1, -1), monoUV.z, 1);

// Step 2: Convert Clip Space to View Space for the current eye
float4 viewPosCurrentEye = mul(CameraProjInverse[eyeIndex], clipPos);
viewPosCurrentEye /= viewPosCurrentEye.w;
// Convert Clip Space to World Space for the current eye
float4 worldPos = mul(CameraViewProjInverse[eyeIndex], clipPos);
worldPos /= worldPos.w;

// Apply eye offset adjustment in world space
worldPos.xyz += CameraPosAdjust[eyeIndex].xyz - CameraPosAdjust[1 - eyeIndex].xyz;

// Step 3: Convert View Space to Clip Space for the other eye
float4 clipPosOtherEye = mul(CameraProj[1 - eyeIndex], viewPosCurrentEye);
// Convert World Space to Clip Space for the other eye
float4 clipPosOtherEye = mul(CameraViewProj[1 - eyeIndex], worldPos);
clipPosOtherEye /= clipPosOtherEye.w;

// Step 4: Convert Clip Space to UV
// Convert Clip Space to UV
float3 monoUVOtherEye = float3((clipPosOtherEye.xy * 0.5f) + 0.5f, clipPosOtherEye.z);

// Convert back to dynamic res space if necessary
Expand Down
21 changes: 19 additions & 2 deletions package/Shaders/DeferredCompositeCS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ TextureCube<half3> EnvReflectionsTexture : register(t8);
SamplerState LinearSampler : register(s0);
#endif

#if !defined(DYNAMIC_CUBEMAPS) && defined(VR) // VR also needs a depthbuffer
Texture2D<float> DepthTexture : register(t5);
#endif

#if defined(SKYLIGHTING)
# include "Skylighting/Skylighting.hlsli"

Expand All @@ -36,8 +40,9 @@ Texture2D<half4> SpecularSSGITexture : register(t10);

[numthreads(8, 8, 1)] void main(uint3 dispatchID
: SV_DispatchThreadID) {
half2 uv = half2(dispatchID.xy + 0.5) * BufferDim.zw * DynamicResolutionParams2.xy;
half2 uv = half2(dispatchID.xy + 0.5) * BufferDim.zw;
uint eyeIndex = Stereo::GetEyeIndexFromTexCoord(uv);
uv *= DynamicResolutionParams2.xy; // adjust for dynamic res
uv = Stereo::ConvertFromStereoUV(uv, eyeIndex);

half3 normalGlossiness = NormalRoughnessTexture[dispatchID.xy];
Expand Down Expand Up @@ -91,7 +96,7 @@ Texture2D<half4> SpecularSSGITexture : register(t10);
finalIrradiance += specularIrradiance;
# elif defined(SKYLIGHTING)
# if defined(VR)
float3 positionMS = positionWS + CameraPosAdjust[eyeIndex] - CameraPosAdjust[0];
float3 positionMS = positionWS + CameraPosAdjust[eyeIndex].xyz - CameraPosAdjust[0].xyz;
# else
float3 positionMS = positionWS;
# endif
Expand Down Expand Up @@ -124,7 +129,19 @@ Texture2D<half4> SpecularSSGITexture : register(t10);
# endif

# if defined(SSGI)
# if defined(VR)
float3 uvF = float3((dispatchID.xy + 0.5) * BufferDim.zw, DepthTexture[dispatchID.xy]); // calculate high precision uv of initial eye
float3 uv2 = Stereo::ConvertStereoUVToOtherEyeStereoUV(uvF, eyeIndex, false); // calculate other eye uv
float3 uv1Mono = Stereo::ConvertFromStereoUV(uvF, eyeIndex);
float3 uv2Mono = Stereo::ConvertFromStereoUV(uv2, (1 - eyeIndex));
uint2 pixCoord2 = (uint2)(uv2.xy / BufferDim.zw - 0.5);
# endif

half4 ssgiSpecular = SpecularSSGITexture[dispatchID.xy];
# if defined(VR)
half4 ssgiSpecular2 = SpecularSSGITexture[pixCoord2];
ssgiSpecular = Stereo::BlendEyeColors(uv1Mono, (float4)ssgiSpecular, uv2Mono, (float4)ssgiSpecular2);
# endif
finalIrradiance = finalIrradiance * (1 - ssgiSpecular.a) + ssgiSpecular.rgb;
# endif

Expand Down
42 changes: 38 additions & 4 deletions src/Deferred.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,18 @@ void Deferred::StartDeferred()
static REL::Relocation<ID3D11Buffer**> perFrame{ REL::RelocationID(524768, 411384) };
ID3D11Buffer* buffers[1] = { *perFrame.get() };

context->CSSetConstantBuffers(12, 1, buffers);
ID3D11Buffer* vrBuffer = nullptr;

if (REL::Module::IsVR()) {
static REL::Relocation<ID3D11Buffer**> VRValues{ REL::Offset(0x3180688) };
vrBuffer = *VRValues.get();
}
if (vrBuffer) {
context->CSSetConstantBuffers(12, 1, buffers);
context->CSSetConstantBuffers(13, 1, &vrBuffer);
} else {
context->CSSetConstantBuffers(12, 1, buffers);
}
}

PrepassPasses();
Expand All @@ -333,7 +344,18 @@ void Deferred::DeferredPasses()
{
static REL::Relocation<ID3D11Buffer**> perFrame{ REL::RelocationID(524768, 411384) };
ID3D11Buffer* buffers[1] = { *perFrame.get() };
context->CSSetConstantBuffers(12, 1, buffers);
ID3D11Buffer* vrBuffer = nullptr;

if (REL::Module::IsVR()) {
static REL::Relocation<ID3D11Buffer**> VRValues{ REL::Offset(0x3180688) };
vrBuffer = *VRValues.get();
}
if (vrBuffer) {
context->CSSetConstantBuffers(12, 1, buffers);
context->CSSetConstantBuffers(13, 1, &vrBuffer);
} else {
context->CSSetConstantBuffers(12, 1, buffers);
}
}

auto specular = renderer->GetRuntimeData().renderTargets[SPECULAR];
Expand Down Expand Up @@ -369,7 +391,7 @@ void Deferred::DeferredPasses()
ID3D11ShaderResourceView* srvs[6]{
albedo.SRV,
normalRoughness.SRV,
skylighting->loaded ? depth.depthSRV : nullptr,
skylighting->loaded || REL::Module::IsVR() ? depth.depthSRV : nullptr,
skylighting->loaded ? skylighting->texProbeArray->srv.get() : nullptr,
ssgi->settings.Enabled ? ssgi->texGI[ssgi->outputGIIdx]->srv.get() : nullptr,
masks2.SRV,
Expand Down Expand Up @@ -420,7 +442,7 @@ void Deferred::DeferredPasses()
normalRoughness.SRV,
masks.SRV,
masks2.SRV,
dynamicCubemaps->loaded ? (terrainBlending->loaded ? terrainBlending->blendedDepthTexture16->srv.get() : depth.depthSRV) : nullptr,
dynamicCubemaps->loaded || REL::Module::IsVR() ? (terrainBlending->loaded ? terrainBlending->blendedDepthTexture16->srv.get() : depth.depthSRV) : nullptr,
dynamicCubemaps->loaded ? reflectance.SRV : nullptr,
dynamicCubemaps->loaded ? dynamicCubemaps->envTexture->srv.get() : nullptr,
dynamicCubemaps->loaded ? dynamicCubemaps->envReflectionsTexture->srv.get() : nullptr,
Expand Down Expand Up @@ -570,6 +592,9 @@ ID3D11ComputeShader* Deferred::GetComputeAmbientComposite()
if (ScreenSpaceGI::GetSingleton()->loaded)
defines.push_back({ "SSGI", nullptr });

if (REL::Module::IsVR())
defines.push_back({ "FRAMEBUFFER", nullptr });

ambientCompositeCS = static_cast<ID3D11ComputeShader*>(Util::CompileShader(L"Data\\Shaders\\AmbientCompositeCS.hlsl", defines, "cs_5_0"));
}
return ambientCompositeCS;
Expand All @@ -586,6 +611,9 @@ ID3D11ComputeShader* Deferred::GetComputeAmbientCompositeInterior()
if (ScreenSpaceGI::GetSingleton()->loaded)
defines.push_back({ "SSGI", nullptr });

if (REL::Module::IsVR())
defines.push_back({ "FRAMEBUFFER", nullptr });

ambientCompositeInteriorCS = static_cast<ID3D11ComputeShader*>(Util::CompileShader(L"Data\\Shaders\\AmbientCompositeCS.hlsl", defines, "cs_5_0"));
}
return ambientCompositeInteriorCS;
Expand All @@ -607,6 +635,9 @@ ID3D11ComputeShader* Deferred::GetComputeMainComposite()
if (ScreenSpaceGI::GetSingleton()->loaded)
defines.push_back({ "SSGI", nullptr });

if (REL::Module::IsVR())
defines.push_back({ "FRAMEBUFFER", nullptr });

mainCompositeCS = static_cast<ID3D11ComputeShader*>(Util::CompileShader(L"Data\\Shaders\\DeferredCompositeCS.hlsl", defines, "cs_5_0"));
}
return mainCompositeCS;
Expand All @@ -626,6 +657,9 @@ ID3D11ComputeShader* Deferred::GetComputeMainCompositeInterior()
if (ScreenSpaceGI::GetSingleton()->loaded)
defines.push_back({ "SSGI", nullptr });

if (REL::Module::IsVR())
defines.push_back({ "FRAMEBUFFER", nullptr });

mainCompositeInteriorCS = static_cast<ID3D11ComputeShader*>(Util::CompileShader(L"Data\\Shaders\\DeferredCompositeCS.hlsl", defines, "cs_5_0"));
}
return mainCompositeInteriorCS;
Expand Down
Loading