Skip to content

Commit

Permalink
Fixes and improvements (#43)
Browse files Browse the repository at this point in the history
* Reactivated hardware raytracing

* Fixed temporal filter for reflections

* Fixed some AO/SSGI issues

* Fixed another SSGI issue
  • Loading branch information
tippesi committed Jan 9, 2024
1 parent 9893770 commit 3e73932
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 51 deletions.
17 changes: 12 additions & 5 deletions data/shader/deferred/indirect.csh
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ float UpsampleAo2x(float referenceDepth) {

float invocationDepths[9];

referenceDepth = ConvertDepthToViewSpaceDepth(referenceDepth);

for (uint i = 0; i < 9; i++) {
int sharedMemoryOffset = Flatten2D(pixel + offsets[i], unflattenedDepthDataSize);
invocationDepths[i] = depths[sharedMemoryOffset];
Expand Down Expand Up @@ -222,19 +224,24 @@ void main() {
indirectSpecular *= EvaluateIndirectSpecularBRDF(surface);
indirect = (indirectDiffuse + indirectSpecular) * surface.material.ao;

#ifdef SSGI
vec4 ssgi = UpsampleGi2x(depth, texCoord);
#endif

// This normally only accounts for diffuse occlusion, we need seperate terms
// for diffuse and specular.
#ifdef AO
float occlusionFactor = Uniforms.aoEnabled > 0 ? Uniforms.aoDownsampled2x > 0 ?
UpsampleAo2x(depth) : texture(aoTexture, texCoord).r : 1.0;
#ifdef SSGI
vec4 ssgi = UpsampleGi2x(depth, texCoord);
occlusionFactor = ssgi.a;
#endif

indirect *= vec3(pow(occlusionFactor, Uniforms.aoStrength));
#endif
#ifdef SSGI
indirect += EvaluateIndirectDiffuseBRDF(surface) * ssgi.rgb;
// Only apply SSGI ao if normal AO is turned off
#ifndef AO
indirect *= vec3(pow(ssgi.a, Uniforms.aoStrength));
#endif
indirect += EvaluateIndirectDiffuseBRDF(surface) * ssgi.rgb;
#endif

}
Expand Down
100 changes: 61 additions & 39 deletions data/shader/reflection/temporal.csh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//#define BICUBIC_FILTER

#include <../common/utility.hsh>
#include <../common/convert.hsh>
#include <../common/PI.hsh>
Expand Down Expand Up @@ -221,12 +223,37 @@ bool SampleHistory(ivec2 pixel, vec2 historyPixel, out vec4 history, out vec4 hi
}
void SampleCatmullRom(ivec2 pixel, vec2 uv, out vec4 history) {
float IsHistoryPixelValid(ivec2 pixel, float linearDepth, vec3 normal) {
float confidence = 1.0;
vec3 historyNormal = DecodeNormal(texelFetch(historyNormalTexture, pixel, 0).rg);
confidence *= pow(abs(dot(historyNormal, normal)), 16.0);
float depthPhi = max(1.0, abs(0.25 * linearDepth));
float historyDepth = texelFetch(historyDepthTexture, pixel, 0).r;
float historyLinearDepth = historyDepth;
confidence *= min(1.0 , exp(-abs(linearDepth - historyLinearDepth)));
return confidence > 0.1 ? 1.0 : 0.0;
}
vec4 GetCatmullRomSample(ivec2 pixel, inout float weight, float linearDepth, vec3 normal) {
pixel = clamp(pixel, ivec2(0), ivec2(imageSize(resolveImage) - 1));
weight *= IsHistoryPixelValid(pixel, linearDepth, normal);
return texelFetch(historyTexture, pixel, 0) * weight;
}
bool SampleCatmullRom(ivec2 pixel, vec2 uv, out vec4 history) {
vec3 normal = DecodeNormal(texelFetch(normalTexture, pixel, 0).rg);
float depth = texelFetch(depthTexture, pixel, 0).r;
// http://advances.realtimerendering.com/s2016/Filmic%20SMAA%20v7.pptx
// Credit: Jorge Jimenez (SIGGRAPH 2016)
// Ignores the 4 corners of the 4x4 grid
// Learn more: http://vec3.ca/bicubic-filtering-in-fewer-taps/
vec2 position = uv * resolution;
vec2 center = floor(position - 0.5) + 0.5;
Expand All @@ -239,45 +266,35 @@ void SampleCatmullRom(ivec2 pixel, vec2 uv, out vec4 history) {
vec2 w3 = 0.5 * (f3 - f2);
vec2 w2 = 1.0 - w0 - w1 - w3;
vec2 w12 = w1 + w2;
vec2 tc0 = (center - 1.0) * invResolution;
vec2 tc12 = (center + w2 / w12) * invResolution;
vec2 tc3 = (center + 2.0) * invResolution;
vec2 uv0 = clamp(vec2(tc12.x, tc0.y), vec2(0.0), vec2(1.0)) * resolution - vec2(0.5);
vec2 uv1 = clamp(vec2(tc0.x, tc12.y), vec2(0.0), vec2(1.0)) * resolution - vec2(0.5);
vec2 uv2 = clamp(vec2(tc12.x, tc12.y), vec2(0.0), vec2(1.0)) * resolution - vec2(0.5);
vec2 uv3 = clamp(vec2(tc3.x, tc12.y), vec2(0.0), vec2(1.0)) * resolution - vec2(0.5);
vec2 uv4 = clamp(vec2(tc12.x, tc3.y), vec2(0.0), vec2(1.0)) * resolution - vec2(0.5);
ivec2 uv0 = ivec2(center - 1.0);
ivec2 uv1 = ivec2(center);
ivec2 uv2 = ivec2(center + 1.0);
ivec2 uv3 = ivec2(center + 2.0);
float weight0 = w12.x * w0.y;
float weight1 = w0.x * w12.y;
float weight2 = w12.x * w12.y;
float weight3 = w3.x * w12.y;
float weight4 = w12.x * w3.y;
vec4 sample0, sample1, sample2, sample3, sample4;
vec4 moments0, moments1, moments2, moments3, moments4;
ivec2 uvs[4] = { uv0, uv1, uv2, uv3 };
vec2 weights[4] = { w0, w1, w2, w3 };
SampleHistory(pixel, uv0, sample0, moments0);
SampleHistory(pixel, uv1, sample1, moments1);
SampleHistory(pixel, uv2, sample2, moments2);
SampleHistory(pixel, uv3, sample3, moments3);
SampleHistory(pixel, uv4, sample4, moments4);
history = vec4(0.0);
sample0 *= weight0;
sample1 *= weight1;
sample2 *= weight2;
sample3 *= weight3;
sample4 *= weight4;
float totalWeight = 0.0;
float totalWeight = weight0 + weight1 +
weight2 + weight3 + weight4;
for (int x = 0; x <= 3; x++) {
for (int y = 0; y <= 3; y++) {
float weight = weights[x].x * weights[y].y;
ivec2 uv = ivec2(uvs[x].x, uvs[y].y);
history = sample0 + sample1 +
sample2 + sample3 + sample4;
history += GetCatmullRomSample(uv, weight, depth, normal);
totalWeight += weight;
}
}
if (totalWeight > 0.5) {
history /= totalWeight;
return true;
}
return false;
}
void ComputeVarianceMinMax(out vec3 mean, out vec3 std) {
Expand Down Expand Up @@ -341,7 +358,12 @@ void main() {
vec4 historyMoments;
valid = SampleHistory(pixel, historyPixel, history, historyMoments);
SampleCatmullRom(pixel, uv, history);
#ifdef BICUBIC_FILTER
// This should be implemented more efficiently, see
vec4 catmullRomHistory;
bool success = SampleCatmullRom(pixel, historyPixel, catmullRomHistory);
history = success && valid ? catmullRomHistory : history;
#endif
vec3 historyColor = history.rgb;
vec3 currentColor = texelFetch(currentTexture, pixel, 0).rgb;
Expand Down
2 changes: 2 additions & 0 deletions src/demo/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ void App::LoadContent() {

scene->ao = Atlas::CreateRef<Atlas::Lighting::AO>(16);
scene->ao->rt = true;
// Use SSGI by default
scene->ao->enable = false;
scene->reflection = Atlas::CreateRef<Atlas::Lighting::Reflection>(1);
scene->reflection->useShadowMap = true;

Expand Down
2 changes: 1 addition & 1 deletion src/engine/graphics/GraphicsDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ namespace Atlas {
featureBuilder.Append(rtPipelineFeature);
featureBuilder.Append(rayQueryFeature);

support.hardwareRayTracing = false;
support.hardwareRayTracing = true;
}

if (supportedExtensions.contains(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME)) {
Expand Down
9 changes: 3 additions & 6 deletions src/engine/renderer/IndirectLightRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ namespace Atlas {
auto reflectionEnabled = reflection && reflection->enable && rtDataValid;
auto aoEnabled = ao && ao->enable && (!ao->rt || rtDataValid);
auto ssgiEnabled = ssgi && ssgi->enable && (!ssgi->rt || rtDataValid);

bool ssgiAo = ssgi && ssgi->enable && ssgi->enableAo;
aoEnabled |= ssgiAo;

bool ssgiAo = ssgi && ssgi->enable && ssgi->enableAo;

pipelineConfig.ManageMacro("DDGI", ddgiEnabled);
pipelineConfig.ManageMacro("REFLECTION", reflectionEnabled);
Expand All @@ -56,11 +53,11 @@ namespace Atlas {
}

auto uniforms = Uniforms{
.aoEnabled = aoEnabled ? 1 : 0,
.aoEnabled = aoEnabled || ssgiAo ? 1 : 0,
.aoDownsampled2x = ssgiAo ? target->GetGIResolution() == RenderResolution::HALF_RES :
target->GetAOResolution() == RenderResolution::HALF_RES,
.reflectionEnabled = reflectionEnabled ? 1 : 0,
.aoStrength = aoEnabled ? (ssgiAo ? ssgi->aoStrength / sqrt(ssgi->radius) : ao->strength) : 1.0f,
.aoStrength = aoEnabled || ssgiAo ? (aoEnabled ? ao->strength : ssgi->aoStrength / sqrt(ssgi->radius)) : 1.0f,
.specularProbeMipLevels = int32_t(scene->sky.GetProbe() ? scene->sky.GetProbe()->cubemap.image->mipLevels : 1)
};
uniformBuffer.SetData(&uniforms, 0);
Expand Down

0 comments on commit 3e73932

Please sign in to comment.