This patch implements blue-noise dithered sampling as described by Nathan Vegdahl (https://psychopath.io/post/2022_07_24_owen_scrambling_based_dithered_blue_noise_sampling), which in turn is based on "Screen-Space Blue-Noise Diffusion of Monte Carlo Sampling Error via Hierarchical Ordering of Pixels"(https://repository.kaust.edu.sa/items/1269ae24-2596-400b-a839-e54486033a93). The basic idea is simple: Instead of generating independent sequences for each pixel by scrambling them, we use a single sequence for the entire image, with each pixel getting one chunk of the samples. The ordering across pixels is determined by hierarchical scrambling of the pixel's position along a space-filling curve, which ends up being pretty much the same operation as already used for the underlying sequence. This results in a more high-frequency noise distribution, which appears smoother despite not being less noisy overall. The main limitation at the moment is that the improvement is only clear if the full sample amount is used per pixel, so interactive preview rendering and adaptive sampling will not receive the benefit. One exception to this is that when using the new "Automatic" setting, the first sample in interactive rendering will also be blue-noise-distributed. The sampling mode option is now exposed in the UI, with the three options being Blue Noise (the new mode), Classic (the previous Tabulated Sobol method) and the new default, Automatic (blue noise, with the additional property of ensuring the first sample is also blue-noise-distributed in interactive rendering). When debug mode is enabled, additional options appear, such as Sobol-Burley. Note that the scrambling distance option is not compatible with the blue-noise pattern. Pull Request: https://projects.blender.org/blender/blender/pulls/118479
79 lines
1.8 KiB
C
79 lines
1.8 KiB
C
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
|
|
|
#pragma once
|
|
|
|
#include "util/types.h"
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
/*
|
|
* Performs base-2 Owen scrambling on a reversed-bit unsigned integer.
|
|
*
|
|
* This is equivalent to the Laine-Karras permutation, but much higher
|
|
* quality. See https://psychopath.io/post/2021_01_30_building_a_better_lk_hash
|
|
*/
|
|
ccl_device_inline uint reversed_bit_owen(uint n, uint seed)
|
|
{
|
|
n ^= n * 0x3d20adea;
|
|
n += seed;
|
|
n *= (seed >> 16) | 1;
|
|
n ^= n * 0x05526c56;
|
|
n ^= n * 0x53a22864;
|
|
|
|
return n;
|
|
}
|
|
|
|
/*
|
|
* Performs base-4 Owen scrambling on a reversed-bit unsigned integer.
|
|
*
|
|
* See https://psychopath.io/post/2022_08_14_a_fast_hash_for_base_4_owen_scrambling
|
|
*/
|
|
|
|
ccl_device_inline uint reversed_bit_owen_base4(uint n, uint seed)
|
|
{
|
|
n ^= n * 0x3d20adea;
|
|
n ^= (n >> 1) & (n << 1) & 0x55555555;
|
|
n += seed;
|
|
n *= (seed >> 16) | 1;
|
|
n ^= (n >> 1) & (n << 1) & 0x55555555;
|
|
n ^= n * 0x05526c56;
|
|
n ^= n * 0x53a22864;
|
|
|
|
return n;
|
|
}
|
|
|
|
/*
|
|
* Performs base-2 Owen scrambling on an unsigned integer.
|
|
*/
|
|
ccl_device_inline uint nested_uniform_scramble(uint i, uint seed)
|
|
{
|
|
return reverse_integer_bits(reversed_bit_owen(reverse_integer_bits(i), seed));
|
|
}
|
|
|
|
/*
|
|
* Performs base-4 Owen scrambling on an unsigned integer.
|
|
*/
|
|
ccl_device_inline uint nested_uniform_scramble_base4(uint i, uint seed)
|
|
{
|
|
return reverse_integer_bits(reversed_bit_owen_base4(reverse_integer_bits(i), seed));
|
|
}
|
|
|
|
ccl_device_inline uint expand_bits(uint x)
|
|
{
|
|
x &= 0x0000ffff;
|
|
x = (x ^ (x << 8)) & 0x00ff00ff;
|
|
x = (x ^ (x << 4)) & 0x0f0f0f0f;
|
|
x = (x ^ (x << 2)) & 0x33333333;
|
|
x = (x ^ (x << 1)) & 0x55555555;
|
|
return x;
|
|
}
|
|
|
|
ccl_device_inline uint morton2d(uint x, uint y)
|
|
{
|
|
return (expand_bits(x) << 1) | expand_bits(y);
|
|
}
|
|
|
|
CCL_NAMESPACE_END
|