Blender V4.3
kernel/sample/tabulated_sobol.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
6#include "util/hash.h"
7
8#pragma once
10
13 uint dimension,
14 uint seed)
15{
16 const uint sample_count = kernel_data.integrator.tabulated_sobol_sequence_size;
17
18 /* Shuffle the pattern order and sample index to decorrelate
19 * dimensions and make the most of the finite patterns we have.
20 * The funky sample mask stuff is to ensure that we only shuffle
21 * *within* the current sample pattern, which is necessary to avoid
22 * early repeat pattern use. */
23 const uint pattern_i = hash_shuffle_uint(dimension, NUM_TAB_SOBOL_PATTERNS, seed);
24 /* sample_count should always be a power of two, so this results in a mask. */
25 const uint sample_mask = sample_count - 1;
26 const uint sample_shuffled = nested_uniform_scramble(sample,
27 hash_wang_seeded_uint(dimension, seed));
28 sample = (sample & ~sample_mask) | (sample_shuffled & sample_mask);
29
30 return ((pattern_i * sample_count) + sample) % (sample_count * NUM_TAB_SOBOL_PATTERNS);
31}
32
35 const uint rng_hash,
36 const uint dimension)
37{
38 uint seed = rng_hash;
39
40 /* Use the same sample sequence seed for all pixels when using
41 * scrambling distance. */
42 if (kernel_data.integrator.scrambling_distance < 1.0f) {
43 seed = kernel_data.integrator.seed;
44 }
45
46 /* Fetch the sample. */
47 const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed);
48 float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS);
49
50 /* Do limited Cranley-Patterson rotation when using scrambling distance. */
51 if (kernel_data.integrator.scrambling_distance < 1.0f) {
52 const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) *
53 kernel_data.integrator.scrambling_distance;
54 x += jitter_x;
55 x -= floorf(x);
56 }
57
58 return x;
59}
60
63 const uint rng_hash,
64 const uint dimension)
65{
66 uint seed = rng_hash;
67
68 /* Use the same sample sequence seed for all pixels when using
69 * scrambling distance. */
70 if (kernel_data.integrator.scrambling_distance < 1.0f) {
71 seed = kernel_data.integrator.seed;
72 }
73
74 /* Fetch the sample. */
75 const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed);
76 float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS);
77 float y = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 1);
78
79 /* Do limited Cranley-Patterson rotation when using scrambling distance. */
80 if (kernel_data.integrator.scrambling_distance < 1.0f) {
81 const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) *
82 kernel_data.integrator.scrambling_distance;
83 const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) *
84 kernel_data.integrator.scrambling_distance;
85 x += jitter_x;
86 y += jitter_y;
87 x -= floorf(x);
88 y -= floorf(y);
89 }
90
91 return make_float2(x, y);
92}
93
96 const uint rng_hash,
97 const uint dimension)
98{
99 uint seed = rng_hash;
100
101 /* Use the same sample sequence seed for all pixels when using
102 * scrambling distance. */
103 if (kernel_data.integrator.scrambling_distance < 1.0f) {
104 seed = kernel_data.integrator.seed;
105 }
106
107 /* Fetch the sample. */
108 const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed);
109 float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS);
110 float y = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 1);
111 float z = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 2);
112
113 /* Do limited Cranley-Patterson rotation when using scrambling distance. */
114 if (kernel_data.integrator.scrambling_distance < 1.0f) {
115 const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) *
116 kernel_data.integrator.scrambling_distance;
117 const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) *
118 kernel_data.integrator.scrambling_distance;
119 const float jitter_z = hash_wang_seeded_float(dimension, rng_hash ^ 0xbf604c5a) *
120 kernel_data.integrator.scrambling_distance;
121 x += jitter_x;
122 y += jitter_y;
123 z += jitter_z;
124 x -= floorf(x);
125 y -= floorf(y);
126 z -= floorf(z);
127 }
128
129 return make_float3(x, y, z);
130}
131
133 uint sample,
134 const uint rng_hash,
135 const uint dimension)
136{
137 uint seed = rng_hash;
138
139 /* Use the same sample sequence seed for all pixels when using
140 * scrambling distance. */
141 if (kernel_data.integrator.scrambling_distance < 1.0f) {
142 seed = kernel_data.integrator.seed;
143 }
144
145 /* Fetch the sample. */
146 const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed);
147 float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS);
148 float y = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 1);
149 float z = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 2);
150 float w = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 3);
151
152 /* Do limited Cranley-Patterson rotation when using scrambling distance. */
153 if (kernel_data.integrator.scrambling_distance < 1.0f) {
154 const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) *
155 kernel_data.integrator.scrambling_distance;
156 const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) *
157 kernel_data.integrator.scrambling_distance;
158 const float jitter_z = hash_wang_seeded_float(dimension, rng_hash ^ 0xbf604c5a) *
159 kernel_data.integrator.scrambling_distance;
160 const float jitter_w = hash_wang_seeded_float(dimension, rng_hash ^ 0x99634d1d) *
161 kernel_data.integrator.scrambling_distance;
162 x += jitter_x;
163 y += jitter_y;
164 z += jitter_z;
165 w += jitter_w;
166 x -= floorf(x);
167 y -= floorf(y);
168 z -= floorf(z);
169 w -= floorf(w);
170 }
171
172 return make_float4(x, y, z, w);
173}
174
unsigned int uint
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
static unsigned long seed
Definition btSoftBody.h:39
ccl_device_inline uint nested_uniform_scramble(uint i, uint seed)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_device
#define CCL_NAMESPACE_END
ccl_device_forceinline float4 make_float4(const float x, const float y, const float z, const float w)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define floorf(x)
ccl_device_forceinline float2 make_float2(const float x, const float y)
ccl_device_inline float hash_wang_seeded_float(uint i, uint seed)
Definition hash.h:462
ccl_device_inline uint hash_wang_seeded_uint(uint i, uint seed)
Definition hash.h:452
ccl_device_inline uint hash_shuffle_uint(uint i, uint length, uint seed)
Definition hash.h:486
ccl_device float3 tabulated_sobol_sample_3D(KernelGlobals kg, uint sample, const uint rng_hash, const uint dimension)
CCL_NAMESPACE_BEGIN ccl_device uint tabulated_sobol_shuffled_sample_index(KernelGlobals kg, uint sample, uint dimension, uint seed)
ccl_device float2 tabulated_sobol_sample_2D(KernelGlobals kg, uint sample, const uint rng_hash, const uint dimension)
ccl_device float4 tabulated_sobol_sample_4D(KernelGlobals kg, uint sample, const uint rng_hash, const uint dimension)
ccl_device float tabulated_sobol_sample_1D(KernelGlobals kg, uint sample, const uint rng_hash, const uint dimension)
#define NUM_TAB_SOBOL_DIMENSIONS
#define NUM_TAB_SOBOL_PATTERNS