Skip to content
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
9 changes: 6 additions & 3 deletions features/Screen Space GI/Shaders/ScreenSpaceGI/gi.cs.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Texture2D<float> srcPrevAo : register(t5); // maybe half-res
Texture2D<float4> srcPrevY : register(t6); // maybe half-res
Texture2D<float2> srcPrevCoCg : register(t7); // maybe half-res
Texture2D<float4> srcPrevGISpecular : register(t8); // maybe half-res
Texture2D<float2> srcNormal : register(t9);

RWTexture2D<unorm float> outAo : register(u0);
RWTexture2D<float4> outY : register(u1);
Expand Down Expand Up @@ -206,14 +207,16 @@ void CalculateGI(
float SZ = srcWorkingDepth.SampleLevel(samplerPointClamp, sampleUV * frameScale, mipLevel);

// Reconstruct sample in current eye's viewspace for correct horizon angles.
float3 samplePos = ScreenToViewPosition(sampleScreenPos, SZ, sampleEyeIndex);
// For cross-eye samples, reject if the depth differs too much from the
// center pixel -- the other eye may see a different surface due to occlusion.
float3 samplePos = ScreenToViewPosition(sampleScreenPos, SZ, sampleEyeIndex);
#if defined(VR)
if (sampleEyeIndex != eyeIndex) {
if (abs(SZ - viewspaceZ) > viewspaceZ * 0.1)
continue;
samplePos = FrameBuffer::WorldToView(FrameBuffer::ViewToWorld(samplePos, true, sampleEyeIndex), true, eyeIndex);
}
#endif
float3 sampleDelta = samplePos - pixCenterPos;
float3 sampleHorizonVec = normalize(sampleDelta);

Expand Down Expand Up @@ -263,7 +266,7 @@ void CalculateGI(
float giBoost = 4.0 * Math::PI * (1 + GIDistanceCompensation * smoothstep(0, GICompensationMaxDist, s * EffectRadius));

// IL
float3 normalSample = GBuffer::DecodeNormal(srcNormalRoughness.SampleLevel(samplerPointClamp, sampleUV * frameScale, 0).xy);
float3 normalSample = GBuffer::DecodeNormal(srcNormal.SampleLevel(samplerPointClamp, sampleUV * OUT_FRAME_SCALE, mipLevelRadiance));
if (dot(samplePos, normalSample) > 0)
normalSample = -normalSample;
float frontBackMult = -dot(normalSample, sampleHorizonVec);
Expand Down Expand Up @@ -345,7 +348,7 @@ void CalculateGI(

float viewspaceZ = READ_DEPTH(srcWorkingDepth, pxCoord);

float2 normalSample = FULLRES_LOAD(srcNormalRoughness, pxCoord, uv * frameScale, samplerLinearClamp).xy;
float2 normalSample = FULLRES_LOAD(srcNormal, pxCoord, uv * OUT_FRAME_SCALE, samplerLinearClamp);
float3 viewspaceNormal = GBuffer::DecodeNormal(normalSample);

half2 encodedWorldNormal = GBuffer::EncodeNormal(ViewToWorldVector(viewspaceNormal, FrameBuffer::CameraViewInverse[eyeIndex]));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "Common/GBuffer.hlsli"
#include "ScreenSpaceGI/common.hlsli"

Texture2D<float4> srcNormalRoughness : register(t0);

RWTexture2D<unorm float2> outNormal0 : register(u0);
RWTexture2D<unorm float2> outNormal1 : register(u1);
RWTexture2D<unorm float2> outNormal2 : register(u2);
RWTexture2D<unorm float2> outNormal3 : register(u3);
RWTexture2D<unorm float2> outNormal4 : register(u4);

float2 NormalMIPFilter(float2 enc0, float2 enc1, float2 enc2, float2 enc3)
{
float3 avg = GBuffer::DecodeNormal(enc0) + GBuffer::DecodeNormal(enc1) + GBuffer::DecodeNormal(enc2) + GBuffer::DecodeNormal(enc3);
return GBuffer::EncodeNormal(normalize(avg));
}

groupshared float2 g_scratchNormal[8][8];
[numthreads(8, 8, 1)] void main(uint2 dispatchThreadID : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID) {
const float2 frameScale = FrameDim * RcpTexDim;

// MIP 0
const uint2 baseCoord = dispatchThreadID;
const uint2 pixCoord = baseCoord * 2;
const float2 uv = (pixCoord + .5) * RCP_OUT_FRAME_DIM;

float4 nr0 = srcNormalRoughness.GatherRed(samplerPointClamp, uv * frameScale);
float4 nr1 = srcNormalRoughness.GatherGreen(samplerPointClamp, uv * frameScale);

float2 normal0 = float2(nr0.w, nr1.w);
float2 normal1 = float2(nr0.z, nr1.z);
float2 normal2 = float2(nr0.x, nr1.x);
float2 normal3 = float2(nr0.y, nr1.y);

outNormal0[pixCoord + uint2(0, 0)] = normal0;
outNormal0[pixCoord + uint2(1, 0)] = normal1;
outNormal0[pixCoord + uint2(0, 1)] = normal2;
outNormal0[pixCoord + uint2(1, 1)] = normal3;

// MIP 1
float2 nm1 = NormalMIPFilter(normal0, normal1, normal2, normal3);
outNormal1[baseCoord] = nm1;
g_scratchNormal[groupThreadID.x][groupThreadID.y] = nm1;

GroupMemoryBarrierWithGroupSync();

// MIP 2
[branch] if (all((groupThreadID.xy % 2) == 0))
{
float2 inTL = g_scratchNormal[groupThreadID.x + 0][groupThreadID.y + 0];
float2 inTR = g_scratchNormal[groupThreadID.x + 1][groupThreadID.y + 0];
float2 inBL = g_scratchNormal[groupThreadID.x + 0][groupThreadID.y + 1];
float2 inBR = g_scratchNormal[groupThreadID.x + 1][groupThreadID.y + 1];

float2 nm2 = NormalMIPFilter(inTL, inTR, inBL, inBR);
outNormal2[baseCoord / 2] = nm2;
g_scratchNormal[groupThreadID.x][groupThreadID.y] = nm2;
}

GroupMemoryBarrierWithGroupSync();

// MIP 3
[branch] if (all((groupThreadID.xy % 4) == 0))
{
float2 inTL = g_scratchNormal[groupThreadID.x + 0][groupThreadID.y + 0];
float2 inTR = g_scratchNormal[groupThreadID.x + 2][groupThreadID.y + 0];
float2 inBL = g_scratchNormal[groupThreadID.x + 0][groupThreadID.y + 2];
float2 inBR = g_scratchNormal[groupThreadID.x + 2][groupThreadID.y + 2];

float2 nm3 = NormalMIPFilter(inTL, inTR, inBL, inBR);
outNormal3[baseCoord / 4] = nm3;
g_scratchNormal[groupThreadID.x][groupThreadID.y] = nm3;
}

GroupMemoryBarrierWithGroupSync();

// MIP 4
[branch] if (all((groupThreadID.xy % 8) == 0))
{
float2 inTL = g_scratchNormal[groupThreadID.x + 0][groupThreadID.y + 0];
float2 inTR = g_scratchNormal[groupThreadID.x + 4][groupThreadID.y + 0];
float2 inBL = g_scratchNormal[groupThreadID.x + 0][groupThreadID.y + 4];
float2 inBR = g_scratchNormal[groupThreadID.x + 4][groupThreadID.y + 4];

float2 nm4 = NormalMIPFilter(inTL, inTR, inBL, inBR);
outNormal4[baseCoord / 8] = nm4;
}
}
34 changes: 32 additions & 2 deletions src/Features/ScreenSpaceGI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,16 @@ void ScreenSpaceGI::SetupResources()
}
}

srvDesc.Format = uavDesc.Format = texDesc.Format = DXGI_FORMAT_R8G8_UNORM;
{
texNormal = eastl::make_unique<Texture2D>(texDesc);
texNormal->CreateSRV(srvDesc);
for (uint i = 0; i < 5; ++i) {
uavDesc.Texture2D.MipSlice = i;
DX::ThrowIfFailed(device->CreateUnorderedAccessView(texNormal->resource.get(), &uavDesc, uavNormal[i].put()));
}
}

uavDesc.Texture2D.MipSlice = 0;
texDesc.MipLevels = srvDesc.Texture2D.MipLevels = 1;
srvDesc.Format = uavDesc.Format = texDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
Expand Down Expand Up @@ -569,7 +579,7 @@ void ScreenSpaceGI::SetupResources()
void ScreenSpaceGI::ClearShaderCache()
{
static const std::vector<winrt::com_ptr<ID3D11ComputeShader>*> shaderPtrs = {
&prefilterDepthsCompute, &prefilterRadianceCompute, &radianceDisoccCompute, &giCompute, &blurCompute, &stereoSyncCompute, &upsampleCompute
&prefilterDepthsCompute, &prefilterRadianceCompute, &prefilterNormalCompute, &radianceDisoccCompute, &giCompute, &blurCompute, &stereoSyncCompute, &upsampleCompute
};

for (auto shader : shaderPtrs)
Expand All @@ -591,6 +601,7 @@ void ScreenSpaceGI::CompileComputeShaders()
shaderInfos = {
{ &prefilterDepthsCompute, "prefilterDepths.cs.hlsl", { { "LINEAR_FILTER", "" } } },
{ &prefilterRadianceCompute, "prefilterRadiance.cs.hlsl", {} },
{ &prefilterNormalCompute, "prefilterNormal.cs.hlsl", {} },
{ &radianceDisoccCompute, "radianceDisocc.cs.hlsl", {} },
{ &giCompute, "gi.cs.hlsl", {} },
{ &blurCompute, "blur.cs.hlsl", {} },
Expand Down Expand Up @@ -625,7 +636,7 @@ void ScreenSpaceGI::CompileComputeShaders()

bool ScreenSpaceGI::ShadersOK()
{
return texNoise && prefilterDepthsCompute && prefilterRadianceCompute && radianceDisoccCompute && giCompute && blurCompute && upsampleCompute;
return texNoise && prefilterDepthsCompute && prefilterRadianceCompute && prefilterNormalCompute && radianceDisoccCompute && giCompute && blurCompute && upsampleCompute;
}

void ScreenSpaceGI::UpdateSB()
Expand Down Expand Up @@ -820,6 +831,24 @@ void ScreenSpaceGI::DrawSSGI()
lastFrameAccumTexIdx = !lastFrameAccumTexIdx;
}

// Prefilter normals
{
TracyD3D11Zone(globals::state->tracyCtx, "SSGI - Prefilter Normals");

resetViews();
srvs.at(0) = rts[globals::deferred->normalRoughnessRT].SRV;
uavs.at(0) = uavNormal[0].get();
uavs.at(1) = uavNormal[1].get();
uavs.at(2) = uavNormal[2].get();
uavs.at(3) = uavNormal[3].get();
uavs.at(4) = uavNormal[4].get();

context->CSSetShaderResources(0, 1, srvs.data());
context->CSSetUnorderedAccessViews(0, 5, uavs.data(), nullptr);
context->CSSetShader(prefilterNormalCompute.get(), nullptr, 0);
context->Dispatch((internalRes[0] + 15u) >> 4, (internalRes[1] + 15u) >> 4, 1);
}

// GI
{
TracyD3D11Zone(globals::state->tracyCtx, "SSGI - GI");
Expand All @@ -834,6 +863,7 @@ void ScreenSpaceGI::DrawSSGI()
srvs.at(6) = texIlY[inputGITexIdx]->srv.get();
srvs.at(7) = texIlCoCg[inputGITexIdx]->srv.get();
srvs.at(8) = texGiSpecular[inputAoTexIdx]->srv.get();
srvs.at(9) = texNormal->srv.get();

uavs.at(0) = texAo[!inputAoTexIdx]->uav.get();
uavs.at(1) = texIlY[!inputGITexIdx]->uav.get();
Expand Down
3 changes: 3 additions & 0 deletions src/Features/ScreenSpaceGI.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ struct ScreenSpaceGI : Feature
eastl::unique_ptr<Texture2D> texRadiance = nullptr;
eastl::unique_ptr<Texture2D> texRadianceTemp = nullptr;
winrt::com_ptr<ID3D11UnorderedAccessView> uavRadiance[5] = { nullptr };
eastl::unique_ptr<Texture2D> texNormal = nullptr;
winrt::com_ptr<ID3D11UnorderedAccessView> uavNormal[5] = { nullptr };
eastl::unique_ptr<Texture2D> texAccumFrames[2] = { nullptr };
eastl::unique_ptr<Texture2D> texAo[2] = { nullptr };
eastl::unique_ptr<Texture2D> texIlY[2] = { nullptr };
Expand All @@ -161,6 +163,7 @@ struct ScreenSpaceGI : Feature

winrt::com_ptr<ID3D11ComputeShader> prefilterDepthsCompute = nullptr;
winrt::com_ptr<ID3D11ComputeShader> prefilterRadianceCompute = nullptr;
winrt::com_ptr<ID3D11ComputeShader> prefilterNormalCompute = nullptr;
winrt::com_ptr<ID3D11ComputeShader> radianceDisoccCompute = nullptr;
winrt::com_ptr<ID3D11ComputeShader> giCompute = nullptr;
winrt::com_ptr<ID3D11ComputeShader> blurCompute = nullptr;
Expand Down
Loading