Skip to content

Commit

Permalink
merian-nodes: Accum: Test stochastic bilinear filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
LDAP committed Aug 14, 2024
1 parent 968f59e commit 5173e39
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 6 deletions.
2 changes: 2 additions & 0 deletions include/merian-nodes/nodes/accumulate/accumulate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class Accumulate : public Node {

float adaptive_alpha_reduction = 0.0;
float adaptive_alpha_ipr_factor = 1.5;

uint32_t iteration = 0;
};

public:
Expand Down
25 changes: 25 additions & 0 deletions include/merian-shaders/reprojection.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,29 @@ bool reprojection_intersect_border(inout vec2 prev_pos, const vec2 mv, const vec
return false;
}

ivec2 reproject_pixel_nearest(const vec2 pixel) {
return ivec2(round(pixel));
}

// Performs stochastic bilinear interpolation when reprojecting
ivec2 reproject_pixel_stochastic(const vec2 pixel, const float random) {
const vec2 relative_pos = fract(pixel);

// (0, 0)
float bary_sum = relative_pos.x * relative_pos.y;
if (random <= bary_sum)
return ivec2(ceil(pixel));

bary_sum += relative_pos.x * (1. - relative_pos.y);
if (random <= bary_sum)
return ivec2(0, 1) * ivec2(floor(pixel)) + (1 - ivec2(0, 1)) * ivec2(ceil(pixel));

bary_sum += (1. - relative_pos.x) * relative_pos.y;
if (random <= bary_sum)
return ivec2(1, 0) * ivec2(floor(pixel)) + (1 - ivec2(1, 0)) * ivec2(ceil(pixel));

// (1, 1)
return ivec2(floor(pixel));
}

#endif
24 changes: 19 additions & 5 deletions src/merian-nodes/nodes/accumulate/accumulate.comp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#define FILTER_MODE_NEAREST 0
#define FILTER_MODE_BILINEAR 1
#define FILTER_MODE_STOCHASTIC_BILINEAR 2

layout(constant_id = 2) const uint WG_ROUNDED_IRR_SIZE_X = 1;
layout(constant_id = 3) const uint WG_ROUNDED_IRR_SIZE_Y = 1;
Expand All @@ -31,20 +32,23 @@ layout(push_constant, std140) uniform pc_t {

float adaptive_alpha_reduction;
float adaptive_alpha_ipr_factor;

uint iteration;
} pc;

#include "merian-shaders/normal_encode.glsl"
#include "merian-shaders/reprojection.glsl"
#include "merian-shaders/hash.glsl"
#include "merian-shaders/random.glsl"
#include "merian-shaders/color/colors_yuv.glsl"

void get_prev_nearest(const vec2 prev_pos,
void get_prev_nearest(const ivec2 prev_ipos,
const float linear_z,
const float vel_z,
const vec3 normal,
inout vec4 prev_irr_histlen,
inout vec2 prev_moments,
inout float sum_w) {
const ivec2 prev_ipos = ivec2(round(prev_pos));
if(any(greaterThanEqual(prev_ipos, textureSize(img_prev_accum, 0))) || any(lessThan(prev_ipos, ivec2(0))))
return;

Expand Down Expand Up @@ -180,22 +184,32 @@ void main() {
const GBuffer gbuf = gbuffer[gbuffer_index(ipos, imageSize(img_accum))];
const vec3 normal = geo_decode_normal(gbuf.enc_normal);

if (FILTER_MODE == FILTER_MODE_NEAREST)
get_prev_nearest(prev_pos,
if (FILTER_MODE == FILTER_MODE_NEAREST) {
get_prev_nearest(ivec2(round(prev_pos)),
gbuf.linear_z,
gbuf.vel_z,
normal,
prev_irr_histlen,
prev_moments,
sum_w);
else if (FILTER_MODE == FILTER_MODE_BILINEAR)
} else if (FILTER_MODE == FILTER_MODE_BILINEAR) {
get_prev_bilinear(prev_pos,
gbuf.linear_z,
gbuf.vel_z,
normal,
prev_irr_histlen,
prev_moments,
sum_w);
} else if (FILTER_MODE == FILTER_MODE_STOCHASTIC_BILINEAR) {
uint rng_state = pcg3d16(uvec3(ipos, pc.iteration));
get_prev_nearest(reproject_pixel_stochastic(prev_pos, XorShift32(rng_state)),
gbuf.linear_z,
gbuf.vel_z,
normal,
prev_irr_histlen,
prev_moments,
sum_w);
}

if (EXTENDED_SEARCH) {
if (sum_w <= 0.01) {
Expand Down
4 changes: 3 additions & 1 deletion src/merian-nodes/nodes/accumulate/accumulate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ void Accumulate::process(GraphRun& run,
const vk::CommandBuffer& cmd,
const DescriptorSetHandle& descriptor_set,
[[maybe_unused]] const NodeIO& io) {
accumulate_pc.iteration = run.get_total_iteration();

if (accumulate_pc.firefly_filter_enable || accumulate_pc.adaptive_alpha_reduction > 0.0f) {
MERIAN_PROFILE_SCOPE_GPU(run.get_profiler(), cmd, "compute percentiles");
Expand Down Expand Up @@ -183,7 +184,8 @@ Accumulate::NodeStatusFlags Accumulate::properties(Properties& config) {
accumulate_pc.normal_reject_cos = glm::cos(angle);
config.config_percent("depth threshold", accumulate_pc.depth_reject_percent,
"Reject points with depths farther apart (relative to the max)");
needs_rebuild |= config.config_options("filter mode", filter_mode, {"nearest", "linear"});
needs_rebuild |= config.config_options("filter mode", filter_mode,
{"nearest", "bilinear", "stochastic bilinear"});
needs_rebuild |=
config.config_bool("extended search", extended_search,
"search in a 3x3 radius with weakened rejection thresholds for valid "
Expand Down

0 comments on commit 5173e39

Please sign in to comment.