Blender V4.3
path_state.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
8
10
11/* Initialize queues, so that the this path is considered terminated.
12 * Used for early outputs in the camera ray initialization, as well as initialization of split
13 * states for shadow catcher. */
15{
16 INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = 0;
17#ifndef __KERNEL_GPU__
18 INTEGRATOR_STATE_WRITE(&state->shadow, shadow_path, queued_kernel) = 0;
19 INTEGRATOR_STATE_WRITE(&state->ao, shadow_path, queued_kernel) = 0;
20#endif
21}
22
23/* Minimalistic initialization of the path state, which is needed for early outputs in the
24 * integrator initialization to work. */
27 const int x,
28 const int y)
29{
30 const uint render_pixel_index = (uint)tile->offset + x + y * tile->stride;
31
32 INTEGRATOR_STATE_WRITE(state, path, render_pixel_index) = render_pixel_index;
33
35}
36
37/* Initialize the rest of the path state needed to continue the path integration. */
40 const int sample,
41 const uint rng_pixel)
42{
44 INTEGRATOR_STATE_WRITE(state, path, bounce) = 0;
45 INTEGRATOR_STATE_WRITE(state, path, diffuse_bounce) = 0;
46 INTEGRATOR_STATE_WRITE(state, path, glossy_bounce) = 0;
47 INTEGRATOR_STATE_WRITE(state, path, transmission_bounce) = 0;
48 INTEGRATOR_STATE_WRITE(state, path, transparent_bounce) = 0;
49 INTEGRATOR_STATE_WRITE(state, path, volume_bounce) = 0;
50 INTEGRATOR_STATE_WRITE(state, path, volume_bounds_bounce) = 0;
51 INTEGRATOR_STATE_WRITE(state, path, rng_pixel) = rng_pixel;
52 INTEGRATOR_STATE_WRITE(state, path, rng_offset) = PRNG_BOUNCE_NUM;
55 INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = 0.0f;
56 INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = FLT_MAX;
57 INTEGRATOR_STATE_WRITE(state, path, continuation_probability) = 1.0f;
58 INTEGRATOR_STATE_WRITE(state, path, throughput) = one_spectrum();
59
60#ifdef __PATH_GUIDING__
61 INTEGRATOR_STATE_WRITE(state, path, unguided_throughput) = 1.0f;
62 INTEGRATOR_STATE_WRITE(state, guiding, path_segment) = nullptr;
63 INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = false;
64 INTEGRATOR_STATE_WRITE(state, guiding, sample_surface_guiding_rand) = 0.5f;
65 INTEGRATOR_STATE_WRITE(state, guiding, surface_guiding_sampling_prob) = 0.0f;
66 INTEGRATOR_STATE_WRITE(state, guiding, bssrdf_sampling_prob) = 0.0f;
67 INTEGRATOR_STATE_WRITE(state, guiding, use_volume_guiding) = false;
68 INTEGRATOR_STATE_WRITE(state, guiding, sample_volume_guiding_rand) = 0.5f;
69 INTEGRATOR_STATE_WRITE(state, guiding, volume_guiding_sampling_prob) = 0.0f;
70#endif
71
72#ifdef __MNEE__
73 INTEGRATOR_STATE_WRITE(state, path, mnee) = 0;
74#endif
75
78
79 if (kernel_data.kernel_features & KERNEL_FEATURE_VOLUME) {
80 INTEGRATOR_STATE_ARRAY_WRITE(state, volume_stack, 0, object) = OBJECT_NONE;
82 state, volume_stack, 0, shader) = kernel_data.background.volume_shader;
83 INTEGRATOR_STATE_ARRAY_WRITE(state, volume_stack, 1, object) = OBJECT_NONE;
84 INTEGRATOR_STATE_ARRAY_WRITE(state, volume_stack, 1, shader) = SHADER_NONE;
85 }
86
87#ifdef __DENOISING_FEATURES__
88 if (kernel_data.kernel_features & KERNEL_FEATURE_DENOISING) {
90 INTEGRATOR_STATE_WRITE(state, path, denoising_feature_throughput) = one_spectrum();
91 }
92#endif
93
94#ifdef __LIGHT_LINKING__
95 if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_LINKING) {
96 INTEGRATOR_STATE_WRITE(state, path, mis_ray_object) = OBJECT_NONE;
97 }
98#endif
99}
100
103 const int label,
104 const int shader_flag)
105{
107
108 /* ray through transparent keeps same flags from previous ray and is
109 * not counted as a regular bounce, transparent has separate max */
111 uint32_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce) + 1;
112
114 if (transparent_bounce >= kernel_data.integrator.transparent_max_bounce) {
116 }
117
118 if (shader_flag & SD_RAY_PORTAL) {
120 }
121
123 INTEGRATOR_STATE_WRITE(state, path, transparent_bounce) = transparent_bounce;
124 /* Random number generator next bounce. */
125 INTEGRATOR_STATE_WRITE(state, path, rng_offset) += PRNG_BOUNCE_NUM;
126 return;
127 }
128
129 uint32_t bounce = INTEGRATOR_STATE(state, path, bounce) + 1;
130 if (bounce >= kernel_data.integrator.max_bounce) {
132 }
133
135
136#ifdef __VOLUME__
138 /* volume scatter */
140 flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
141 if (!(flag & PATH_RAY_ANY_PASS)) {
143 }
144
145 const int volume_bounce = INTEGRATOR_STATE(state, path, volume_bounce) + 1;
146 INTEGRATOR_STATE_WRITE(state, path, volume_bounce) = volume_bounce;
147 if (volume_bounce >= kernel_data.integrator.max_volume_bounce) {
149 }
150 }
151 else
152#endif
153 {
154 /* surface reflection/transmission */
155 if (label & LABEL_REFLECT) {
157 flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
158
159 if (label & LABEL_DIFFUSE) {
160 const int diffuse_bounce = INTEGRATOR_STATE(state, path, diffuse_bounce) + 1;
161 INTEGRATOR_STATE_WRITE(state, path, diffuse_bounce) = diffuse_bounce;
162 if (diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) {
164 }
165 }
166 else {
167 const int glossy_bounce = INTEGRATOR_STATE(state, path, glossy_bounce) + 1;
168 INTEGRATOR_STATE_WRITE(state, path, glossy_bounce) = glossy_bounce;
169 if (glossy_bounce >= kernel_data.integrator.max_glossy_bounce) {
171 }
172 }
173 }
174 else {
176
178
180 flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
181 }
182
183 const int transmission_bounce = INTEGRATOR_STATE(state, path, transmission_bounce) + 1;
184 INTEGRATOR_STATE_WRITE(state, path, transmission_bounce) = transmission_bounce;
185 if (transmission_bounce >= kernel_data.integrator.max_transmission_bounce) {
187 }
188 }
189
190 /* diffuse/glossy/singular */
191 if (label & LABEL_DIFFUSE) {
193 }
194 else if (label & LABEL_GLOSSY) {
196 }
197 else {
200 }
201
202 /* Flag for consistent MIS weights with light tree. */
203 if (shader_flag & SD_BSDF_HAS_TRANSMISSION) {
205 }
206
207 /* Render pass categories. */
210 }
211 }
212
214 INTEGRATOR_STATE_WRITE(state, path, bounce) = bounce;
215
216 /* Random number generator next bounce. */
217 INTEGRATOR_STATE_WRITE(state, path, rng_offset) += PRNG_BOUNCE_NUM;
218}
219
220#ifdef __VOLUME__
221ccl_device_inline bool path_state_volume_next(IntegratorState state)
222{
223 /* For volume bounding meshes we pass through without counting transparent
224 * bounces, only sanity check in case self intersection gets us stuck. */
225 uint32_t volume_bounds_bounce = INTEGRATOR_STATE(state, path, volume_bounds_bounce) + 1;
226 INTEGRATOR_STATE_WRITE(state, path, volume_bounds_bounce) = volume_bounds_bounce;
227 if (volume_bounds_bounce > VOLUME_BOUNDS_MAX) {
228 return false;
229 }
230
231 /* Random number generator next bounce. */
232 INTEGRATOR_STATE_WRITE(state, path, rng_offset) += PRNG_BOUNCE_NUM;
233
234 return true;
235}
236#endif
237
239{
240 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
241
242 uint32_t visibility = path_flag & PATH_RAY_ALL_VISIBILITY;
243
244 /* For visibility, diffuse/glossy are for reflection only. */
245 if (visibility & PATH_RAY_TRANSMIT) {
246 visibility &= ~(PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY);
247 }
248
249 /* todo: this is not supported as its own ray visibility yet. */
250 if (path_flag & PATH_RAY_VOLUME_SCATTER) {
251 visibility |= PATH_RAY_DIFFUSE;
252 }
253
254 visibility = SHADOW_CATCHER_PATH_VISIBILITY(path_flag, visibility);
255
256 return visibility;
257}
258
261 const uint32_t path_flag)
262{
263 if (path_flag & PATH_RAY_TRANSPARENT) {
264 const uint32_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
265 /* Do at least specified number of bounces without RR. */
266 if (transparent_bounce <= kernel_data.integrator.transparent_min_bounce) {
267 return 1.0f;
268 }
269 }
270 else {
271 const uint32_t bounce = INTEGRATOR_STATE(state, path, bounce);
272 /* Do at least specified number of bounces without RR. */
273 if (bounce <= kernel_data.integrator.min_bounce) {
274 return 1.0f;
275 }
276 }
277
278 /* Probabilistic termination: use `sqrt()` to roughly match typical view
279 * transform and do path termination a bit later on average. */
280 Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
281#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
282 throughput *= INTEGRATOR_STATE(state, path, unguided_throughput);
283#endif
284 return min(sqrtf(reduce_max(fabs(throughput))), 1.0f);
285}
286
288{
289 if (!kernel_data.integrator.ao_bounces) {
290 return false;
291 }
292
293 const int bounce = INTEGRATOR_STATE(state, path, bounce) -
294 INTEGRATOR_STATE(state, path, transmission_bounce) -
295 (INTEGRATOR_STATE(state, path, glossy_bounce) > 0) + 1;
296 return (bounce > kernel_data.integrator.ao_bounces);
297}
298
299/* Random Number Sampling Utility Functions
300 *
301 * For each random number in each step of the path we must have a unique
302 * dimension to avoid using the same sequence twice.
303 *
304 * For branches in the path we must be careful not to reuse the same number
305 * in a sequence and offset accordingly.
306 */
307
308/* RNG State loaded onto stack. */
314
316 ccl_private RNGState *rng_state)
317{
318 rng_state->rng_pixel = INTEGRATOR_STATE(state, path, rng_pixel);
319 rng_state->rng_offset = INTEGRATOR_STATE(state, path, rng_offset);
320 rng_state->sample = INTEGRATOR_STATE(state, path, sample);
321}
322
324 ccl_private RNGState *rng_state)
325{
326 rng_state->rng_pixel = INTEGRATOR_STATE(state, shadow_path, rng_pixel);
327 rng_state->rng_offset = INTEGRATOR_STATE(state, shadow_path, rng_offset);
328 rng_state->sample = INTEGRATOR_STATE(state, shadow_path, sample);
329}
330
332{
333 /* To get an uncorrelated sequence of samples (e.g. for subsurface random walk), just change
334 * the dimension offset since all implemented samplers can generate unlimited numbers of
335 * dimensions anyways. The only thing to ensure is that the offset is divisible by 4. */
336 rng_state->rng_offset = hash_hp_seeded_uint(rng_state->rng_offset, seed) & ~0x3;
337}
338
340 ccl_private const RNGState *rng_state,
341 const int dimension)
342{
343 return path_rng_1D(
344 kg, rng_state->rng_pixel, rng_state->sample, rng_state->rng_offset + dimension);
345}
346
348 ccl_private const RNGState *rng_state,
349 const int dimension)
350{
351 return path_rng_2D(
352 kg, rng_state->rng_pixel, rng_state->sample, rng_state->rng_offset + dimension);
353}
354
356 ccl_private const RNGState *rng_state,
357 const int dimension)
358{
359 return path_rng_3D(
360 kg, rng_state->rng_pixel, rng_state->sample, rng_state->rng_offset + dimension);
361}
362
364 ccl_private const RNGState *rng_state,
365 const int branch,
366 const int num_branches,
367 const int dimension)
368{
369 return path_rng_1D(kg,
370 rng_state->rng_pixel,
371 rng_state->sample * num_branches + branch,
372 rng_state->rng_offset + dimension);
373}
374
376 ccl_private const RNGState *rng_state,
377 const int branch,
378 const int num_branches,
379 const int dimension)
380{
381 return path_rng_2D(kg,
382 rng_state->rng_pixel,
383 rng_state->sample * num_branches + branch,
384 rng_state->rng_offset + dimension);
385}
386
388 ccl_private const RNGState *rng_state,
389 const int branch,
390 const int num_branches,
391 const int dimension)
392{
393 return path_rng_3D(kg,
394 rng_state->rng_pixel,
395 rng_state->sample * num_branches + branch,
396 rng_state->rng_offset + dimension);
397}
398
399/* Utility functions to get light termination value,
400 * since it might not be needed in many cases.
401 */
404{
405 if (kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
407 }
408 return 0.0f;
409}
410
unsigned int uint
static unsigned long seed
Definition btSoftBody.h:39
const char * label
#define kernel_assert(cond)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define ccl_restrict
#define ccl_private
#define ccl_device_inline
#define ccl_global
#define CCL_NAMESPACE_END
#define sqrtf(x)
ccl_device_inline uint hash_hp_seeded_uint(uint i, uint seed)
Definition hash.h:421
ccl_global const KernelWorkTile * tile
#define KERNEL_FEATURE_VOLUME
@ SD_RAY_PORTAL
@ SD_BSDF_HAS_TRANSMISSION
#define VOLUME_BOUNDS_MAX
#define SHADER_NONE
@ PRNG_BOUNCE_NUM
@ PRNG_LIGHT_TERMINATE
#define PRIM_NONE
@ PATH_RAY_VOLUME_PASS
@ PATH_RAY_TERMINATE_AFTER_TRANSPARENT
@ PATH_RAY_SINGULAR
@ PATH_RAY_REFLECT
@ PATH_RAY_MIS_HAD_TRANSMISSION
@ PATH_RAY_TRANSPARENT
@ PATH_RAY_TRANSMIT
@ PATH_RAY_VOLUME_SCATTER
@ PATH_RAY_MIS_SKIP
@ PATH_RAY_DENOISING_FEATURES
@ PATH_RAY_GLOSSY
@ PATH_RAY_SURFACE_PASS
@ PATH_RAY_ALL_VISIBILITY
@ PATH_RAY_DIFFUSE
@ PATH_RAY_TRANSPARENT_BACKGROUND
@ PATH_RAY_CAMERA
@ PATH_RAY_ANY_PASS
@ PATH_RAY_TERMINATE_ON_NEXT_SURFACE
@ PATH_RAY_DIFFUSE_ANCESTOR
#define OBJECT_NONE
@ LABEL_TRANSMIT
@ LABEL_RAY_PORTAL
@ LABEL_TRANSMIT_TRANSPARENT
@ LABEL_VOLUME_SCATTER
@ LABEL_DIFFUSE
@ LABEL_SINGULAR
@ LABEL_GLOSSY
@ LABEL_REFLECT
@ LABEL_TRANSPARENT
#define KERNEL_FEATURE_DENOISING
#define KERNEL_FEATURE_LIGHT_LINKING
#define SHADOW_CATCHER_PATH_VISIBILITY(path_flag, visibility)
ccl_device_inline float reduce_max(const float2 a)
ccl_device_inline float2 fabs(const float2 a)
static ulong state[N]
ccl_device_inline void path_state_init(IntegratorState state, ccl_global const KernelWorkTile *ccl_restrict tile, const int x, const int y)
Definition path_state.h:25
ccl_device_inline float path_state_continuation_probability(KernelGlobals kg, ConstIntegratorState state, const uint32_t path_flag)
Definition path_state.h:259
ccl_device_inline bool path_state_ao_bounce(KernelGlobals kg, ConstIntegratorState state)
Definition path_state.h:287
ccl_device_inline float3 path_state_rng_3D(KernelGlobals kg, ccl_private const RNGState *rng_state, const int dimension)
Definition path_state.h:355
ccl_device_inline void shadow_path_state_rng_load(ConstIntegratorShadowState state, ccl_private RNGState *rng_state)
Definition path_state.h:323
ccl_device_inline float path_state_rng_1D(KernelGlobals kg, ccl_private const RNGState *rng_state, const int dimension)
Definition path_state.h:339
ccl_device_inline float path_state_rng_light_termination(KernelGlobals kg, ccl_private const RNGState *state)
Definition path_state.h:402
struct RNGState RNGState
ccl_device_inline float2 path_state_rng_2D(KernelGlobals kg, ccl_private const RNGState *rng_state, const int dimension)
Definition path_state.h:347
ccl_device_inline void path_state_rng_load(ConstIntegratorState state, ccl_private RNGState *rng_state)
Definition path_state.h:315
ccl_device_inline uint path_state_ray_visibility(ConstIntegratorState state)
Definition path_state.h:238
ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state, const int label, const int shader_flag)
Definition path_state.h:101
ccl_device_inline float2 path_branched_rng_2D(KernelGlobals kg, ccl_private const RNGState *rng_state, const int branch, const int num_branches, const int dimension)
Definition path_state.h:375
ccl_device_inline void path_state_init_integrator(KernelGlobals kg, IntegratorState state, const int sample, const uint rng_pixel)
Definition path_state.h:38
ccl_device_inline float3 path_branched_rng_3D(KernelGlobals kg, ccl_private const RNGState *rng_state, const int branch, const int num_branches, const int dimension)
Definition path_state.h:387
ccl_device_inline float path_branched_rng_1D(KernelGlobals kg, ccl_private const RNGState *rng_state, const int branch, const int num_branches, const int dimension)
Definition path_state.h:363
CCL_NAMESPACE_BEGIN ccl_device_inline void path_state_init_queues(IntegratorState state)
Definition path_state.h:14
ccl_device_inline void path_state_rng_scramble(ccl_private RNGState *rng_state, const int seed)
Definition path_state.h:331
ccl_device_forceinline float2 path_rng_2D(KernelGlobals kg, uint rng_pixel, int sample, int dimension)
Definition pattern.h:82
ccl_device_forceinline float path_rng_1D(KernelGlobals kg, uint rng_pixel, uint sample, int dimension)
Definition pattern.h:65
ccl_device_forceinline float3 path_rng_3D(KernelGlobals kg, uint rng_pixel, int sample, int dimension)
Definition pattern.h:99
#define min(a, b)
Definition sort.c:32
const IntegratorShadowStateCPU *ccl_restrict ConstIntegratorShadowState
Definition state.h:231
#define INTEGRATOR_STATE_ARRAY_WRITE(state, nested_struct, array_index, member)
Definition state.h:240
IntegratorStateCPU *ccl_restrict IntegratorState
Definition state.h:228
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
Definition state.h:236
const IntegratorStateCPU *ccl_restrict ConstIntegratorState
Definition state.h:229
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition state.h:235
#define FLT_MAX
Definition stdcycles.h:14
unsigned int uint32_t
Definition stdint.h:80
uint rng_pixel
Definition path_state.h:310
uint rng_offset
Definition path_state.h:311
#define one_spectrum
SPECTRUM_DATA_TYPE Spectrum
uint8_t flag
Definition wm_window.cc:138