Blender  V3.3
shade_volume.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
7 #include "kernel/film/passes.h"
8 
13 
14 #include "kernel/light/light.h"
15 #include "kernel/light/sample.h"
16 
18 
19 #ifdef __VOLUME__
20 
21 /* Events for probabilistic scattering. */
22 
23 typedef enum VolumeIntegrateEvent {
24  VOLUME_PATH_SCATTERED = 0,
25  VOLUME_PATH_ATTENUATED = 1,
26  VOLUME_PATH_MISSED = 2
27 } VolumeIntegrateEvent;
28 
29 typedef struct VolumeIntegrateResult {
30  /* Throughput and offset for direct light scattering. */
31  bool direct_scatter;
32  float3 direct_throughput;
33  float direct_t;
34  ShaderVolumePhases direct_phases;
35 
36  /* Throughput and offset for indirect light scattering. */
37  bool indirect_scatter;
38  float3 indirect_throughput;
39  float indirect_t;
40  ShaderVolumePhases indirect_phases;
41 } VolumeIntegrateResult;
42 
43 /* Ignore paths that have volume throughput below this value, to avoid unnecessary work
44  * and precision issues.
45  * todo: this value could be tweaked or turned into a probability to avoid unnecessary
46  * work in volumes and subsurface scattering. */
47 # define VOLUME_THROUGHPUT_EPSILON 1e-6f
48 
49 /* Volume shader properties
50  *
51  * extinction coefficient = absorption coefficient + scattering coefficient
52  * sigma_t = sigma_a + sigma_s */
53 
54 typedef struct VolumeShaderCoefficients {
55  float3 sigma_t;
56  float3 sigma_s;
57  float3 emission;
58 } VolumeShaderCoefficients;
59 
60 /* Evaluate shader to get extinction coefficient at P. */
61 ccl_device_inline bool shadow_volume_shader_sample(KernelGlobals kg,
64  ccl_private float3 *ccl_restrict extinction)
65 {
67  shader_eval_volume<true>(kg, state, sd, PATH_RAY_SHADOW, volume_read_lambda_pass);
68 
69  if (!(sd->flag & SD_EXTINCTION)) {
70  return false;
71  }
72 
73  const float density = object_volume_density(kg, sd->object);
74  *extinction = sd->closure_transparent_extinction * density;
75  return true;
76 }
77 
78 /* Evaluate shader to get absorption, scattering and emission at P. */
79 ccl_device_inline bool volume_shader_sample(KernelGlobals kg,
82  ccl_private VolumeShaderCoefficients *coeff)
83 {
84  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
86  shader_eval_volume<false>(kg, state, sd, path_flag, volume_read_lambda_pass);
87 
88  if (!(sd->flag & (SD_EXTINCTION | SD_SCATTER | SD_EMISSION))) {
89  return false;
90  }
91 
92  coeff->sigma_s = zero_float3();
93  coeff->sigma_t = (sd->flag & SD_EXTINCTION) ? sd->closure_transparent_extinction : zero_float3();
94  coeff->emission = (sd->flag & SD_EMISSION) ? sd->closure_emission_background : zero_float3();
95 
96  if (sd->flag & SD_SCATTER) {
97  for (int i = 0; i < sd->num_closure; i++) {
98  ccl_private const ShaderClosure *sc = &sd->closure[i];
99 
100  if (CLOSURE_IS_VOLUME(sc->type)) {
101  coeff->sigma_s += sc->weight;
102  }
103  }
104  }
105 
106  const float density = object_volume_density(kg, sd->object);
107  coeff->sigma_s *= density;
108  coeff->sigma_t *= density;
109  coeff->emission *= density;
110 
111  return true;
112 }
113 
114 ccl_device_forceinline void volume_step_init(KernelGlobals kg,
115  ccl_private const RNGState *rng_state,
116  const float object_step_size,
117  const float tmin,
118  const float tmax,
119  ccl_private float *step_size,
120  ccl_private float *step_shade_offset,
121  ccl_private float *steps_offset,
122  ccl_private int *max_steps)
123 {
124  if (object_step_size == FLT_MAX) {
125  /* Homogeneous volume. */
126  *step_size = tmax - tmin;
127  *step_shade_offset = 0.0f;
128  *steps_offset = 1.0f;
129  *max_steps = 1;
130  }
131  else {
132  /* Heterogeneous volume. */
133  *max_steps = kernel_data.integrator.volume_max_steps;
134  const float t = tmax - tmin;
135  float step = min(object_step_size, t);
136 
137  /* compute exact steps in advance for malloc */
138  if (t > *max_steps * step) {
139  step = t / (float)*max_steps;
140  }
141 
142  *step_size = step;
143 
144  /* Perform shading at this offset within a step, to integrate over
145  * over the entire step segment. */
146  *step_shade_offset = path_state_rng_1D_hash(kg, rng_state, 0x1e31d8a4);
147 
148  /* Shift starting point of all segment by this random amount to avoid
149  * banding artifacts from the volume bounding shape. */
150  *steps_offset = path_state_rng_1D_hash(kg, rng_state, 0x3d22c7b3);
151  }
152 }
153 
154 /* Volume Shadows
155  *
156  * These functions are used to attenuate shadow rays to lights. Both absorption
157  * and scattering will block light, represented by the extinction coefficient. */
158 
159 # if 0
160 /* homogeneous volume: assume shader evaluation at the starts gives
161  * the extinction coefficient for the entire line segment */
162 ccl_device void volume_shadow_homogeneous(KernelGlobals kg, IntegratorState state,
165  ccl_global float3 *ccl_restrict throughput)
166 {
167  float3 sigma_t = zero_float3();
168 
169  if (shadow_volume_shader_sample(kg, state, sd, &sigma_t)) {
170  *throughput *= volume_color_transmittance(sigma_t, ray->tmax - ray->tmin);
171  }
172 }
173 # endif
174 
175 /* heterogeneous volume: integrate stepping through the volume until we
176  * reach the end, get absorbed entirely, or run out of iterations */
177 ccl_device void volume_shadow_heterogeneous(KernelGlobals kg,
181  ccl_private float3 *ccl_restrict throughput,
182  const float object_step_size)
183 {
184  /* Load random number state. */
185  RNGState rng_state;
186  shadow_path_state_rng_load(state, &rng_state);
187 
188  float3 tp = *throughput;
189 
190  /* Prepare for stepping.
191  * For shadows we do not offset all segments, since the starting point is
192  * already a random distance inside the volume. It also appears to create
193  * banding artifacts for unknown reasons. */
194  int max_steps;
195  float step_size, step_shade_offset, unused;
196  volume_step_init(kg,
197  &rng_state,
198  object_step_size,
199  ray->tmin,
200  ray->tmax,
201  &step_size,
202  &step_shade_offset,
203  &unused,
204  &max_steps);
205  const float steps_offset = 1.0f;
206 
207  /* compute extinction at the start */
208  float t = ray->tmin;
209 
210  float3 sum = zero_float3();
211 
212  for (int i = 0; i < max_steps; i++) {
213  /* advance to new position */
214  float new_t = min(ray->tmax, ray->tmin + (i + steps_offset) * step_size);
215  float dt = new_t - t;
216 
217  float3 new_P = ray->P + ray->D * (t + dt * step_shade_offset);
218  float3 sigma_t = zero_float3();
219 
220  /* compute attenuation over segment */
221  sd->P = new_P;
222  if (shadow_volume_shader_sample(kg, state, sd, &sigma_t)) {
223  /* Compute `expf()` only for every Nth step, to save some calculations
224  * because `exp(a)*exp(b) = exp(a+b)`, also do a quick #VOLUME_THROUGHPUT_EPSILON
225  * check then. */
226  sum += (-sigma_t * dt);
227  if ((i & 0x07) == 0) { /* TODO: Other interval? */
228  tp = *throughput * exp(sum);
229 
230  /* stop if nearly all light is blocked */
233  break;
234  }
235  }
236 
237  /* stop if at the end of the volume */
238  t = new_t;
239  if (t == ray->tmax) {
240  /* Update throughput in case we haven't done it above */
241  tp = *throughput * exp(sum);
242  break;
243  }
244  }
245 
246  *throughput = tp;
247 }
248 
249 /* Equi-angular sampling as in:
250  * "Importance Sampling Techniques for Path Tracing in Participating Media" */
251 
252 /* Below this pdf we ignore samples, as they tend to lead to very long distances.
253  * This can cause performance issues with BVH traversal in OptiX, leading it to
254  * traverse many nodes. Since these contribute very little to the image, just ignore
255  * those samples. */
256 # define VOLUME_SAMPLE_PDF_CUTOFF 1e-8f
257 
258 ccl_device float volume_equiangular_sample(ccl_private const Ray *ccl_restrict ray,
259  const float3 light_P,
260  const float xi,
261  ccl_private float *pdf)
262 {
263  const float tmin = ray->tmin;
264  const float tmax = ray->tmax;
265  const float delta = dot((light_P - ray->P), ray->D);
266  const float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
267  if (UNLIKELY(D == 0.0f)) {
268  *pdf = 0.0f;
269  return 0.0f;
270  }
271  const float theta_a = atan2f(tmin - delta, D);
272  const float theta_b = atan2f(tmax - delta, D);
273  const float t_ = D * tanf((xi * theta_b) + (1 - xi) * theta_a);
274  if (UNLIKELY(theta_b == theta_a)) {
275  *pdf = 0.0f;
276  return 0.0f;
277  }
278  *pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
279 
280  return clamp(delta + t_, tmin, tmax); /* clamp is only for float precision errors */
281 }
282 
283 ccl_device float volume_equiangular_pdf(ccl_private const Ray *ccl_restrict ray,
284  const float3 light_P,
285  const float sample_t)
286 {
287  const float delta = dot((light_P - ray->P), ray->D);
288  const float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
289  if (UNLIKELY(D == 0.0f)) {
290  return 0.0f;
291  }
292 
293  const float tmin = ray->tmin;
294  const float tmax = ray->tmax;
295  const float t_ = sample_t - delta;
296 
297  const float theta_a = atan2f(tmin - delta, D);
298  const float theta_b = atan2f(tmax - delta, D);
299  if (UNLIKELY(theta_b == theta_a)) {
300  return 0.0f;
301  }
302 
303  const float pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
304 
305  return pdf;
306 }
307 
308 ccl_device float volume_equiangular_cdf(ccl_private const Ray *ccl_restrict ray,
309  const float3 light_P,
310  const float sample_t)
311 {
312  float delta = dot((light_P - ray->P), ray->D);
313  float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
314  if (UNLIKELY(D == 0.0f)) {
315  return 0.0f;
316  }
317 
318  const float tmin = ray->tmin;
319  const float tmax = ray->tmax;
320  const float t_ = sample_t - delta;
321 
322  const float theta_a = atan2f(tmin - delta, D);
323  const float theta_b = atan2f(tmax - delta, D);
324  if (UNLIKELY(theta_b == theta_a)) {
325  return 0.0f;
326  }
327 
328  const float theta_sample = atan2f(t_, D);
329  const float cdf = (theta_sample - theta_a) / (theta_b - theta_a);
330 
331  return cdf;
332 }
333 
334 /* Distance sampling */
335 
336 ccl_device float volume_distance_sample(float max_t,
337  float3 sigma_t,
338  int channel,
339  float xi,
340  ccl_private float3 *transmittance,
341  ccl_private float3 *pdf)
342 {
343  /* xi is [0, 1[ so log(0) should never happen, division by zero is
344  * avoided because sample_sigma_t > 0 when SD_SCATTER is set */
345  float sample_sigma_t = volume_channel_get(sigma_t, channel);
346  float3 full_transmittance = volume_color_transmittance(sigma_t, max_t);
347  float sample_transmittance = volume_channel_get(full_transmittance, channel);
348 
349  float sample_t = min(max_t, -logf(1.0f - xi * (1.0f - sample_transmittance)) / sample_sigma_t);
350 
351  *transmittance = volume_color_transmittance(sigma_t, sample_t);
352  *pdf = safe_divide_color(sigma_t * *transmittance, one_float3() - full_transmittance);
353 
354  /* todo: optimization: when taken together with hit/miss decision,
355  * the full_transmittance cancels out drops out and xi does not
356  * need to be remapped */
357 
358  return sample_t;
359 }
360 
361 ccl_device float3 volume_distance_pdf(float max_t, float3 sigma_t, float sample_t)
362 {
363  float3 full_transmittance = volume_color_transmittance(sigma_t, max_t);
364  float3 transmittance = volume_color_transmittance(sigma_t, sample_t);
365 
366  return safe_divide_color(sigma_t * transmittance, one_float3() - full_transmittance);
367 }
368 
369 /* Emission */
370 
371 ccl_device float3 volume_emission_integrate(ccl_private VolumeShaderCoefficients *coeff,
372  int closure_flag,
373  float3 transmittance,
374  float t)
375 {
376  /* integral E * exp(-sigma_t * t) from 0 to t = E * (1 - exp(-sigma_t * t))/sigma_t
377  * this goes to E * t as sigma_t goes to zero
378  *
379  * todo: we should use an epsilon to avoid precision issues near zero sigma_t */
380  float3 emission = coeff->emission;
381 
382  if (closure_flag & SD_EXTINCTION) {
383  float3 sigma_t = coeff->sigma_t;
384 
385  emission.x *= (sigma_t.x > 0.0f) ? (1.0f - transmittance.x) / sigma_t.x : t;
386  emission.y *= (sigma_t.y > 0.0f) ? (1.0f - transmittance.y) / sigma_t.y : t;
387  emission.z *= (sigma_t.z > 0.0f) ? (1.0f - transmittance.z) / sigma_t.z : t;
388  }
389  else
390  emission *= t;
391 
392  return emission;
393 }
394 
395 /* Volume Integration */
396 
397 typedef struct VolumeIntegrateState {
398  /* Volume segment extents. */
399  float tmin;
400  float tmax;
401 
402  /* If volume is absorption-only up to this point, and no probabilistic
403  * scattering or termination has been used yet. */
404  bool absorption_only;
405 
406  /* Random numbers for scattering. */
407  float rscatter;
408  float rphase;
409 
410  /* Multiple importance sampling. */
411  VolumeSampleMethod direct_sample_method;
412  bool use_mis;
413  float distance_pdf;
414  float equiangular_pdf;
415 } VolumeIntegrateState;
416 
417 ccl_device_forceinline void volume_integrate_step_scattering(
418  ccl_private const ShaderData *sd,
419  ccl_private const Ray *ray,
420  const float3 equiangular_light_P,
421  ccl_private const VolumeShaderCoefficients &ccl_restrict coeff,
422  const float3 transmittance,
423  ccl_private VolumeIntegrateState &ccl_restrict vstate,
424  ccl_private VolumeIntegrateResult &ccl_restrict result)
425 {
426  /* Pick random color channel, we use the Veach one-sample
427  * model with balance heuristic for the channels. */
428  const float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
429  float3 channel_pdf;
430  const int channel = volume_sample_channel(
431  albedo, result.indirect_throughput, vstate.rphase, &channel_pdf);
432 
433  /* Equiangular sampling for direct lighting. */
434  if (vstate.direct_sample_method == VOLUME_SAMPLE_EQUIANGULAR && !result.direct_scatter) {
435  if (result.direct_t >= vstate.tmin && result.direct_t <= vstate.tmax &&
436  vstate.equiangular_pdf > VOLUME_SAMPLE_PDF_CUTOFF) {
437  const float new_dt = result.direct_t - vstate.tmin;
438  const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt);
439 
440  result.direct_scatter = true;
441  result.direct_throughput *= coeff.sigma_s * new_transmittance / vstate.equiangular_pdf;
442  shader_copy_volume_phases(&result.direct_phases, sd);
443 
444  /* Multiple importance sampling. */
445  if (vstate.use_mis) {
446  const float distance_pdf = vstate.distance_pdf *
447  dot(channel_pdf, coeff.sigma_t * new_transmittance);
448  const float mis_weight = 2.0f * power_heuristic(vstate.equiangular_pdf, distance_pdf);
449  result.direct_throughput *= mis_weight;
450  }
451  }
452  else {
453  result.direct_throughput *= transmittance;
454  vstate.distance_pdf *= dot(channel_pdf, transmittance);
455  }
456  }
457 
458  /* Distance sampling for indirect and optional direct lighting. */
459  if (!result.indirect_scatter) {
460  /* decide if we will scatter or continue */
461  const float sample_transmittance = volume_channel_get(transmittance, channel);
462 
463  if (1.0f - vstate.rscatter >= sample_transmittance) {
464  /* compute sampling distance */
465  const float sample_sigma_t = volume_channel_get(coeff.sigma_t, channel);
466  const float new_dt = -logf(1.0f - vstate.rscatter) / sample_sigma_t;
467  const float new_t = vstate.tmin + new_dt;
468 
469  /* transmittance and pdf */
470  const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt);
471  const float distance_pdf = dot(channel_pdf, coeff.sigma_t * new_transmittance);
472 
473  if (vstate.distance_pdf * distance_pdf > VOLUME_SAMPLE_PDF_CUTOFF) {
474  /* throughput */
475  result.indirect_scatter = true;
476  result.indirect_t = new_t;
477  result.indirect_throughput *= coeff.sigma_s * new_transmittance / distance_pdf;
478  shader_copy_volume_phases(&result.indirect_phases, sd);
479 
480  if (vstate.direct_sample_method != VOLUME_SAMPLE_EQUIANGULAR) {
481  /* If using distance sampling for direct light, just copy parameters
482  * of indirect light since we scatter at the same point then. */
483  result.direct_scatter = true;
484  result.direct_t = result.indirect_t;
485  result.direct_throughput = result.indirect_throughput;
486  shader_copy_volume_phases(&result.direct_phases, sd);
487 
488  /* Multiple importance sampling. */
489  if (vstate.use_mis) {
490  const float equiangular_pdf = volume_equiangular_pdf(ray, equiangular_light_P, new_t);
491  const float mis_weight = power_heuristic(vstate.distance_pdf * distance_pdf,
492  equiangular_pdf);
493  result.direct_throughput *= 2.0f * mis_weight;
494  }
495  }
496  }
497  }
498  else {
499  /* throughput */
500  const float pdf = dot(channel_pdf, transmittance);
501  result.indirect_throughput *= transmittance / pdf;
502  if (vstate.direct_sample_method != VOLUME_SAMPLE_EQUIANGULAR) {
503  vstate.distance_pdf *= pdf;
504  }
505 
506  /* remap rscatter so we can reuse it and keep thing stratified */
507  vstate.rscatter = 1.0f - (1.0f - vstate.rscatter) / sample_transmittance;
508  }
509  }
510 }
511 
512 /* heterogeneous volume distance sampling: integrate stepping through the
513  * volume until we reach the end, get absorbed entirely, or run out of
514  * iterations. this does probabilistically scatter or get transmitted through
515  * for path tracing where we don't want to branch. */
516 ccl_device_forceinline void volume_integrate_heterogeneous(
517  KernelGlobals kg,
521  ccl_private const RNGState *rng_state,
523  const float object_step_size,
524  const VolumeSampleMethod direct_sample_method,
525  const float3 equiangular_light_P,
526  ccl_private VolumeIntegrateResult &result)
527 {
529 
530  /* Prepare for stepping.
531  * Using a different step offset for the first step avoids banding artifacts. */
532  int max_steps;
533  float step_size, step_shade_offset, steps_offset;
534  volume_step_init(kg,
535  rng_state,
536  object_step_size,
537  ray->tmin,
538  ray->tmax,
539  &step_size,
540  &step_shade_offset,
541  &steps_offset,
542  &max_steps);
543 
544  /* Initialize volume integration state. */
545  VolumeIntegrateState vstate ccl_optional_struct_init;
546  vstate.tmin = ray->tmin;
547  vstate.tmax = ray->tmin;
548  vstate.absorption_only = true;
549  vstate.rscatter = path_state_rng_1D(kg, rng_state, PRNG_SCATTER_DISTANCE);
550  vstate.rphase = path_state_rng_1D(kg, rng_state, PRNG_PHASE_CHANNEL);
551 
552  /* Multiple importance sampling: pick between equiangular and distance sampling strategy. */
553  vstate.direct_sample_method = direct_sample_method;
554  vstate.use_mis = (direct_sample_method == VOLUME_SAMPLE_MIS);
555  if (vstate.use_mis) {
556  if (vstate.rscatter < 0.5f) {
557  vstate.rscatter *= 2.0f;
558  vstate.direct_sample_method = VOLUME_SAMPLE_DISTANCE;
559  }
560  else {
561  vstate.rscatter = (vstate.rscatter - 0.5f) * 2.0f;
562  vstate.direct_sample_method = VOLUME_SAMPLE_EQUIANGULAR;
563  }
564  }
565  vstate.equiangular_pdf = 0.0f;
566  vstate.distance_pdf = 1.0f;
567 
568  /* Initialize volume integration result. */
569  const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
570  result.direct_throughput = throughput;
571  result.indirect_throughput = throughput;
572 
573  /* Equiangular sampling: compute distance and PDF in advance. */
574  if (vstate.direct_sample_method == VOLUME_SAMPLE_EQUIANGULAR) {
575  result.direct_t = volume_equiangular_sample(
576  ray, equiangular_light_P, vstate.rscatter, &vstate.equiangular_pdf);
577  }
578 
579 # ifdef __DENOISING_FEATURES__
580  const bool write_denoising_features = (INTEGRATOR_STATE(state, path, flag) &
582  float3 accum_albedo = zero_float3();
583 # endif
584  float3 accum_emission = zero_float3();
585 
586  for (int i = 0; i < max_steps; i++) {
587  /* Advance to new position */
588  vstate.tmax = min(ray->tmax, ray->tmin + (i + steps_offset) * step_size);
589  const float shade_t = vstate.tmin + (vstate.tmax - vstate.tmin) * step_shade_offset;
590  sd->P = ray->P + ray->D * shade_t;
591 
592  /* compute segment */
593  VolumeShaderCoefficients coeff ccl_optional_struct_init;
594  if (volume_shader_sample(kg, state, sd, &coeff)) {
595  const int closure_flag = sd->flag;
596 
597  /* Evaluate transmittance over segment. */
598  const float dt = (vstate.tmax - vstate.tmin);
599  const float3 transmittance = (closure_flag & SD_EXTINCTION) ?
600  volume_color_transmittance(coeff.sigma_t, dt) :
601  one_float3();
602 
603  /* Emission. */
604  if (closure_flag & SD_EMISSION) {
605  /* Only write emission before indirect light scatter position, since we terminate
606  * stepping at that point if we have already found a direct light scatter position. */
607  if (!result.indirect_scatter) {
608  const float3 emission = volume_emission_integrate(
609  &coeff, closure_flag, transmittance, dt);
610  accum_emission += result.indirect_throughput * emission;
611  }
612  }
613 
614  if (closure_flag & SD_EXTINCTION) {
615  if ((closure_flag & SD_SCATTER) || !vstate.absorption_only) {
616 # ifdef __DENOISING_FEATURES__
617  /* Accumulate albedo for denoising features. */
618  if (write_denoising_features && (closure_flag & SD_SCATTER)) {
619  const float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
620  accum_albedo += result.indirect_throughput * albedo * (one_float3() - transmittance);
621  }
622 # endif
623 
624  /* Scattering and absorption. */
625  volume_integrate_step_scattering(
626  sd, ray, equiangular_light_P, coeff, transmittance, vstate, result);
627  }
628  else {
629  /* Absorption only. */
630  result.indirect_throughput *= transmittance;
631  result.direct_throughput *= transmittance;
632  }
633 
634  /* Stop if nearly all light blocked. */
635  if (!result.indirect_scatter) {
636  if (reduce_max(result.indirect_throughput) < VOLUME_THROUGHPUT_EPSILON) {
637  result.indirect_throughput = zero_float3();
638  break;
639  }
640  }
641  else if (!result.direct_scatter) {
642  if (reduce_max(result.direct_throughput) < VOLUME_THROUGHPUT_EPSILON) {
643  break;
644  }
645  }
646  }
647 
648  /* If we have scattering data for both direct and indirect, we're done. */
649  if (result.direct_scatter && result.indirect_scatter) {
650  break;
651  }
652  }
653 
654  /* Stop if at the end of the volume. */
655  vstate.tmin = vstate.tmax;
656  if (vstate.tmin == ray->tmax) {
657  break;
658  }
659  }
660 
661  /* Write accumulated emission. */
662  if (!is_zero(accum_emission)) {
664  kg, state, accum_emission, render_buffer, object_lightgroup(kg, sd->object));
665  }
666 
667 # ifdef __DENOISING_FEATURES__
668  /* Write denoising features. */
669  if (write_denoising_features) {
670  kernel_write_denoising_features_volume(
671  kg, state, accum_albedo, result.indirect_scatter, render_buffer);
672  }
673 # endif /* __DENOISING_FEATURES__ */
674 }
675 
676 # ifdef __EMISSION__
677 /* Path tracing: sample point on light and evaluate light shader, then
678  * queue shadow ray to be traced. */
679 ccl_device_forceinline bool integrate_volume_sample_light(
680  KernelGlobals kg,
683  ccl_private const RNGState *ccl_restrict rng_state,
685 {
686  /* Test if there is a light or BSDF that needs direct light. */
687  if (!kernel_data.integrator.use_direct_light) {
688  return false;
689  }
690 
691  /* Sample position on a light. */
692  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
693  const uint bounce = INTEGRATOR_STATE(state, path, bounce);
694  float light_u, light_v;
695  path_state_rng_2D(kg, rng_state, PRNG_LIGHT_U, &light_u, &light_v);
696 
698  kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, ls)) {
699  return false;
700  }
701 
702  if (ls->shader & SHADER_EXCLUDE_SCATTER) {
703  return false;
704  }
705 
706  return true;
707 }
708 
709 /* Path tracing: sample point on light and evaluate light shader, then
710  * queue shadow ray to be traced. */
711 ccl_device_forceinline void integrate_volume_direct_light(
712  KernelGlobals kg,
715  ccl_private const RNGState *ccl_restrict rng_state,
716  const float3 P,
718  ccl_private const float3 throughput,
720 {
722 
723  if (!kernel_data.integrator.use_direct_light) {
724  return;
725  }
726 
727  /* Sample position on the same light again, now from the shading
728  * point where we scattered.
729  *
730  * TODO: decorrelate random numbers and use light_sample_new_position to
731  * avoid resampling the CDF. */
732  {
733  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
734  const uint bounce = INTEGRATOR_STATE(state, path, bounce);
735  float light_u, light_v;
736  path_state_rng_2D(kg, rng_state, PRNG_LIGHT_U, &light_u, &light_v);
737 
739  kg, light_u, light_v, sd->time, P, bounce, path_flag, ls)) {
740  return;
741  }
742  }
743 
744  if (ls->shader & SHADER_EXCLUDE_SCATTER) {
745  return;
746  }
747 
748  /* Evaluate light shader.
749  *
750  * TODO: can we reuse sd memory? In theory we can move this after
751  * integrate_surface_bounce, evaluate the BSDF, and only then evaluate
752  * the light shader. This could also move to its own kernel, for
753  * non-constant light sources. */
754  ShaderDataTinyStorage emission_sd_storage;
755  ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
756  const float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, ls, sd->time);
757  if (is_zero(light_eval)) {
758  return;
759  }
760 
761  /* Evaluate BSDF. */
763  const float phase_pdf = shader_volume_phase_eval(kg, sd, phases, ls->D, &phase_eval);
764 
765  if (ls->shader & SHADER_USE_MIS) {
766  float mis_weight = light_sample_mis_weight_nee(kg, ls->pdf, phase_pdf);
767  bsdf_eval_mul(&phase_eval, mis_weight);
768  }
769 
770  bsdf_eval_mul(&phase_eval, light_eval / ls->pdf);
771 
772  /* Path termination. */
773  const float terminate = path_state_rng_light_termination(kg, rng_state);
774  if (light_sample_terminate(kg, ls, &phase_eval, terminate)) {
775  return;
776  }
777 
778  /* Create shadow ray. */
780  light_sample_to_volume_shadow_ray(kg, sd, ls, P, &ray);
781  const bool is_light = light_sample_is_light(ls);
782 
783  /* Branch off shadow kernel. */
786 
787  /* Write shadow ray and associated state to global memory. */
788  integrator_state_write_shadow_ray(kg, shadow_state, &ray);
789  INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 0, object) = ray.self.object;
790  INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 0, prim) = ray.self.prim;
791  INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 1, object) = ray.self.light_object;
792  INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 1, prim) = ray.self.light_prim;
793 
794  /* Copy state from main path to shadow path. */
795  const uint16_t bounce = INTEGRATOR_STATE(state, path, bounce);
796  const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
797  uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
798  shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
799  const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval);
800 
801  if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
802  packed_float3 pass_diffuse_weight;
803  packed_float3 pass_glossy_weight;
804 
805  if (shadow_flag & PATH_RAY_ANY_PASS) {
806  /* Indirect bounce, use weights from earlier surface or volume bounce. */
807  pass_diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight);
808  pass_glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight);
809  }
810  else {
811  /* Direct light, no diffuse/glossy distinction needed for volumes. */
812  shadow_flag |= PATH_RAY_VOLUME_PASS;
813  pass_diffuse_weight = packed_float3(one_float3());
814  pass_glossy_weight = packed_float3(zero_float3());
815  }
816 
817  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight;
818  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_glossy_weight) = pass_glossy_weight;
819  }
820 
821  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, render_pixel_index) = INTEGRATOR_STATE(
822  state, path, render_pixel_index);
823  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, rng_offset) = INTEGRATOR_STATE(
824  state, path, rng_offset);
825  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, rng_hash) = INTEGRATOR_STATE(
826  state, path, rng_hash);
827  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, sample) = INTEGRATOR_STATE(
828  state, path, sample);
829  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, flag) = shadow_flag;
830  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, bounce) = bounce;
831  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transparent_bounce) = transparent_bounce;
832  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, diffuse_bounce) = INTEGRATOR_STATE(
833  state, path, diffuse_bounce);
834  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, glossy_bounce) = INTEGRATOR_STATE(
835  state, path, glossy_bounce);
836  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transmission_bounce) = INTEGRATOR_STATE(
837  state, path, transmission_bounce);
838  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, throughput) = throughput_phase;
839 
840  if (kernel_data.kernel_features & KERNEL_FEATURE_SHADOW_PASS) {
841  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unshadowed_throughput) = throughput;
842  }
843 
844  /* Write Lightgroup, +1 as lightgroup is int but we need to encode into a uint8_t. */
846  shadow_state, shadow_path, lightgroup) = (ls->type != LIGHT_BACKGROUND) ?
847  ls->group + 1 :
848  kernel_data.background.lightgroup + 1;
849 
851 }
852 # endif
853 
854 /* Path tracing: scatter in new direction using phase function */
855 ccl_device_forceinline bool integrate_volume_phase_scatter(
856  KernelGlobals kg,
859  ccl_private const RNGState *rng_state,
860  ccl_private const ShaderVolumePhases *phases)
861 {
863 
864  float phase_u, phase_v;
865  path_state_rng_2D(kg, rng_state, PRNG_BSDF_U, &phase_u, &phase_v);
866 
867  /* Phase closure, sample direction. */
868  float phase_pdf;
870  float3 phase_omega_in ccl_optional_struct_init;
871  differential3 phase_domega_in ccl_optional_struct_init;
872 
873  const int label = shader_volume_phase_sample(kg,
874  sd,
875  phases,
876  phase_u,
877  phase_v,
878  &phase_eval,
879  &phase_omega_in,
880  &phase_domega_in,
881  &phase_pdf);
882 
883  if (phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval)) {
884  return false;
885  }
886 
887  /* Setup ray. */
888  INTEGRATOR_STATE_WRITE(state, ray, P) = sd->P;
889  INTEGRATOR_STATE_WRITE(state, ray, D) = normalize(phase_omega_in);
890  INTEGRATOR_STATE_WRITE(state, ray, tmin) = 0.0f;
891  INTEGRATOR_STATE_WRITE(state, ray, tmax) = FLT_MAX;
892 # ifdef __RAY_DIFFERENTIALS__
894  INTEGRATOR_STATE_WRITE(state, ray, dD) = differential_make_compact(phase_domega_in);
895 # endif
896  // Save memory by storing last hit prim and object in isect
897  INTEGRATOR_STATE_WRITE(state, isect, prim) = sd->prim;
898  INTEGRATOR_STATE_WRITE(state, isect, object) = sd->object;
899 
900  /* Update throughput. */
901  const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
902  const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval) / phase_pdf;
903  INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput_phase;
904 
905  if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
906  INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_float3();
907  INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_float3();
908  }
909 
910  /* Update path state */
911  INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = phase_pdf;
912  INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf(
913  phase_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf));
914 
916  return true;
917 }
918 
919 /* get the volume attenuation and emission over line segment defined by
920  * ray, with the assumption that there are no surfaces blocking light
921  * between the endpoints. distance sampling is used to decide if we will
922  * scatter or not. */
923 ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
927 {
928  ShaderData sd;
929  shader_setup_from_volume(kg, &sd, ray);
930 
931  /* Load random number state. */
932  RNGState rng_state;
933  path_state_rng_load(state, &rng_state);
934 
935  /* Sample light ahead of volume stepping, for equiangular sampling. */
936  /* TODO: distant lights are ignored now, but could instead use even distribution. */
938  const bool need_light_sample = !(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_TERMINATE);
939  const bool have_equiangular_sample = need_light_sample &&
940  integrate_volume_sample_light(
941  kg, state, &sd, &rng_state, &ls) &&
942  (ls.t != FLT_MAX);
943 
944  VolumeSampleMethod direct_sample_method = (have_equiangular_sample) ?
947 
948  /* Step through volume. */
950  const float step_size = volume_stack_step_size(kg, volume_read_lambda_pass);
951 
952  /* TODO: expensive to zero closures? */
953  VolumeIntegrateResult result = {};
954  volume_integrate_heterogeneous(kg,
955  state,
956  ray,
957  &sd,
958  &rng_state,
960  step_size,
961  direct_sample_method,
962  ls.P,
963  result);
964 
965  /* Perform path termination. The intersect_closest will have already marked this path
966  * to be terminated. That will shading evaluating to leave out any scattering closures,
967  * but emission and absorption are still handled for multiple importance sampling. */
968  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
969  const float probability = (path_flag & PATH_RAY_TERMINATE_IN_NEXT_VOLUME) ?
970  0.0f :
971  INTEGRATOR_STATE(state, path, continuation_probability);
972  if (probability == 0.0f) {
973  return VOLUME_PATH_MISSED;
974  }
975 
976  /* Direct light. */
977  if (result.direct_scatter) {
978  const float3 direct_P = ray->P + result.direct_t * ray->D;
979  result.direct_throughput /= probability;
980  integrate_volume_direct_light(kg,
981  state,
982  &sd,
983  &rng_state,
984  direct_P,
985  &result.direct_phases,
986  result.direct_throughput,
987  &ls);
988  }
989 
990  /* Indirect light.
991  *
992  * Only divide throughput by probability if we scatter. For the attenuation
993  * case the next surface will already do this division. */
994  if (result.indirect_scatter) {
995  result.indirect_throughput /= probability;
996  }
997  INTEGRATOR_STATE_WRITE(state, path, throughput) = result.indirect_throughput;
998 
999  if (result.indirect_scatter) {
1000  sd.P = ray->P + result.indirect_t * ray->D;
1001 
1002  if (integrate_volume_phase_scatter(kg, state, &sd, &rng_state, &result.indirect_phases)) {
1003  return VOLUME_PATH_SCATTERED;
1004  }
1005  else {
1006  return VOLUME_PATH_MISSED;
1007  }
1008  }
1009  else {
1010  return VOLUME_PATH_ATTENUATED;
1011  }
1012 }
1013 
1014 #endif
1015 
1019 {
1021 
1022 #ifdef __VOLUME__
1023  /* Setup shader data. */
1025  integrator_state_read_ray(kg, state, &ray);
1026 
1028  integrator_state_read_isect(kg, state, &isect);
1029 
1030  /* Set ray length to current segment. */
1031  ray.tmax = (isect.prim != PRIM_NONE) ? isect.t : FLT_MAX;
1032 
1033  /* Clean volume stack for background rays. */
1034  if (isect.prim == PRIM_NONE) {
1036  }
1037 
1038  VolumeIntegrateEvent event = volume_integrate(kg, state, &ray, render_buffer);
1039 
1040  if (event == VOLUME_PATH_SCATTERED) {
1041  /* Queue intersect_closest kernel. */
1043  state,
1046  return;
1047  }
1048  else if (event == VOLUME_PATH_MISSED) {
1049  /* End path. */
1051  return;
1052  }
1053  else {
1054  /* Continue to background, light or surface. */
1055  integrator_intersect_next_kernel_after_volume<DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME>(
1056  kg, state, &isect, render_buffer);
1057  return;
1058  }
1059 #endif /* __VOLUME__ */
1060 }
1061 
typedef float(TangentPoint)[2]
MINLINE float safe_sqrtf(float a)
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNLIKELY(x)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float value)
Definition: accumulate.h:58
ccl_device_inline bool bsdf_eval_is_zero(ccl_private BsdfEval *eval)
Definition: accumulate.h:53
ccl_device_inline void kernel_accum_emission(KernelGlobals kg, ConstIntegratorState state, const float3 L, ccl_global float *ccl_restrict render_buffer, const int lightgroup=LIGHTGROUP_NONE)
Definition: accumulate.h:592
ccl_device_inline float3 bsdf_eval_sum(ccl_private const BsdfEval *eval)
Definition: accumulate.h:72
__forceinline int reduce_max(const avxi &v)
Definition: avxi.h:692
static T sum(const btAlignedObjectArray< T > &items)
#define ccl_restrict
Definition: cuda/compat.h:50
#define ccl_device_forceinline
Definition: cuda/compat.h:35
#define logf(x)
Definition: cuda/compat.h:105
#define ccl_optional_struct_init
Definition: cuda/compat.h:53
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_private
Definition: cuda/compat.h:48
#define ccl_device_inline
Definition: cuda/compat.h:34
#define tanf(x)
Definition: cuda/compat.h:104
#define ccl_global
Definition: cuda/compat.h:43
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
ccl_device_inline float light_sample_mis_weight_nee(KernelGlobals kg, const float nee_pdf, const float forward_pdf)
CCL_NAMESPACE_BEGIN ccl_device_noinline_cpu float3 light_sample_shader_eval(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *ccl_restrict emission_sd, ccl_private LightSample *ccl_restrict ls, float time)
ccl_device_inline void light_sample_to_volume_shadow_ray(KernelGlobals kg, ccl_private const ShaderData *ccl_restrict sd, ccl_private const LightSample *ccl_restrict ls, const float3 P, ccl_private Ray *ray)
ccl_device_inline bool light_sample_is_light(ccl_private const LightSample *ccl_restrict ls)
ccl_device_inline bool light_sample_terminate(KernelGlobals kg, ccl_private const LightSample *ccl_restrict ls, ccl_private BsdfEval *ccl_restrict eval, const float rand_terminate)
const char * label
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
ccl_device_forceinline float differential_make_compact(const differential3 D)
Definition: differential.h:117
#define VOLUME_THROUGHPUT_EPSILON
ccl_device float3 volume_color_transmittance(float3 sigma, float t)
ccl_device float volume_channel_get(float3 value, int channel)
ccl_device int volume_sample_channel(float3 albedo, float3 throughput, float rand, ccl_private float3 *pdf)
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
const uint64_t render_pixel_index
const int state
ccl_device_inline float object_volume_density(KernelGlobals kg, int object)
ccl_device_inline int object_lightgroup(KernelGlobals kg, int object)
ccl_device_inline bool light_distribution_sample_from_volume_segment(KernelGlobals kg, float randu, const float randv, const float time, const float3 P, const int bounce, const uint32_t path_flag, ccl_private LightSample *ls)
ccl_device_inline bool light_distribution_sample_from_position(KernelGlobals kg, float randu, const float randv, const float time, const float3 P, const int bounce, const uint32_t path_flag, ccl_private LightSample *ls)
#define CLOSURE_IS_VOLUME(type)
@ SD_EXTINCTION
Definition: kernel/types.h:750
@ SD_SCATTER
Definition: kernel/types.h:752
@ SD_EMISSION
Definition: kernel/types.h:740
#define AS_SHADER_DATA(shader_data_tiny_storage)
Definition: kernel/types.h:943
@ PRNG_BSDF_U
Definition: kernel/types.h:164
@ PRNG_LIGHT_U
Definition: kernel/types.h:166
@ PRNG_SCATTER_DISTANCE
Definition: kernel/types.h:171
@ PRNG_PHASE_CHANNEL
Definition: kernel/types.h:170
#define PRIM_NONE
Definition: kernel/types.h:41
@ PATH_RAY_SHADOW
Definition: kernel/types.h:206
@ PATH_RAY_VOLUME_PASS
Definition: kernel/types.h:270
@ PATH_RAY_TERMINATE
Definition: kernel/types.h:251
@ PATH_RAY_TERMINATE_IN_NEXT_VOLUME
Definition: kernel/types.h:239
@ PATH_RAY_DENOISING_FEATURES
Definition: kernel/types.h:266
@ PATH_RAY_SHADOW_FOR_LIGHT
Definition: kernel/types.h:274
@ PATH_RAY_ANY_PASS
Definition: kernel/types.h:271
@ KERNEL_FEATURE_LIGHT_PASSES
@ KERNEL_FEATURE_SHADOW_PASS
ShaderDataTinyStorage
Definition: kernel/types.h:933
ShaderData
Definition: kernel/types.h:925
@ SHADER_USE_MIS
Definition: kernel/types.h:438
@ SHADER_EXCLUDE_SCATTER
Definition: kernel/types.h:443
ShaderClosure
Definition: kernel/types.h:726
@ LIGHT_BACKGROUND
Definition: kernel/types.h:458
@ DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST
#define PROFILING_INIT(kg, event)
ccl_device_inline float3 one_float3()
Definition: math_float3.h:89
ccl_device_inline float3 exp(float3 v)
Definition: math_float3.h:392
ccl_device_inline float3 zero_float3()
Definition: math_float3.h:80
ccl_device_inline float len_squared(const float3 a)
Definition: math_float3.h:423
static float P(float k)
Definition: math_interp.c:25
#define atan2f(x, y)
Definition: metal/compat.h:227
#define fminf(x, y)
Definition: metal/compat.h:229
#define VOLUME_READ_LAMBDA(function_call)
Definition: metal/compat.h:156
ccl_device float power_heuristic(float a, float b)
Definition: mis.h:25
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
T clamp(const T &a, const T &min, const T &max)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
bool is_zero(const T &a)
static const pxr::TfToken density("density", pxr::TfToken::Immortal)
ccl_device_inline void shadow_path_state_rng_load(ConstIntegratorShadowState state, ccl_private RNGState *rng_state)
Definition: path_state.h:291
ccl_device_inline float path_state_rng_1D(KernelGlobals kg, ccl_private const RNGState *rng_state, int dimension)
Definition: path_state.h:299
ccl_device_inline float path_state_rng_light_termination(KernelGlobals kg, ccl_private const RNGState *state)
Definition: path_state.h:359
ccl_device_inline float path_state_rng_1D_hash(KernelGlobals kg, ccl_private const RNGState *rng_state, uint hash)
Definition: path_state.h:317
ccl_device_inline void path_state_rng_load(ConstIntegratorState state, ccl_private RNGState *rng_state)
Definition: path_state.h:283
ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state, int label)
Definition: path_state.h:82
ccl_device_inline void path_state_rng_2D(KernelGlobals kg, ccl_private const RNGState *rng_state, int dimension, ccl_private float *fx, ccl_private float *fy)
Definition: path_state.h:307
CCL_NAMESPACE_BEGIN ccl_device void integrator_shade_volume(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
#define min(a, b)
Definition: sort.c:35
#define INTEGRATOR_STATE_ARRAY_WRITE(state, nested_struct, array_index, member)
Definition: state.h:159
IntegratorStateCPU *ccl_restrict IntegratorState
Definition: state.h:147
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
Definition: state.h:155
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition: state.h:154
IntegratorShadowStateCPU *ccl_restrict IntegratorShadowState
Definition: state.h:149
ccl_device_forceinline void integrator_path_terminate(KernelGlobals kg, IntegratorState state, const DeviceKernel current_kernel)
Definition: state_flow.h:160
ccl_device_forceinline void integrator_path_next(KernelGlobals kg, IntegratorState state, const DeviceKernel current_kernel, const DeviceKernel next_kernel)
Definition: state_flow.h:151
ccl_device_forceinline IntegratorShadowState integrator_shadow_path_init(KernelGlobals kg, IntegratorState state, const DeviceKernel next_kernel, const bool is_ao)
Definition: state_flow.h:179
ccl_device_forceinline VolumeStack integrator_state_read_volume_stack(ConstIntegratorState state, int i)
Definition: state_util.h:90
ccl_device_forceinline void integrator_state_read_ray(KernelGlobals kg, ConstIntegratorState state, ccl_private Ray *ccl_restrict ray)
Definition: state_util.h:27
ccl_device_forceinline VolumeStack integrator_state_read_shadow_volume_stack(ConstIntegratorShadowState state, int i)
Definition: state_util.h:180
ccl_device_forceinline void integrator_state_read_isect(KernelGlobals kg, ConstIntegratorState state, ccl_private Intersection *ccl_restrict isect)
Definition: state_util.h:79
ccl_device_forceinline void integrator_state_write_shadow_ray(KernelGlobals kg, IntegratorShadowState state, ccl_private const Ray *ccl_restrict ray)
Definition: state_util.h:42
ccl_device_forceinline void integrator_state_copy_volume_stack_to_shadow(KernelGlobals kg, IntegratorShadowState shadow_state, ConstIntegratorState state)
Definition: state_util.h:142
unsigned short uint16_t
Definition: stdint.h:79
unsigned int uint32_t
Definition: stdint.h:80
float z
float y
float x
ccl_device_inline float3 safe_divide_color(float3 a, float3 b)
Definition: util/math.h:605
@ PROFILING_SHADE_VOLUME_INTEGRATE
@ PROFILING_SHADE_VOLUME_SETUP
@ PROFILING_SHADE_VOLUME_DIRECT_LIGHT
@ PROFILING_SHADE_VOLUME_INDIRECT_LIGHT
ccl_device VolumeSampleMethod volume_stack_sample_method(KernelGlobals kg, IntegratorState state)
Definition: volume_stack.h:173
ccl_device_inline void volume_stack_clean(KernelGlobals kg, IntegratorState state)
Definition: volume_stack.h:114
VolumeSampleMethod
Definition: volume_stack.h:166
@ VOLUME_SAMPLE_DISTANCE
Definition: volume_stack.h:168
@ VOLUME_SAMPLE_MIS
Definition: volume_stack.h:170
@ VOLUME_SAMPLE_EQUIANGULAR
Definition: volume_stack.h:169
ccl_device float volume_stack_step_size(KernelGlobals kg, StackReadOp stack_read)
Definition: volume_stack.h:126
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
Definition: voxel.c:13