Blender V4.3
shade_background.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
9
12
13#include "kernel/light/light.h"
14#include "kernel/light/sample.h"
15
17
21{
22 const int shader = kernel_data.background.surface_shader;
23 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
24
25 /* Use visibility flag to skip lights. */
26 if (!is_light_shader_visible_to_path(shader, path_flag)) {
27 return zero_spectrum();
28 }
29
30 /* Use fast constant background color if available. */
32 if (surface_shader_constant_emission(kg, shader, &L)) {
33 return L;
34 }
35
36 /* Evaluate background shader. */
37
38 /* TODO: does aliasing like this break automatic SoA in CUDA?
39 * Should we instead store closures separate from ShaderData? */
40 ShaderDataTinyStorage emission_sd_storage;
41 ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
42
45 emission_sd,
47 INTEGRATOR_STATE(state, ray, D),
48 INTEGRATOR_STATE(state, ray, time));
49
50 PROFILING_SHADER(emission_sd->object, emission_sd->shader);
53 kg, state, emission_sd, render_buffer, path_flag | PATH_RAY_EMISSION);
54
55 return surface_shader_background(emission_sd);
56}
57
61{
62 /* Accumulate transparency for transparent background. We can skip background
63 * shader evaluation unless a background pass is used. */
64 bool eval_background = true;
65 float transparent = 0.0f;
66
67 int path_flag = INTEGRATOR_STATE(state, path, flag);
68 const bool is_transparent_background_ray = kernel_data.background.transparent &&
70
71 if (is_transparent_background_ray) {
72 transparent = average(INTEGRATOR_STATE(state, path, throughput));
73
74#ifdef __PASSES__
75 eval_background = (kernel_data.film.light_pass_flag & PASSMASK(BACKGROUND));
76#else
77 eval_background = false;
78#endif
79 }
80
81#ifdef __MNEE__
83 if (kernel_data.background.use_mis) {
84 for (int lamp = 0; lamp < kernel_data.integrator.num_lights; lamp++) {
85 /* This path should have been resolved with mnee, it will
86 * generate a firefly for small lights since it is improbable. */
87 const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
88 if (klight->type == LIGHT_BACKGROUND && klight->use_caustics) {
89 eval_background = false;
90 break;
91 }
92 }
93 }
94 }
95#endif /* __MNEE__ */
96
97 /* Evaluate background shader. */
99
100 if (eval_background) {
102
103 /* When using the ao bounces approximation, adjust background
104 * shader intensity with ao factor. */
105 if (path_state_ao_bounce(kg, state)) {
106 L *= kernel_data.integrator.ao_bounces_factor;
107 }
108
109 /* Background MIS weights. */
110 const float mis_weight = light_sample_mis_weight_forward_background(kg, state, path_flag);
111
112 guiding_record_background(kg, state, L, mis_weight);
113 L *= mis_weight;
114 }
115
116 /* Write to render buffer. */
117 film_write_background(kg, state, L, transparent, is_transparent_background_ray, render_buffer);
119}
120
124{
125 const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
126 const float ray_time = INTEGRATOR_STATE(state, ray, time);
128 for (int lamp = 0; lamp < kernel_data.integrator.num_lights; lamp++) {
129 if (distant_light_sample_from_intersection(kg, ray_D, lamp, &ls)) {
130 /* Use visibility flag to skip lights. */
131#ifdef __PASSES__
132 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
133 if (!is_light_shader_visible_to_path(ls.shader, path_flag)) {
134 continue;
135 }
136#endif
137
138#ifdef __LIGHT_LINKING__
140 !(path_flag & PATH_RAY_CAMERA))
141 {
142 continue;
143 }
144#endif
145#ifdef __SHADOW_LINKING__
146 if (kernel_data_fetch(lights, lamp).shadow_set_membership != LIGHT_LINK_MASK_ALL) {
147 continue;
148 }
149#endif
150
151#ifdef __MNEE__
153 /* This path should have been resolved with mnee, it will
154 * generate a firefly for small lights since it is improbable. */
155 const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
156 if (klight->use_caustics)
157 continue;
158 }
159#endif /* __MNEE__ */
160
161 /* Evaluate light shader. */
162 /* TODO: does aliasing like this break automatic SoA in CUDA? */
163 ShaderDataTinyStorage emission_sd_storage;
164 ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
165 Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time);
166 if (is_zero(light_eval)) {
167 continue;
168 }
169
170 /* MIS weighting. */
171 const float mis_weight = light_sample_mis_weight_forward_distant(kg, state, path_flag, &ls);
172
173 /* Write to render buffer. */
174 guiding_record_background(kg, state, light_eval, mis_weight);
175 film_write_surface_emission(kg, state, light_eval, mis_weight, render_buffer, ls.group);
176 }
177 }
178}
179
183{
185
186 /* TODO: unify these in a single loop to only have a single shader evaluation call. */
189
190#ifdef __SHADOW_CATCHER__
192 /* Special case for shadow catcher where we want to fill the background pass
193 * behind the shadow catcher but also continue tracing the path. */
194 INTEGRATOR_STATE_WRITE(state, path, flag) &= ~PATH_RAY_SHADOW_CATCHER_BACKGROUND;
195 integrator_intersect_next_kernel_after_shadow_catcher_background<
197 return;
198 }
199#endif
200
202}
203
CCL_NAMESPACE_BEGIN ccl_device_noinline_cpu Spectrum 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 float light_sample_mis_weight_forward_background(KernelGlobals kg, IntegratorState state, const uint32_t path_flag)
ccl_device_inline float light_sample_mis_weight_forward_distant(KernelGlobals kg, IntegratorState state, const uint32_t path_flag, const ccl_private LightSample *ls)
ccl_device_inline void film_write_data_passes_background(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_restrict
#define ccl_optional_struct_init
#define ccl_device
#define ccl_private
#define ccl_device_inline
#define ccl_global
#define CCL_NAMESPACE_END
ccl_device bool distant_light_sample_from_intersection(KernelGlobals kg, const float3 ray_D, const int lamp, ccl_private LightSample *ccl_restrict ls)
Definition distant.h:82
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
ccl_device_forceinline void guiding_record_background(KernelGlobals kg, IntegratorState state, const Spectrum L, const float mis_weight)
ccl_device_inline bool light_link_light_match(KernelGlobals kg, const int object_receiver, const int light_emitter)
ccl_device_inline int light_link_receiver_forward(KernelGlobals kg, IntegratorState state)
@ PATH_MNEE_CULL_LIGHT_CONNECTION
#define AS_SHADER_DATA(shader_data_tiny_storage)
@ PATH_RAY_EMISSION
@ PATH_RAY_TRANSPARENT_BACKGROUND
@ PATH_RAY_SHADOW_CATCHER_BACKGROUND
@ PATH_RAY_CAMERA
ShaderDataTinyStorage
ShaderData
#define PASSMASK(pass)
#define LIGHT_LINK_MASK_ALL
@ LIGHT_BACKGROUND
@ 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 bool is_light_shader_visible_to_path(const int shader, const uint32_t path_flag)
ccl_device_inline void film_write_background(KernelGlobals kg, ConstIntegratorState state, const Spectrum L, const float transparent, const bool is_transparent_background_ray, ccl_global float *ccl_restrict render_buffer)
ccl_device_inline void film_write_surface_emission(KernelGlobals kg, ConstIntegratorState state, const Spectrum L, const float mis_weight, ccl_global float *ccl_restrict render_buffer, const int lightgroup=LIGHTGROUP_NONE)
ccl_device_inline bool is_zero(const float2 a)
ccl_device_inline float average(const float2 a)
static ulong state[N]
#define L
ccl_device_inline bool path_state_ao_bounce(KernelGlobals kg, ConstIntegratorState state)
Definition path_state.h:287
CCL_NAMESPACE_BEGIN ccl_device Spectrum 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)
IntegratorStateCPU *ccl_restrict IntegratorState
Definition state.h:228
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
Definition state.h:236
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition state.h:235
ccl_device_forceinline void integrator_path_terminate(KernelGlobals kg, IntegratorState state, const DeviceKernel current_kernel)
Definition state_flow.h:178
unsigned int uint32_t
Definition stdint.h:80
ccl_device bool surface_shader_constant_emission(KernelGlobals kg, int shader, ccl_private Spectrum *eval)
ccl_device void surface_shader_eval(KernelGlobals kg, ConstIntegratorGenericState state, ccl_private ShaderData *ccl_restrict sd, ccl_global float *ccl_restrict buffer, uint32_t path_flag, bool use_caustics_storage=false)
ccl_device Spectrum surface_shader_background(ccl_private const ShaderData *sd)
#define zero_spectrum
SPECTRUM_DATA_TYPE Spectrum
@ PROFILING_SHADE_LIGHT_SETUP
@ PROFILING_SHADE_LIGHT_EVAL
uint8_t flag
Definition wm_window.cc:138