Blender V4.3
shade_light.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
10#include "kernel/light/sample.h"
11
13
17{
18 /* Setup light sample. */
21
23
24 float3 ray_P = INTEGRATOR_STATE(state, ray, P);
25 const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
26 const float ray_time = INTEGRATOR_STATE(state, ray, time);
27 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
28 const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
29
30 /* Advance ray to new start distance. */
32
34 const bool use_light_sample = light_sample_from_intersection(
35 kg, &isect, ray_P, ray_D, N, path_flag, &ls);
36
37 if (!use_light_sample) {
38 return;
39 }
40
41 /* Use visibility flag to skip lights. */
42#ifdef __PASSES__
43 if (!is_light_shader_visible_to_path(ls.shader, path_flag)) {
44 return;
45 }
46#endif
47
48 /* Evaluate light shader. */
49 /* TODO: does aliasing like this break automatic SoA in CUDA? */
50 ShaderDataTinyStorage emission_sd_storage;
51 ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
52 Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time);
53 if (is_zero(light_eval)) {
54 return;
55 }
56
57 /* MIS weighting. */
58 const float mis_weight = light_sample_mis_weight_forward_lamp(kg, state, path_flag, &ls, ray_P);
59
60 /* Write to render buffer. */
61 guiding_record_surface_emission(kg, state, light_eval, mis_weight);
62 film_write_surface_emission(kg, state, light_eval, mis_weight, render_buffer, ls.group);
63}
64
68{
70
72
73 /* TODO: we could get stuck in an infinite loop if there are precision issues
74 * and the same light is hit again.
75 *
76 * As a workaround count this as a transparent bounce. It makes some sense
77 * to interpret lights as transparent surfaces (and support making them opaque),
78 * but this needs to be revisited. */
79 uint32_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce) + 1;
80 INTEGRATOR_STATE_WRITE(state, path, transparent_bounce) = transparent_bounce;
81
82 if (transparent_bounce >= kernel_data.integrator.transparent_max_bounce) {
84 return;
85 }
86 else {
88 state,
91 return;
92 }
93
94 /* TODO: in some cases we could continue directly to SHADE_BACKGROUND, but
95 * probably that optimization is probably not practical if we add lights to
96 * scene geometry. */
97}
98
ccl_device_forceinline float intersection_t_offset(const float t)
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_lamp(KernelGlobals kg, IntegratorState state, const uint32_t path_flag, const ccl_private LightSample *ls, const float3 P)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#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_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
ccl_device_forceinline void guiding_record_surface_emission(KernelGlobals kg, IntegratorState state, const Spectrum Le, const float mis_weight)
ccl_device_forceinline void guiding_record_light_surface_segment(KernelGlobals kg, IntegratorState state, ccl_private const Intersection *ccl_restrict isect)
ccl_device bool light_sample_from_intersection(KernelGlobals kg, ccl_private const Intersection *ccl_restrict isect, const float3 ray_P, const float3 ray_D, const float3 N, const uint32_t path_flag, ccl_private LightSample *ccl_restrict ls)
#define AS_SHADER_DATA(shader_data_tiny_storage)
ShaderDataTinyStorage
ShaderData
@ DEVICE_KERNEL_INTEGRATOR_SHADE_LIGHT
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST
#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_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)
static ulong state[N]
#define N
ccl_device void integrator_shade_light(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
Definition shade_light.h:65
CCL_NAMESPACE_BEGIN ccl_device_inline void integrate_light(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
Definition shade_light.h:14
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
ccl_device_forceinline void integrator_path_next(KernelGlobals kg, IntegratorState state, const DeviceKernel current_kernel, const DeviceKernel next_kernel)
Definition state_flow.h:169
ccl_device_forceinline void integrator_state_read_isect(ConstIntegratorState state, ccl_private Intersection *ccl_restrict isect)
Definition state_util.h:158
unsigned int uint32_t
Definition stdint.h:80
SPECTRUM_DATA_TYPE Spectrum
@ PROFILING_SHADE_LIGHT_SETUP
uint8_t flag
Definition wm_window.cc:138