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