Skip to content

Commit

Permalink
fix: fix upscaler support (#361)
Browse files Browse the repository at this point in the history
  • Loading branch information
FlayaN authored Jul 31, 2024
1 parent d8f6acc commit e4369de
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ cbuffer PerFrame : register(b1)
float2 InvDepthTextureSize; // Inverse of the texture dimensions for 'DepthTexture' (used to convert from pixel coordinates to UVs)
// If 'PointBorderSampler' is an Unnormalized sampler, then this value can be hard-coded to 1.
// The 'USE_HALF_PIXEL_OFFSET' macro might need to be defined if sampling at exact pixel coordinates isn't precise (e.g., if odd patterns appear in the shadow).

float2 DynamicRes;

float SurfaceThickness;
float BilinearThreshold;
float ShadowContrast;
Expand All @@ -47,5 +50,7 @@ cbuffer PerFrame : register(b1)
parameters.BilinearThreshold = BilinearThreshold;
parameters.ShadowContrast = ShadowContrast;

parameters.DynamicRes = DynamicRes;

WriteScreenSpaceShadow(parameters, groupID, groupThreadID);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ float GetScreenSpaceShadow(float2 a_uv, float a_noise, float3 a_viewPosition, ui
float2 offset = mul(BlurOffsets[i], rotationMatrix) * 0.0025;

float2 sampleUV = a_uv + offset;
sampleUV = saturate(sampleUV);
int3 sampleCoord = ConvertUVToSampleCoord(sampleUV, a_eyeIndex);

float rawDepth = TexDepthSampler.Load(sampleCoord).x;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ struct DispatchParameters
half ShadowContrast; // A contrast boost is applied to the transition in/out of shadow.
// Recommended starting value: 2 or 4. Values >= 1 are valid.

float2 DynamicRes;

bool IgnoreEdgePixels; // If an edge is detected, the edge pixel will not contribute to the shadow.
// If a very flat surface is being lit and rendered at an grazing angles, the edge detect may incorrectly detect multiple 'edge' pixels along that flat surface.
// In these cases, the grazing angle of the light may subsequently produce aliasing artefacts in the shadow where these incorrect edges were detected.
Expand Down Expand Up @@ -259,16 +261,6 @@ void WriteScreenSpaceShadow(DispatchParameters inParameters, int3 inGroupID, int

half2 write_xy = floor(pixel_xy);

# if !defined(RIGHT)
half2 minUV = half2(0.0, 0.0);
half2 maxUV = half2(0.5, 1.0);
# else
half2 minUV = half2(0.5, 0.0);
half2 maxUV = half2(1.0, 1.0);
# endif

half2 uv = pixel_xy * inParameters.InvDepthTextureSize * half2(0.5, 1.0);

[unroll] for (i = 0; i < READ_COUNT; i++)
{
// We sample depth twice per pixel per sample, and interpolate with an edge detect filter
Expand All @@ -291,14 +283,17 @@ void WriteScreenSpaceShadow(DispatchParameters inParameters, int3 inGroupID, int

// HLSL enforces that a pixel offset is a compile-time constant, which isn't strictly required (and can sometimes be a bit faster)
// So this fallback will use a manual uv offset instead
half2 coord = read_xy * inParameters.InvDepthTextureSize * inParameters.DynamicRes;
half2 coord_with_offset = (read_xy + offset_xy) * inParameters.InvDepthTextureSize * inParameters.DynamicRes;
# if defined(VR)
coord *= half2(0.5, 1.0);
coord_with_offset *= half2(0.5, 1.0);
# endif
depths.x = inParameters.DepthTexture.SampleLevel(inParameters.PointBorderSampler, coord, 0);
depths.y = inParameters.DepthTexture.SampleLevel(inParameters.PointBorderSampler, coord_with_offset, 0);
# if defined(VR)
depths.x = inParameters.DepthTexture.SampleLevel(inParameters.PointBorderSampler, read_xy * inParameters.InvDepthTextureSize * half2(0.5, 1.0), 0);
depths.y = inParameters.DepthTexture.SampleLevel(inParameters.PointBorderSampler, (read_xy + offset_xy) * inParameters.InvDepthTextureSize * half2(0.5, 1.0), 0);
depths.x = lerp(depths.x, 1.0, (float)(depths.x == 0)); // Stencil area
depths.y = lerp(depths.y, 1.0, (float)(depths.y == 0)); // Stencil area
# else
depths.x = inParameters.DepthTexture.SampleLevel(inParameters.PointBorderSampler, read_xy * inParameters.InvDepthTextureSize, 0);
depths.y = inParameters.DepthTexture.SampleLevel(inParameters.PointBorderSampler, (read_xy + offset_xy) * inParameters.InvDepthTextureSize, 0);
# endif

// Depth thresholds (bilinear/shadow thickness) are based on a fractional ratio of the difference between sampled depth and the far clip depth
Expand Down
2 changes: 1 addition & 1 deletion package/Shaders/AmbientCompositeCS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ RWTexture2D<half3> DiffuseAmbientRW : register(u1);

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

Expand Down
2 changes: 1 addition & 1 deletion package/Shaders/DeferredCompositeCS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Texture3D<sh2> SkylightingProbeArray : register(t9);

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

Expand Down
15 changes: 11 additions & 4 deletions src/Features/ScreenSpaceShadows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,14 @@ void ScreenSpaceShadows::DrawShadows()
lightProjection = DirectX::SimpleMath::Vector4::Transform(lightProjection, viewProjMat);
float lightProjectionF[4] = { lightProjection.x, lightProjection.y, lightProjection.z, lightProjection.w };

int viewportSize[2] = { (int)state->screenSize.x, (int)state->screenSize.y };
float2 size = Util::ConvertToDynamic(state->screenSize);
int viewportSize[2] = { (int)size.x, (int)size.y };

if (REL::Module::IsVR())
viewportSize[0] /= 2;

float2 size = Util::ConvertToDynamic({ (float)viewportSize[0], (float)viewportSize[1] });

int minRenderBounds[2] = { 0, 0 };
int maxRenderBounds[2] = { (int)size.x, (int)size.y };
int maxRenderBounds[2] = { viewportSize[0], viewportSize[1] };

auto depth = renderer->GetDepthStencilData().depthStencils[RE::RENDER_TARGETS_DEPTHSTENCIL::kPOST_ZPREPASS_COPY];
context->CSSetShaderResources(0, 1, &depth.depthSRV);
Expand All @@ -130,6 +129,10 @@ void ScreenSpaceShadows::DrawShadows()

auto dispatchList = Bend::BuildDispatchList(lightProjectionF, viewportSize, minRenderBounds, maxRenderBounds);

auto viewport = RE::BSGraphics::State::GetSingleton();

float2 dynamicRes = { viewport->GetRuntimeData().dynamicResolutionWidthRatio, viewport->GetRuntimeData().dynamicResolutionHeightRatio };

for (int i = 0; i < dispatchList.DispatchCount; i++) {
auto dispatchData = dispatchList.Dispatch[i];

Expand All @@ -148,6 +151,8 @@ void ScreenSpaceShadows::DrawShadows()
data.InvDepthTextureSize[0] = 1.0f / (float)viewportSize[0];
data.InvDepthTextureSize[1] = 1.0f / (float)viewportSize[1];

data.DynamicRes = dynamicRes;

data.settings = bendSettings;

raymarchCB->Update(data);
Expand Down Expand Up @@ -186,6 +191,8 @@ void ScreenSpaceShadows::DrawShadows()
data.InvDepthTextureSize[0] = 1.0f / (float)viewportSize[0];
data.InvDepthTextureSize[1] = 1.0f / (float)viewportSize[1];

data.DynamicRes = dynamicRes;

data.settings = bendSettings;

raymarchCB->Update(data);
Expand Down
4 changes: 3 additions & 1 deletion src/Features/ScreenSpaceShadows.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct ScreenSpaceShadows : Feature
float ShadowContrast = 4.0f;
uint Enable = 1;
uint SampleCount = 1;
uint pad0[1];
uint pad0[3];
};

BendSettings bendSettings;
Expand All @@ -43,6 +43,8 @@ struct ScreenSpaceShadows : Feature
// If 'PointBorderSampler' is an Unnormalized sampler, then this value can be hard-coded to 1.
// The 'USE_HALF_PIXEL_OFFSET' macro might need to be defined if sampling at exact pixel coordinates isn't precise (e.g., if odd patterns appear in the shadow).

float2 DynamicRes;

BendSettings settings;
};

Expand Down

0 comments on commit e4369de

Please sign in to comment.