Skip to content

Commit

Permalink
vk: rt: parametrize different light channels differently in denoiser
Browse files Browse the repository at this point in the history
  • Loading branch information
w23 committed Jan 29, 2024
1 parent 5d6c1d4 commit a56e6a4
Showing 1 changed file with 116 additions and 49 deletions.
165 changes: 116 additions & 49 deletions ref/vk/shaders/denoiser.comp
Original file line number Diff line number Diff line change
Expand Up @@ -148,69 +148,136 @@ Components boxBlurSamples(ivec2 res, ivec2 pix) {

// https://jo.dreggn.org/home/2010_atrous.pdf
// https://www.shadertoy.com/view/ldKBzG
const int a_trous_width = 2;
const float kATrousKernel[5] = { 1./16., 1./4., 3./8., 1./4., 1./16. };
Components blurATrous(const ivec2 res, const ivec2 pix, vec3 pos, vec3 shading_normal, vec3 geometry_normal) {
Components c;
c.direct_diffuse = c.direct_specular = c.indirect_diffuse = c.indirect_specular = vec3(0.);
#define ATROUS_KERNEL_WIDTH 5
#define ATROUS_KERNEL_HALF 2
const float kATrousKernel[ATROUS_KERNEL_WIDTH] = { 1./16., 1./4., 3./8., 1./4., 1./16. };

const float sn_phi = .5;
const float p_phi = 10.;
const float step_width = 1.;
float aTrousSampleWeigth(const ivec2 res, const ivec2 pix, vec3 pos, vec3 shading_normal, ivec2 offset, int step_width, float phi_normal, float phi_pos, out ivec2 p) {
const float x_kernel = kATrousKernel[offset.x];
const float y_kernel = kATrousKernel[offset.y];

const ivec2 res_scaled = res / INDIRECT_SCALE;
const float inv_step_width_sq = 1. / float(step_width * step_width);
p = pix + (offset - ivec2(ATROUS_KERNEL_HALF)) * step_width;

float weight_total = 0.;
const int offset_scale = 3;
for (int x = -a_trous_width; x <= a_trous_width; ++x) {
const float x_kernel = kATrousKernel[x+a_trous_width];
for (int y = -a_trous_width; y <= a_trous_width; ++y) {
const float y_kernel = kATrousKernel[y+a_trous_width];
const ivec2 p = pix + ivec2(x, y) * offset_scale;
if (any(greaterThanEqual(p, res)) || any(lessThan(p, ivec2(0)))) {
return 0.;
}

if (any(greaterThanEqual(p, res)) || any(lessThan(p, ivec2(0)))) {
continue;
}
// Weight normals
vec3 sample_geometry_normal, sample_shading_normal;
readNormals(p, sample_geometry_normal, sample_shading_normal);

// Weight normals
vec3 sample_geometry_normal, sample_shading_normal;
readNormals(p, sample_geometry_normal, sample_shading_normal);
// TODO should we go geometry_normal too?
const vec3 sn_diff = sample_shading_normal - shading_normal;
const float sn_dist2 = max(dot(sn_diff,sn_diff)/(step_width * step_width), 0.);
const float weight_sn = min(exp(-(sn_dist2)/sn_phi), 1.0);
// TODO should we go geometry_normal too?
const vec3 sn_diff = sample_shading_normal - shading_normal;
const float sn_dist2 = max(dot(sn_diff,sn_diff) * inv_step_width_sq, 0.);
const float weight_sn = min(exp(-(sn_dist2)/phi_normal), 1.0);

// Weight positions
const vec3 sample_position = imageLoad(position_t, p).xyz;
const vec3 p_diff = sample_position - pos;
const float p_dist2 = dot(p_diff, p_diff);
const float weight_pos = min(exp(-(p_dist2)/p_phi),1.0);
// Weight positions
const vec3 sample_position = imageLoad(position_t, p).xyz;
const vec3 p_diff = sample_position - pos;
//Original paper: const float p_dist2 = dot(p_diff, p_diff);
const float p_dist2 = max(dot(p_diff,p_diff) * inv_step_width_sq, 0.);
const float weight_pos = min(exp(-(p_dist2)/phi_pos),1.0);

const float weight = (weight_pos * weight_sn) * x_kernel * y_kernel;
return weight;
}

Components blurATrous(const ivec2 res, const ivec2 pix, vec3 pos, vec3 shading_normal, vec3 geometry_normal) {
Components c;
c.direct_diffuse = c.direct_specular = c.indirect_diffuse = c.indirect_specular = vec3(0.);

const float weight = (weight_pos * weight_sn) * x_kernel * y_kernel;
weight_total += weight;
float weight_total_diffuse = 0.;
float weight_total_specular = 0.;
float weight_total_indirect_diffuse = 0.;
float weight_total_indirect_specular = 0.;
const ivec2 res_scaled = res / INDIRECT_SCALE;
for (int x = 0; x <= ATROUS_KERNEL_WIDTH; ++x) {
for (int y = 0; y <= ATROUS_KERNEL_WIDTH; ++y) {
const ivec2 offset = ivec2(x, y);
// 1. Direct diffuse
{
const float sn_phi = .5;
const float p_phi = 2.;
const int step_width = 3;
ivec2 p;
const float weight = aTrousSampleWeigth(
res, pix, pos, shading_normal, offset, step_width, sn_phi, p_phi, p);

if (weight > 0.) {
weight_total_diffuse += weight;
c.direct_diffuse +=
(imageLoad(light_poly_diffuse, p).rgb
+imageLoad(light_point_diffuse, p).rgb) * weight;
}
}

c.direct_diffuse +=
(imageLoad(light_poly_diffuse, p).rgb
+imageLoad(light_point_diffuse, p).rgb) * weight;
// 2. Direct specular
{
const float sn_phi = .5;
const float p_phi = 1.;
const int step_width = 1;
ivec2 p;
const float weight = aTrousSampleWeigth(
res, pix, pos, shading_normal, offset, step_width, sn_phi, p_phi, p);

if (weight > 0.) {
weight_total_specular += weight;
c.direct_specular +=
(imageLoad(light_poly_specular, p).rgb
+imageLoad(light_point_specular, p).rgb) * weight;
}
}

c.direct_specular +=
(imageLoad(light_poly_specular, p).rgb
+imageLoad(light_point_specular, p).rgb) * weight;
// 3. Indirect diffuse
{
const float sn_phi = .5;
const float p_phi = 3.;
const int step_width = 3;
ivec2 p;
const float weight = aTrousSampleWeigth(
res, pix, pos, shading_normal, offset, step_width, sn_phi, p_phi, p);

if (weight > 0.) {
const ivec2 p_indirect = p / INDIRECT_SCALE;
const bool do_indirect = all(lessThan(p_indirect, res_scaled)) && all(greaterThanEqual(p_indirect, ivec2(0)));
if (do_indirect) {
weight_total_indirect_diffuse += weight;
c.indirect_diffuse += imageLoad(indirect_diffuse, p_indirect).rgb * weight;
}
}
}

const ivec2 p_indirect = p / INDIRECT_SCALE;
const bool do_indirect = all(lessThan(p_indirect, res_scaled)) && all(greaterThanEqual(p_indirect, ivec2(0)));
if (do_indirect) {
c.indirect_diffuse += imageLoad(indirect_diffuse, p_indirect).rgb * weight;
c.indirect_specular += imageLoad(indirect_specular, p_indirect).rgb * weight;
// 4. Indirect specular
{
const float sn_phi = .5;
const float p_phi = 1.;
const int step_width = 1;
ivec2 p;
const float weight = aTrousSampleWeigth(
res, pix, pos, shading_normal, offset, step_width, sn_phi, p_phi, p);

if (weight > 0.) {
const ivec2 p_indirect = p / INDIRECT_SCALE;
const bool do_indirect = all(lessThan(p_indirect, res_scaled)) && all(greaterThanEqual(p_indirect, ivec2(0)));
if (do_indirect) {
weight_total_indirect_specular += weight;
c.indirect_specular += imageLoad(indirect_specular, p_indirect).rgb * weight;
}
}
}
} // for y
} // for x

const float one_over_weight = 1. / weight_total;
c.direct_diffuse *= one_over_weight;
c.indirect_diffuse *= one_over_weight;
c.direct_specular *= one_over_weight;
c.indirect_specular *= one_over_weight;
const float one_over_weight_diffuse = 1. / weight_total_diffuse;
const float one_over_weight_specular = 1. / weight_total_specular;
const float one_over_weight_indirect_diffuse = 1. / weight_total_indirect_diffuse;
const float one_over_weight_indirect_specular = 1. / weight_total_indirect_specular;
c.direct_diffuse *= one_over_weight_diffuse;
c.direct_specular *= one_over_weight_specular;

c.indirect_diffuse *= one_over_weight_indirect_diffuse;
c.indirect_specular *= one_over_weight_indirect_specular;
return c;
}

Expand Down

0 comments on commit a56e6a4

Please sign in to comment.