Blender  V3.3
shade_light.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 
8 #include "kernel/light/light.h"
9 #include "kernel/light/sample.h"
10 
12 
16 {
17  /* Setup light sample. */
20 
21  float3 ray_P = INTEGRATOR_STATE(state, ray, P);
22  const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
23  const float ray_time = INTEGRATOR_STATE(state, ray, time);
24 
25  /* Advance ray to new start distance. */
26  INTEGRATOR_STATE_WRITE(state, ray, tmin) = intersection_t_offset(isect.t);
27 
29  const bool use_light_sample = light_sample_from_intersection(kg, &isect, ray_P, ray_D, &ls);
30 
31  if (!use_light_sample) {
32  return;
33  }
34 
35  /* Use visibility flag to skip lights. */
36 #ifdef __PASSES__
37  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
38 
39  if (ls.shader & SHADER_EXCLUDE_ANY) {
40  if (((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) ||
41  ((ls.shader & SHADER_EXCLUDE_GLOSSY) &&
42  ((path_flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) ==
44  ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)) ||
45  ((ls.shader & SHADER_EXCLUDE_SCATTER) && (path_flag & PATH_RAY_VOLUME_SCATTER)))
46  return;
47  }
48 #endif
49 
50  /* Evaluate light shader. */
51  /* TODO: does aliasing like this break automatic SoA in CUDA? */
52  ShaderDataTinyStorage emission_sd_storage;
53  ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
54  float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time);
55  if (is_zero(light_eval)) {
56  return;
57  }
58 
59  /* MIS weighting. */
60  if (!(path_flag & PATH_RAY_MIS_SKIP)) {
61  /* multiple importance sampling, get regular light pdf,
62  * and compute weight with respect to BSDF pdf */
63  const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
64  const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
65  light_eval *= mis_weight;
66  }
67 
68  /* Write to render buffer. */
69  const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
70  kernel_accum_emission(kg, state, throughput * light_eval, render_buffer, ls.group);
71 }
72 
76 {
78 
80 
81  /* TODO: we could get stuck in an infinite loop if there are precision issues
82  * and the same light is hit again.
83  *
84  * As a workaround count this as a transparent bounce. It makes some sense
85  * to interpret lights as transparent surfaces (and support making them opaque),
86  * but this needs to be revisited. */
87  uint32_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce) + 1;
88  INTEGRATOR_STATE_WRITE(state, path, transparent_bounce) = transparent_bounce;
89 
90  if (transparent_bounce >= kernel_data.integrator.transparent_max_bounce) {
92  return;
93  }
94  else {
96  state,
99  return;
100  }
101 
102  /* TODO: in some cases we could continue directly to SHADE_BACKGROUND, but
103  * probably that optimization is probably not practical if we add lights to
104  * scene geometry. */
105 }
106 
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
#define ccl_restrict
Definition: cuda/compat.h:50
#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 ccl_global
Definition: cuda/compat.h:43
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
ccl_device_forceinline float intersection_t_offset(const float t)
ccl_device_inline float light_sample_mis_weight_forward(KernelGlobals kg, const float forward_pdf, const float nee_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)
double time
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
const int state
ccl_device bool light_sample_from_intersection(KernelGlobals kg, ccl_private const Intersection *ccl_restrict isect, const float3 ray_P, const float3 ray_D, ccl_private LightSample *ccl_restrict ls)
#define AS_SHADER_DATA(shader_data_tiny_storage)
Definition: kernel/types.h:943
@ PATH_RAY_REFLECT
Definition: kernel/types.h:195
@ PATH_RAY_TRANSMIT
Definition: kernel/types.h:196
@ PATH_RAY_VOLUME_SCATTER
Definition: kernel/types.h:201
@ PATH_RAY_MIS_SKIP
Definition: kernel/types.h:225
@ PATH_RAY_GLOSSY
Definition: kernel/types.h:198
@ PATH_RAY_DIFFUSE
Definition: kernel/types.h:197
ShaderDataTinyStorage
Definition: kernel/types.h:933
ShaderData
Definition: kernel/types.h:925
@ SHADER_EXCLUDE_DIFFUSE
Definition: kernel/types.h:439
@ SHADER_EXCLUDE_ANY
Definition: kernel/types.h:445
@ SHADER_EXCLUDE_SCATTER
Definition: kernel/types.h:443
@ SHADER_EXCLUDE_GLOSSY
Definition: kernel/types.h:440
@ SHADER_EXCLUDE_TRANSMIT
Definition: kernel/types.h:441
@ DEVICE_KERNEL_INTEGRATOR_SHADE_LIGHT
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST
#define PROFILING_INIT(kg, event)
static float P(float k)
Definition: math_interp.c:25
bool is_zero(const T &a)
ccl_device void integrator_shade_light(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
Definition: shade_light.h:73
CCL_NAMESPACE_BEGIN ccl_device_inline void integrate_light(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
Definition: shade_light.h:13
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
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 void integrator_state_read_isect(KernelGlobals kg, ConstIntegratorState state, ccl_private Intersection *ccl_restrict isect)
Definition: state_util.h:79
unsigned int uint32_t
Definition: stdint.h:80
@ PROFILING_SHADE_LIGHT_SETUP
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
Definition: voxel.c:13