Cycles: add Progressive Multi-Jitter sampling pattern

This sampling pattern is particularly suited to adaptive sampling, and will
be used for that upcoming feature.

Based on "Progressive Multi-Jittered Sample Sequences" by Per Christensen,
Andrew Kensler and Charlie Kilpatrick.

Ref D4686
This commit is contained in:
Stefan Werner
2020-03-02 15:12:44 +01:00
committed by Brecht Van Lommel
parent 7b8db971d4
commit 409074aae5
12 changed files with 415 additions and 11 deletions

View File

@@ -18,11 +18,14 @@
#include "render/background.h"
#include "render/integrator.h"
#include "render/film.h"
#include "render/jitter.h"
#include "render/light.h"
#include "render/scene.h"
#include "render/shader.h"
#include "render/sobol.h"
#include "kernel/kernel_types.h"
#include "util/util_foreach.h"
#include "util/util_hash.h"
@@ -78,6 +81,7 @@ NODE_DEFINE(Integrator)
static NodeEnum sampling_pattern_enum;
sampling_pattern_enum.insert("sobol", SAMPLING_PATTERN_SOBOL);
sampling_pattern_enum.insert("cmj", SAMPLING_PATTERN_CMJ);
sampling_pattern_enum.insert("pmj", SAMPLING_PATTERN_PMJ);
SOCKET_ENUM(sampling_pattern, "Sampling Pattern", sampling_pattern_enum, SAMPLING_PATTERN_SOBOL);
return type;
@@ -203,18 +207,34 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
int dimensions = PRNG_BASE_NUM + max_samples * PRNG_BOUNCE_NUM;
dimensions = min(dimensions, SOBOL_MAX_DIMENSIONS);
uint *directions = dscene->sobol_directions.alloc(SOBOL_BITS * dimensions);
if (sampling_pattern == SAMPLING_PATTERN_SOBOL) {
uint *directions = dscene->sample_pattern_lut.alloc(SOBOL_BITS * dimensions);
sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
dscene->sobol_directions.copy_to_device();
dscene->sample_pattern_lut.copy_to_device();
}
else {
constexpr int sequence_size = NUM_PMJ_SAMPLES;
constexpr int num_sequences = NUM_PMJ_PATTERNS;
float2 *directions = (float2 *)dscene->sample_pattern_lut.alloc(sequence_size * num_sequences *
2);
TaskPool pool;
for (int j = 0; j < num_sequences; ++j) {
float2 *sequence = directions + j * sequence_size;
pool.push(
function_bind(&progressive_multi_jitter_02_generate_2D, sequence, sequence_size, j));
}
pool.wait_work();
dscene->sample_pattern_lut.copy_to_device();
}
need_update = false;
}
void Integrator::device_free(Device *, DeviceScene *dscene)
{
dscene->sobol_directions.free();
dscene->sample_pattern_lut.free();
}
bool Integrator::modified(const Integrator &integrator)