Blender  V3.3
shade_background.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 #ifdef __BACKGROUND__
18  const int shader = kernel_data.background.surface_shader;
19  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
20 
21  /* Use visibility flag to skip lights. */
22  if (shader & SHADER_EXCLUDE_ANY) {
23  if (((shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) ||
24  ((shader & SHADER_EXCLUDE_GLOSSY) && ((path_flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) ==
26  ((shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)) ||
27  ((shader & SHADER_EXCLUDE_CAMERA) && (path_flag & PATH_RAY_CAMERA)) ||
28  ((shader & SHADER_EXCLUDE_SCATTER) && (path_flag & PATH_RAY_VOLUME_SCATTER)))
29  return zero_float3();
30  }
31 
32  /* Use fast constant background color if available. */
33  float3 L = zero_float3();
34  if (!shader_constant_emission_eval(kg, shader, &L)) {
35  /* Evaluate background shader. */
36 
37  /* TODO: does aliasing like this break automatic SoA in CUDA?
38  * Should we instead store closures separate from ShaderData? */
39  ShaderDataTinyStorage emission_sd_storage;
40  ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
41 
44  emission_sd,
45  INTEGRATOR_STATE(state, ray, P),
46  INTEGRATOR_STATE(state, ray, D),
47  INTEGRATOR_STATE(state, ray, time));
48 
49  PROFILING_SHADER(emission_sd->object, emission_sd->shader);
51  shader_eval_surface<KERNEL_FEATURE_NODE_MASK_SURFACE_BACKGROUND>(
52  kg, state, emission_sd, render_buffer, path_flag | PATH_RAY_EMISSION);
53 
54  L = shader_background_eval(emission_sd);
55  }
56 
57  /* Background MIS weights. */
58 # ifdef __BACKGROUND_MIS__
59  /* Check if background light exists or if we should skip pdf. */
60  if (!(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_MIS_SKIP) &&
61  kernel_data.background.use_mis) {
62  const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
63  const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
64  const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
65 
66  /* multiple importance sampling, get background light pdf for ray
67  * direction, and compute weight with respect to BSDF pdf */
68  const float pdf = background_light_pdf(kg, ray_P, ray_D);
69  const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf);
70  L *= mis_weight;
71  }
72 # endif
73 
74  return L;
75 #else
76  return make_float3(0.8f, 0.8f, 0.8f);
77 #endif
78 }
79 
83 {
84  /* Accumulate transparency for transparent background. We can skip background
85  * shader evaluation unless a background pass is used. */
86  bool eval_background = true;
87  float transparent = 0.0f;
88 
89  const bool is_transparent_background_ray = kernel_data.background.transparent &&
90  (INTEGRATOR_STATE(state, path, flag) &
92 
93  if (is_transparent_background_ray) {
94  transparent = average(INTEGRATOR_STATE(state, path, throughput));
95 
96 #ifdef __PASSES__
97  eval_background = (kernel_data.film.light_pass_flag & PASSMASK(BACKGROUND));
98 #else
99  eval_background = false;
100 #endif
101  }
102 
103 #ifdef __MNEE__
105  if (kernel_data.background.use_mis) {
106  for (int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
107  /* This path should have been resolved with mnee, it will
108  * generate a firefly for small lights since it is improbable. */
109  const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
110  if (klight->type == LIGHT_BACKGROUND && klight->use_caustics) {
111  eval_background = false;
112  break;
113  }
114  }
115  }
116  }
117 #endif /* __MNEE__ */
118 
119  /* Evaluate background shader. */
120  float3 L = (eval_background) ? integrator_eval_background_shader(kg, state, render_buffer) :
121  zero_float3();
122 
123  /* When using the ao bounces approximation, adjust background
124  * shader intensity with ao factor. */
125  if (path_state_ao_bounce(kg, state)) {
126  L *= kernel_data.integrator.ao_bounces_factor;
127  }
128 
129  /* Write to render buffer. */
130  kernel_accum_background(kg, state, L, transparent, is_transparent_background_ray, render_buffer);
131 }
132 
136 {
137  const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
138  const float ray_time = INTEGRATOR_STATE(state, ray, time);
140  for (int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
141  if (light_sample_from_distant_ray(kg, ray_D, lamp, &ls)) {
142  /* Use visibility flag to skip lights. */
143 #ifdef __PASSES__
144  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
145 
146  if (ls.shader & SHADER_EXCLUDE_ANY) {
147  if (((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) ||
148  ((ls.shader & SHADER_EXCLUDE_GLOSSY) &&
149  ((path_flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) ==
151  ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)) ||
152  ((ls.shader & SHADER_EXCLUDE_CAMERA) && (path_flag & PATH_RAY_CAMERA)) ||
153  ((ls.shader & SHADER_EXCLUDE_SCATTER) && (path_flag & PATH_RAY_VOLUME_SCATTER)))
154  return;
155  }
156 #endif
157 
158 #ifdef __MNEE__
160  /* This path should have been resolved with mnee, it will
161  * generate a firefly for small lights since it is improbable. */
162  const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
163  if (klight->use_caustics)
164  return;
165  }
166 #endif /* __MNEE__ */
167 
168  /* Evaluate light shader. */
169  /* TODO: does aliasing like this break automatic SoA in CUDA? */
170  ShaderDataTinyStorage emission_sd_storage;
171  ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
172  float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time);
173  if (is_zero(light_eval)) {
174  return;
175  }
176 
177  /* MIS weighting. */
178  if (!(path_flag & PATH_RAY_MIS_SKIP)) {
179  /* multiple importance sampling, get regular light pdf,
180  * and compute weight with respect to BSDF pdf */
181  const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
182  const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
183  light_eval *= mis_weight;
184  }
185 
186  /* Write to render buffer. */
187  const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
188  kernel_accum_emission(kg, state, throughput * light_eval, render_buffer, ls.group);
189  }
190  }
191 }
192 
196 {
198 
199  /* TODO: unify these in a single loop to only have a single shader evaluation call. */
202 
203 #ifdef __SHADOW_CATCHER__
205  /* Special case for shadow catcher where we want to fill the background pass
206  * behind the shadow catcher but also continue tracing the path. */
208  integrator_intersect_next_kernel_after_shadow_catcher_background<
210  return;
211  }
212 #endif
213 
215 }
216 
ccl_device_inline void kernel_accum_background(KernelGlobals kg, ConstIntegratorState state, const float3 L, const float transparent, const bool is_transparent_background_ray, ccl_global float *ccl_restrict render_buffer)
Definition: accumulate.h:562
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_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
Light lamp
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
const int state
ccl_device float3 shader_background_eval(ccl_private const ShaderData *sd)
ccl_device bool shader_constant_emission_eval(KernelGlobals kg, int shader, ccl_private float3 *eval)
ccl_device bool light_sample_from_distant_ray(KernelGlobals kg, const float3 ray_D, const int lamp, ccl_private LightSample *ccl_restrict ls)
@ PATH_MNEE_CULL_LIGHT_CONNECTION
Definition: kernel/types.h:295
#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_EMISSION
Definition: kernel/types.h:255
@ 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
@ PATH_RAY_TRANSPARENT_BACKGROUND
Definition: kernel/types.h:235
@ PATH_RAY_SHADOW_CATCHER_BACKGROUND
Definition: kernel/types.h:288
@ PATH_RAY_CAMERA
Definition: kernel/types.h:194
ShaderDataTinyStorage
Definition: kernel/types.h:933
ShaderData
Definition: kernel/types.h:925
@ SHADER_EXCLUDE_CAMERA
Definition: kernel/types.h:442
@ 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
#define PASSMASK(pass)
Definition: kernel/types.h:331
@ LIGHT_BACKGROUND
Definition: kernel/types.h:458
@ DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND
#define PROFILING_INIT_FOR_SHADER(kg, event)
#define PROFILING_EVENT(event)
#define PROFILING_SHADER(object, shader)
#define PROFILING_INIT(kg, event)
ccl_device_inline float average(const float2 &a)
Definition: math_float2.h:170
ccl_device_inline float3 zero_float3()
Definition: math_float3.h:80
static float P(float k)
Definition: math_interp.c:25
#define L
#define make_float3(x, y, z)
Definition: metal/compat.h:204
bool is_zero(const T &a)
ccl_device_inline bool path_state_ao_bounce(KernelGlobals kg, ConstIntegratorState state)
Definition: path_state.h:255
CCL_NAMESPACE_BEGIN ccl_device float3 integrator_eval_background_shader(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
ccl_device_inline void integrate_background(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
ccl_device void integrator_shade_background(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
ccl_device_inline void integrate_distant_lights(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
ccl_device_inline void shader_setup_from_background(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const float3 ray_P, const float3 ray_D, const float ray_time)
Definition: shader_data.h:360
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
unsigned int uint32_t
Definition: stdint.h:80
@ PROFILING_SHADE_LIGHT_SETUP
@ PROFILING_SHADE_LIGHT_EVAL
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
Definition: voxel.c:13