Skip to content

Commit

Permalink
chore: ssgi improvements and fixes (#341)
Browse files Browse the repository at this point in the history
* fix: fps model glow

* feat: using fastnoise in lieu of hilbert

FastNoise: https://github.com/electronicarts/fastnoise

* chore: ssgi def param and tooltip changes

* feat: half rate gi test

* feat: replace half res with half rate
  • Loading branch information
Pentalimbed authored Jul 15, 2024
1 parent ef6ff3a commit fd4f6d1
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 175 deletions.
4 changes: 2 additions & 2 deletions features/Screen Space GI/Shaders/ScreenSpaceGI/blur.cs.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ float HistoryRadiusScaling(float accumFrames)
uint eyeIndex = GetEyeIndexFromTexCoord(uv);
const float2 screenPos = ConvertFromStereoUV(uv, eyeIndex);

float depth = READ_DEPTH(srcDepth, dtid);
float depth = srcDepth[dtid];
float3 pos = ScreenToViewPosition(screenPos, depth, eyeIndex);
float3 normal = DecodeNormal(FULLRES_LOAD(srcNormal, dtid, uv, samplerLinearClamp).xy);
float3 normal = DecodeNormal(srcNormal[dtid].xy);

float4 sum = srcGI[dtid];
#ifdef TEMPORAL_DENOISER
Expand Down
12 changes: 0 additions & 12 deletions features/Screen Space GI/Shaders/ScreenSpaceGI/common.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,6 @@ SamplerState samplerLinearClamp : register(s1);

///////////////////////////////////////////////////////////////////////////////

// screenPos - normalised position in FrameDim, one eye only
// uv - normalised position in FrameDim, both eye
// texCoord - texture coordinate

#ifdef HALF_RES
# define READ_DEPTH(tex, px) tex.Load(int3(px, 1))
# define FULLRES_LOAD(tex, px, texCoord, samp) tex.SampleLevel(samp, texCoord, 0)
#else
# define READ_DEPTH(tex, px) tex[px]
# define FULLRES_LOAD(tex, px, texCoord, samp) tex[px]
#endif

///////////////////////////////////////////////////////////////////////////////

#define ISNAN(x) (!(x < 0.f || x > 0.f || x == 0.f))
Expand Down
Binary file not shown.
69 changes: 38 additions & 31 deletions features/Screen Space GI/Shaders/ScreenSpaceGI/gi.cs.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,16 @@
#include "../Common/VR.hlsli"
#include "common.hlsli"

#if USE_HALF_FLOAT_PRECISION == 0
# define PI (3.1415926535897932384626433832795)
# define HALF_PI (1.5707963267948966192313216916398)
# define RCP_PI (0.31830988618)
#else
# define PI (3.1415926535897932384626433832795)
# define HALF_PI (1.5707963267948966192313216916398)
# define RCP_PI (0.31830988618)
#endif
#define FP_Z (16.5)

#define PI (3.1415926535897932384626433832795)
#define HALF_PI (1.5707963267948966192313216916398)
#define RCP_PI (0.31830988618)

Texture2D<float> srcWorkingDepth : register(t0);
Texture2D<float4> srcNormal : register(t1);
Texture2D<float3> srcRadiance : register(t2); // maybe half-res
Texture2D<uint> srcHilbertLUT : register(t3);
Texture2D<unorm float2> srcNoise : register(t3);
Texture2D<unorm float> srcAccumFrames : register(t4); // maybe half-res
Texture2D<float4> srcPrevGI : register(t5); // maybe half-res

Expand All @@ -57,12 +53,10 @@ float GetDepthFade(float depth)
// Engine-specific screen & temporal noise loader
float2 SpatioTemporalNoise(uint2 pixCoord, uint temporalIndex) // without TAA, temporalIndex is always 0
{
float2 noise;
uint index = srcHilbertLUT.Load(uint3(pixCoord % 64, 0)).x;
index += 288 * (temporalIndex % 64); // why 288? tried out a few and that's the best so far (with XE_HILBERT_LEVEL 6U) - but there's probably better :)
// R2 sequence - see http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/
// https://www.shadertoy.com/view/mts3zN
return float2(frac(0.5 + index * float2(0.245122333753, 0.430159709002)));
// noise texture from https://github.com/electronicarts/fastnoise
// 128x128x64
uint2 noiseCoord = (pixCoord % 128) + uint2(0, (temporalIndex % 64) * 128);
return srcNoise.Load(uint3(noiseCoord, 0));
}

// HBIL pp.29
Expand Down Expand Up @@ -176,12 +170,9 @@ void CalculateGI(

float sampleOffsetLength = length(sampleOffset);
float mipLevel = clamp(log2(sampleOffsetLength) - DepthMIPSamplingOffset, 0, 5);
#ifdef HALF_RES
mipLevel = max(mipLevel, 1);
#endif

float SZ = srcWorkingDepth.SampleLevel(samplerPointClamp, sampleUV * srcScale, mipLevel);
[branch] if (SZ > DepthFadeRange.y) continue;
[branch] if (SZ > DepthFadeRange.y || SZ < FP_Z) continue;

float3 samplePos = ScreenToViewPosition(sampleScreenPos, SZ, eyeIndex);
float3 sampleDelta = samplePos - float3(pixCenterPos);
Expand Down Expand Up @@ -357,16 +348,23 @@ void CalculateGI(
const float2 srcScale = SrcFrameDim * RcpTexDim;
const float2 outScale = OutFrameDim * RcpTexDim;

float2 uv = (dtid + .5f) * RcpOutFrameDim;
uint2 pxCoord = dtid;
#if defined(HALF_RATE)
const uint halfWidth = uint(OutFrameDim.x) >> 1;
const bool useHistory = dtid.x >= halfWidth;
pxCoord.x = (pxCoord.x % halfWidth) * 2 + (dtid.y + FrameIndex + useHistory) % 2;
#endif

float2 uv = (pxCoord + .5f) * RcpOutFrameDim;
uint eyeIndex = GetEyeIndexFromTexCoord(uv);

float viewspaceZ = READ_DEPTH(srcWorkingDepth, dtid);
float viewspaceZ = srcWorkingDepth[pxCoord];

float2 normalSample = FULLRES_LOAD(srcNormal, dtid, uv * srcScale, samplerLinearClamp).xy;
float2 normalSample = srcNormal[pxCoord].xy;
float3 viewspaceNormal = DecodeNormal(normalSample);

half2 encodedWorldNormal = EncodeNormal(ViewToWorldVector(viewspaceNormal, CameraViewInverse[eyeIndex]));
outPrevGeo[dtid] = half3(viewspaceZ, encodedWorldNormal);
outPrevGeo[pxCoord] = half3(viewspaceZ, encodedWorldNormal);

// Move center pixel slightly towards camera to avoid imprecision artifacts due to depth buffer imprecision; offset depends on depth texture format used
#if USE_HALF_FLOAT_PRECISION == 1
Expand All @@ -377,25 +375,34 @@ void CalculateGI(

float4 currGIAO = float4(0, 0, 0, 1);
float3 bentNormal = viewspaceNormal;
[branch] if (viewspaceZ < DepthFadeRange.y)

bool needGI = viewspaceZ > FP_Z && viewspaceZ < DepthFadeRange.y;
#if defined(HALF_RATE)
needGI = needGI && !useHistory;
#endif
[branch] if (needGI)
CalculateGI(
dtid, uv, viewspaceZ, viewspaceNormal,
pxCoord, uv, viewspaceZ, viewspaceNormal,
currGIAO, bentNormal);

#ifdef BENT_NORMAL
outBentNormal[dtid] = EncodeNormal(bentNormal);
outBentNormal[pxCoord] = EncodeNormal(bentNormal);
#endif

#ifdef TEMPORAL_DENOISER
if (viewspaceZ < DepthFadeRange.y) {
float4 prevGIAO = srcPrevGI[dtid];
uint accumFrames = srcAccumFrames[dtid] * 255;
float lerpFactor = 0;
# if defined(HALF_RATE)
if (!useHistory)
# endif
lerpFactor = rcp(srcAccumFrames[pxCoord] * 255);

currGIAO = lerp(prevGIAO, currGIAO, rcp(accumFrames));
float4 prevGIAO = srcPrevGI[pxCoord];
currGIAO = lerp(prevGIAO, currGIAO, lerpFactor);
}
#endif

currGIAO = any(ISNAN(currGIAO)) ? float4(0, 0, 0, 1) : currGIAO;

outGI[dtid] = currGIAO;
outGI[pxCoord] = currGIAO;
}
46 changes: 0 additions & 46 deletions features/Screen Space GI/Shaders/ScreenSpaceGI/hilbert.cs.hlsl

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ RWTexture2D<float3> outRadianceDisocc : register(u0);
RWTexture2D<unorm float> outAccumFrames : register(u1);
RWTexture2D<float4> outRemappedPrevGI : register(u2);

#if (defined(GI) && defined(GI_BOUNCE)) || defined(TEMPORAL_DENOISER)
#if (defined(GI) && defined(GI_BOUNCE)) || defined(TEMPORAL_DENOISER) || defined(HALF_RATE)
# define REPROJECTION
#endif

Expand Down Expand Up @@ -46,7 +46,7 @@ void readHistory(
// bool normal_pass = normal_prod * normal_prod > NormalDisocclusion;
if (depth_pass) {
#if defined(GI) && defined(GI_BOUNCE)
prev_gi_albedo += FULLRES_LOAD(srcPrevAmbient, pixCoord, uv * srcScale, samplerLinearClamp) * bilinear_weight; // TODO better half res
prev_gi_albedo += srcPrevAmbient[pixCoord] * bilinear_weight; // TODO better half res
#endif
#ifdef TEMPORAL_DENOISER
prev_gi += srcPrevGI[pixCoord] * bilinear_weight;
Expand All @@ -67,7 +67,7 @@ void readHistory(

float2 prev_uv = uv;
#ifdef REPROJECTION
prev_uv += FULLRES_LOAD(srcMotionVec, pixCoord, uv * srcScale, samplerLinearClamp).xy;
prev_uv += srcMotionVec[pixCoord].xy;
#endif
float2 prev_screen_pos = ConvertFromStereoUV(prev_uv, eyeIndex);

Expand All @@ -76,10 +76,10 @@ void readHistory(
float accum_frames = 0;
float wsum = 0;

const float curr_depth = READ_DEPTH(srcCurrDepth, pixCoord);
const float curr_depth = srcCurrDepth[pixCoord];
#ifdef REPROJECTION
if ((curr_depth <= DepthFadeRange.y) && !(any(prev_screen_pos < 0) || any(prev_screen_pos > 1))) {
// float3 curr_normal = DecodeNormal(FULLRES_LOAD(srcCurrNormal, pixCoord, uv * srcScale, samplerLinearClamp).xy);
// float3 curr_normal = DecodeNormal(srcCurrNormal[pixCoord];
// curr_normal = ViewToWorldVector(curr_normal, CameraViewInverse[eyeIndex]);
float3 curr_pos = ScreenToViewPosition(screen_pos, curr_depth, eyeIndex);
curr_pos = ViewToWorldPosition(curr_pos, CameraViewInverse[eyeIndex]);
Expand Down Expand Up @@ -127,7 +127,7 @@ void readHistory(

half3 radiance = 0;
#ifdef GI
radiance = FULLRES_LOAD(srcDiffuse, pixCoord, uv * srcScale, samplerLinearClamp).rgb;
radiance = srcDiffuse[pixCoord].rgb;
# ifdef GI_BOUNCE
radiance += prev_gi_albedo.rgb * GIBounceFade;
# endif
Expand Down
Loading

0 comments on commit fd4f6d1

Please sign in to comment.