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

Feature/rt fx #18

Merged
merged 21 commits into from
Nov 19, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Improved reflection filtering
- Better downsampling
- Improved shader macro handling
- Demo app has material edit now
  • Loading branch information
tippesi committed Nov 6, 2022
commit 0352b7fa9d582a1a1def7e5e92e48c4d25505e62
Binary file added data/noise.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions data/shader/ao/rtao.csh
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ void main() {
ray.hitID = -1;
ray.hitDistance = 0.0;

HitClosest(ray, 0.0, radius);
bool hit = HitAny(ray, 0.0, radius);

ao += ray.hitID >= 0 ? saturate(radius - sqr(ray.hitDistance)) : 0.0;
ao += hit ? 1.0 : 0.0;
}

float result = pow(1.0 - (ao / float(sampleCount)), 1.0);
Expand Down
2 changes: 1 addition & 1 deletion data/shader/bilateralBlur.csh
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ void main() {
ivec2 pixel = offset + ivec2(gl_LocalInvocationID);

#ifdef BLUR_RGB
imageStore(outputImage, pixel, vec4(result / totalWeight, 0.0));
imageStore(outputImage, pixel, vec4(center, 0.0));
#else
imageStore(outputImage, pixel, vec4(result / totalWeight));
#endif
Expand Down
4 changes: 2 additions & 2 deletions data/shader/ddgi/ddgi.hsh
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#define PROBE_STATE_ACTIVE 1
#define PROBE_STATE_INACTIVE 2

layout(binding = 12) uniform sampler2DArray irradianceVolume;
layout(binding = 13) uniform sampler2DArray momentsVolume;
layout(binding = 24) uniform sampler2DArray irradianceVolume;
layout(binding = 25) uniform sampler2DArray momentsVolume;

layout(std430, binding = 9) buffer ProbeStates {
vec4 probeStates[];
Expand Down
2 changes: 1 addition & 1 deletion data/shader/ddgi/probeState.csh
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void main() {
probeState = PROBE_STATE_ACTIVE;
}

probeState = PROBE_STATE_ACTIVE;
//probeState = PROBE_STATE_ACTIVE;

probeStates[baseIdx].x = uintBitsToFloat(probeState);
probeStates[baseIdx].y = temporalPercentageBackface;
Expand Down
23 changes: 22 additions & 1 deletion data/shader/deferred/indirect.csh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ uniform bool reflectionEnabled = true;
// (localSize / 2 + 2)^2
shared float depths[36];
shared float aos[36];
shared vec3 reflections[36];

const uint depthDataSize = (gl_WorkGroupSize.x / 2 + 2) * (gl_WorkGroupSize.y / 2 + 2);
const ivec2 unflattenedDepthDataSize = ivec2(gl_WorkGroupSize) / 2 + 2;
Expand All @@ -36,6 +37,7 @@ void LoadGroupSharedData() {
offset = clamp(offset, ivec2(0), textureSize(lowResDepthTexture, 0));
depths[gl_LocalInvocationIndex] = texelFetch(lowResDepthTexture, offset, 0).r;
aos[gl_LocalInvocationIndex] = texelFetch(aoTexture, offset, 0).r;
reflections[gl_LocalInvocationIndex] = texelFetch(reflectionTexture, offset, 0).rgb;
}

barrier();
Expand Down Expand Up @@ -87,6 +89,24 @@ float UpsampleAo2x(float referenceDepth) {

}

vec3 UpsampleReflection2x(float referenceDepth) {

ivec2 pixel = ivec2(gl_LocalInvocationID) / 2 + ivec2(1);

float invocationDepths[9];

for (uint i = 0; i < 9; i++) {
int sharedMemoryOffset = Flatten2D(pixel + offsets[i], unflattenedDepthDataSize);
invocationDepths[i] = depths[sharedMemoryOffset];
}

int idx = NearestDepth(referenceDepth, invocationDepths);
int offset = Flatten2D(pixel + offsets[idx], unflattenedDepthDataSize);

return reflections[offset];

}

void main() {

if (aoDownsampled2x) LoadGroupSharedData();
Expand Down Expand Up @@ -126,9 +146,10 @@ void main() {
// We multiply by local sky visibility because the reflection probe only includes the sky
//vec3 indirectSpecular = prefilteredSpecular * EvaluateIndirectSpecularBRDF(surface)
// * prefilteredDiffuseLocal.a;
vec3 indirectSpecular = reflectionEnabled ? texture(reflectionTexture, texCoord).rgb * EvaluateIndirectSpecularBRDF(surface)
vec3 indirectSpecular = reflectionEnabled ? true ? UpsampleReflection2x(depth) : texture(reflectionTexture, texCoord).rgb
: vec3(0.0);

indirectSpecular *= EvaluateIndirectSpecularBRDF(surface);
vec3 indirect = (indirectDiffuse + indirectSpecular) * surface.material.ao * indirectStrength;

// This normally only accounts for diffuse occlusion, we need seperate terms
Expand Down
39 changes: 31 additions & 8 deletions data/shader/downsampleGBuffer2x.csh
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ layout (local_size_x = 8, local_size_y = 8) in;

layout (binding = 0) uniform sampler2D depthIn;
layout (binding = 1) uniform sampler2D normalIn;
layout (binding = 2) uniform sampler2D roughnessMetallicAoIn;
layout (binding = 3) writeonly uniform image2D depthOut;
layout (binding = 4) writeonly uniform image2D normalOut;
layout (binding = 5) writeonly uniform image2D roughnessMetallicAoOut;
layout (binding = 6) writeonly uniform iimage2D offsetOut;
layout (binding = 2) uniform sampler2D geometryNormalIn;
layout (binding = 3) uniform sampler2D roughnessMetallicAoIn;
layout (binding = 4) uniform sampler2D velocityIn;

layout (binding = 0) writeonly uniform image2D depthOut;
layout (binding = 1) writeonly uniform image2D normalOut;
layout (binding = 2) writeonly uniform image2D geometryNormalOut;
layout (binding = 3) writeonly uniform image2D roughnessMetallicAoOut;
layout (binding = 4) writeonly uniform image2D velocityOut;
layout (binding = 5) writeonly uniform iimage2D offsetOut;

float Checkerboard(ivec2 coord) {

Expand Down Expand Up @@ -55,7 +60,7 @@ int MaxDepth(vec4 depthVec, out float maxDepth) {

int CheckerboardDepth(vec4 depthVec, ivec2 coord, out float depth) {

float minmax = Checkerboard(coord);
float minmax = 0.0;

float maxDepth;
int maxIdx = MaxDepth(depthVec, maxDepth);
Expand All @@ -81,8 +86,8 @@ void main() {
float depth11 = texelFetch(depthIn, coord * 2 + ivec2(1, 1), 0).r;

vec4 depthVec = vec4(depth00, depth10, depth01, depth11);
float depth;
int depthIdx = CheckerboardDepth(depthVec, coord, depth);
float depth = depthVec[0];
int depthIdx = 0;
imageStore(depthOut, coord, vec4(depth, 0.0, 0.0, 1.0));

#ifndef DEPTH_ONLY
Expand All @@ -95,6 +100,15 @@ void main() {
(depthIdx < 3 ? normal01 : normal11);
imageStore(normalOut, coord, vec4(normal, 1.0));

vec3 geometryNormal00 = texelFetch(geometryNormalIn, coord * 2 + ivec2(0, 0), 0).rgb;
vec3 geometryNormal10 = texelFetch(geometryNormalIn, coord * 2 + ivec2(1, 0), 0).rgb;
vec3 geometryNormal01 = texelFetch(geometryNormalIn, coord * 2 + ivec2(0, 1), 0).rgb;
vec3 geometryNormal11 = texelFetch(geometryNormalIn, coord * 2 + ivec2(1, 1), 0).rgb;

vec3 geometryNormal = depthIdx < 2 ? (depthIdx < 1 ? geometryNormal00 : geometryNormal10) :
(depthIdx < 3 ? geometryNormal01 : geometryNormal11);
imageStore(geometryNormalOut, coord, vec4(geometryNormal, 1.0));

vec3 roughnessMetallicAo00 = texelFetch(roughnessMetallicAoIn, coord * 2 + ivec2(0, 0), 0).rgb;
vec3 roughnessMetallicAo10 = texelFetch(roughnessMetallicAoIn, coord * 2 + ivec2(1, 0), 0).rgb;
vec3 roughnessMetallicAo01 = texelFetch(roughnessMetallicAoIn, coord * 2 + ivec2(0, 1), 0).rgb;
Expand All @@ -104,6 +118,15 @@ void main() {
(depthIdx < 3 ? roughnessMetallicAo01 : roughnessMetallicAo11);
imageStore(roughnessMetallicAoOut, coord, vec4(roughnessMetallicAo, 1.0));

vec2 velocity00 = texelFetch(velocityIn, coord * 2 + ivec2(0, 0), 0).rg;
vec2 velocity10 = texelFetch(velocityIn, coord * 2 + ivec2(1, 0), 0).rg;
vec2 velocity01 = texelFetch(velocityIn, coord * 2 + ivec2(0, 1), 0).rg;
vec2 velocity11 = texelFetch(velocityIn, coord * 2 + ivec2(1, 1), 0).rg;

vec2 velocity = depthIdx < 2 ? (depthIdx < 1 ? velocity00 : velocity10) :
(depthIdx < 3 ? velocity01 : velocity11);
imageStore(velocityOut, coord, vec4(velocity, 0.0, 0.0));

imageStore(offsetOut, coord, ivec4(depthIdx, 0, 0, 0));
#endif

Expand Down
58 changes: 33 additions & 25 deletions data/shader/reflection/rtreflection.csh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <../brdf/importanceSample.hsh>
#include <../brdf/surface.hsh>

#include <../ddgi/ddgi.hsh>

layout (local_size_x = 8, local_size_y = 4) in;

layout (binding = 4, rgba16f) writeonly uniform image2D rtrImage;
Expand All @@ -32,13 +34,14 @@ const ivec2 offsets[4] = ivec2[4](

uniform int sampleCount;
uniform float radianceLimit;
uniform bool useShadowMap;

uniform mat4 pMatrix;
uniform mat4 ivMatrix;

uniform ivec2 resolution;
uniform float frameSeed;
uniform uint frameSeed;

uniform vec2 jitter;

vec3 EvaluateHit(inout Ray ray);
vec3 EvaluateDirectLight(Surface surface);
Expand All @@ -50,6 +53,7 @@ void main() {
int(gl_GlobalInvocationID.y) < resolution.y) {

ivec2 pixel = ivec2(gl_GlobalInvocationID.xy);

vec2 texCoord = (vec2(pixel) + vec2(0.5)) / vec2(resolution);

int offsetIdx = texelFetch(offsetTexture, pixel, 0).r;
Expand All @@ -62,7 +66,11 @@ void main() {
vec3 worldPos = vec3(ivMatrix * vec4(viewPos, 1.0));
vec3 viewVec = vec3(ivMatrix * vec4(viewPos, 0.0));
vec3 worldNorm = normalize(vec3(ivMatrix * vec4(2.0 * textureLod(normalTexture, texCoord, 0).rgb - 1.0, 0.0)));
vec3 randomVec = normalize(vec3(2.0 * texelFetch(randomTexture, pixel % ivec2(2), 0).xy - 1.0, 0.0));

ivec2 noiseOffset = Unflatten2D(int(frameSeed), ivec2(16)) * ivec2(8);
vec2 blueNoiseVec = texelFetch(randomTexture, (pixel + noiseOffset) % ivec2(128), 0).xy * 256.0;
blueNoiseVec = clamp(blueNoiseVec, 0.0, 255.0);
blueNoiseVec = (blueNoiseVec + 0.5) / 256.0;

uint materialIdx = texelFetch(materialIdxTexture, pixel * 2 + offset, 0).r;
Material material = UnpackMaterial(materialIdx);
Expand All @@ -74,23 +82,15 @@ void main() {

if (material.roughness < 0.9) {

float raySeed = float(pixel.x + pixel.y * resolution.x) * 2 * float(sampleCount);
float curSeed = float(frameSeed);

for (uint i = 0; i < sampleCount; i++) {
Ray ray;

float u0 = random(raySeed, curSeed);
float u1 = random(raySeed, curSeed);

float pdf;
ImportanceSampleGGX(vec2(u0, u1), worldNorm, normalize(-viewVec), sqr(material.roughness),
ImportanceSampleGGX(blueNoiseVec, worldNorm, normalize(-viewVec), sqr(material.roughness),
ray.direction, pdf);


if (pdf == 0.0) {
//reflection += vec3(1.0, 0.0, 0.0);
//continue;
if (pdf <= 0.0) {
continue;
}

ray.inverseDirection = 1.0 / ray.direction;
Expand All @@ -102,13 +102,19 @@ void main() {
HitClosest(ray, 0.0, INF);

reflection += min(EvaluateHit(ray), vec3(radianceLimit));

/*
Triangle tri = UnpackTriangle(triangles[ray.hitID]);
Surface surface = GetSurfaceParameters(tri, ray, false);
reflection += min(surface.material.baseColor, vec3(radianceLimit));
*/
}

reflection /= float(sampleCount);

}

imageStore(rtrImage, pixel, vec4(reflection, 0.0));
imageStore(rtrImage, pixel, vec4(reflection, 1.0));
}

}
Expand All @@ -133,10 +139,12 @@ vec3 EvaluateHit(inout Ray ray) {
// Evaluate direct light
radiance += EvaluateDirectLight(surface);

// Need to sample the volume later for infinite bounces:
//vec3 indirect = EvaluateIndirectDiffuseBRDF(surface) *
// GetLocalIrradiance(surface.P, surface.V, surface.N).rgb;
//radiance += IsInsideVolume(surface.P) ? indirect : vec3(0.0);
// Evaluate indirect lighting
#ifdef GI
vec3 indirect = EvaluateIndirectDiffuseBRDF(surface) *
GetLocalIrradiance(surface.P, surface.V, surface.N).rgb;
radiance += IsInsideVolume(surface.P) ? indirect : vec3(0.0);
#endif
return radiance;

}
Expand All @@ -146,7 +154,7 @@ vec3 EvaluateDirectLight(Surface surface) {
if (GetLightCount() == 0)
return vec3(0.0);

float curSeed = frameSeed;
float curSeed = float(frameSeed) / 255.0;
float raySeed = float(gl_GlobalInvocationID.x);

float lightPdf;
Expand All @@ -163,12 +171,12 @@ vec3 EvaluateDirectLight(Surface surface) {
// Check for visibilty. This is important to get an
// estimate of the solid angle of the light from point P
// on the surface.
if (useShadowMap) {
#ifdef USE_SHADOW_MAP

}
else {
radiance *= CheckVisibility(surface, lightDistance) ? 1.0 : 0.0;
}
#else
radiance *= CheckVisibility(surface, lightDistance) ? 1.0 : 0.0;
#endif

return reflectance * radiance * surface.NdotL / lightPdf;

}
Expand Down
Loading