Blender V4.5
shade_shadow.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
11
13
15
20
21#ifdef __TRANSPARENT_SHADOWS__
22ccl_device_inline Spectrum integrate_transparent_surface_shadow(KernelGlobals kg,
24 const int hit)
25{
27
28 /* TODO: does aliasing like this break automatic SoA in CUDA?
29 * Should we instead store closures separate from ShaderData?
30 *
31 * TODO: is it better to declare this outside the loop or keep it local
32 * so the compiler can see there is no dependency between iterations? */
33 ShaderDataTinyStorage shadow_sd_storage;
34 ccl_private ShaderData *shadow_sd = AS_SHADER_DATA(&shadow_sd_storage);
35
36 /* Setup shader data at surface. */
39
42
43 shader_setup_from_ray(kg, shadow_sd, &ray, &isect);
44
45 /* Evaluate shader. */
46 if (!(shadow_sd->flag & SD_HAS_ONLY_VOLUME)) {
48 kg, state, shadow_sd, nullptr, PATH_RAY_SHADOW);
49 }
50
51# ifdef __VOLUME__
52 /* Exit/enter volume. */
53 shadow_volume_stack_enter_exit(kg, state, shadow_sd);
54# endif
55
56 /* Disable transparent shadows for ray portals */
57 if (shadow_sd->flag & SD_RAY_PORTAL) {
58 return zero_spectrum();
59 }
60
61 /* Compute transparency from closures. */
62 return surface_shader_transparency(kg, shadow_sd);
63}
64
65# ifdef __VOLUME__
66ccl_device_inline void integrate_transparent_volume_shadow(KernelGlobals kg,
68 const int hit,
69 const int num_recorded_hits,
71 throughput)
72{
74
75 /* TODO: deduplicate with surface, or does it not matter for memory usage? */
76 ShaderDataTinyStorage shadow_sd_storage;
77 ccl_private ShaderData *shadow_sd = AS_SHADER_DATA(&shadow_sd_storage);
78
79 /* Setup shader data. */
82 ray.self.object = OBJECT_NONE;
83 ray.self.prim = PRIM_NONE;
84 ray.self.light_object = OBJECT_NONE;
85 ray.self.light_prim = PRIM_NONE;
86 /* Modify ray position and length to match current segment. */
87 ray.tmin = (hit == 0) ? ray.tmin : INTEGRATOR_STATE_ARRAY(state, shadow_isect, hit - 1, t);
88 ray.tmax = (hit < num_recorded_hits) ? INTEGRATOR_STATE_ARRAY(state, shadow_isect, hit, t) :
89 ray.tmax;
90
91 /* `object` is only needed for light tree with light linking, it is irrelevant for shadow. */
92 shader_setup_from_volume(kg, shadow_sd, &ray, OBJECT_NONE);
93
94 VOLUME_READ_LAMBDA(integrator_state_read_shadow_volume_stack(state, i));
95 const float step_size = volume_stack_step_size(kg, volume_read_lambda_pass);
96
97 volume_shadow_heterogeneous(kg, state, &ray, shadow_sd, throughput, step_size);
98}
99# endif
100
101ccl_device_inline bool integrate_transparent_shadow(KernelGlobals kg,
103 const uint num_hits)
104{
105 /* Accumulate shadow for transparent surfaces. */
106 const uint num_recorded_hits = min(num_hits, (uint)INTEGRATOR_SHADOW_ISECT_SIZE);
107
108 /* Plus one to account for world volume, which has no boundary to hit but casts shadows. */
109 for (uint hit = 0; hit < num_recorded_hits + 1; hit++) {
110 /* Volume shaders. */
111 if (hit < num_recorded_hits || !shadow_intersections_has_remaining(num_hits)) {
112# ifdef __VOLUME__
113 if (!integrator_state_shadow_volume_stack_is_empty(kg, state)) {
114 Spectrum throughput = INTEGRATOR_STATE(state, shadow_path, throughput);
115 integrate_transparent_volume_shadow(kg, state, hit, num_recorded_hits, &throughput);
116 if (is_zero(throughput)) {
117 return true;
118 }
119
120 INTEGRATOR_STATE_WRITE(state, shadow_path, throughput) = throughput;
121 }
122# endif
123 }
124
125 /* Surface shaders. */
126 if (hit < num_recorded_hits) {
127 const Spectrum shadow = integrate_transparent_surface_shadow(kg, state, hit);
128 const Spectrum throughput = INTEGRATOR_STATE(state, shadow_path, throughput) * shadow;
129 if (is_zero(throughput)) {
130 return true;
131 }
132
133 INTEGRATOR_STATE_WRITE(state, shadow_path, throughput) = throughput;
134 INTEGRATOR_STATE_WRITE(state, shadow_path, transparent_bounce) += 1;
135 INTEGRATOR_STATE_WRITE(state, shadow_path, rng_offset) += PRNG_BOUNCE_NUM;
136 }
137
138 /* Note we do not need to check max_transparent_bounce here, the number
139 * of intersections is already limited and made opaque in the
140 * INTERSECT_SHADOW kernel. */
141 }
142
144 /* There are more hits that we could not recorded due to memory usage,
145 * adjust ray to intersect again from the last hit. */
146 const float last_hit_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, num_recorded_hits - 1, t);
147 INTEGRATOR_STATE_WRITE(state, shadow_ray, tmin) = intersection_t_offset(last_hit_t);
148 }
149
150 return false;
151}
152#endif /* __TRANSPARENT_SHADOWS__ */
153
157{
159 const uint num_hits = INTEGRATOR_STATE(state, shadow_path, num_hits);
160
161#ifdef __TRANSPARENT_SHADOWS__
162 /* Evaluate transparent shadows. */
163 const bool opaque = integrate_transparent_shadow(kg, state, num_hits);
164 if (opaque) {
166 return;
167 }
168#endif
169
171 /* More intersections to find, continue shadow ray. */
173 state,
176 return;
177 }
178
182}
183
unsigned int uint
ccl_device_forceinline float intersection_t_offset(const float t)
#define ccl_restrict
#define ccl_optional_struct_init
#define AS_SHADER_DATA(shader_data_tiny_storage)
#define PRIM_NONE
#define INTEGRATOR_SHADOW_ISECT_SIZE
#define ccl_device
#define zero_spectrum
#define OBJECT_NONE
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define ccl_global
#define CCL_NAMESPACE_END
#define VOLUME_READ_LAMBDA(function_call)
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
ccl_device_forceinline void guiding_record_direct_light(KernelGlobals kg, IntegratorShadowState state)
@ SD_HAS_ONLY_VOLUME
@ SD_RAY_PORTAL
ShaderData ShaderDataTinyStorage
@ PRNG_BOUNCE_NUM
@ PATH_RAY_SHADOW
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW
ccl_device_inline void film_write_direct_light(KernelGlobals kg, ConstIntegratorShadowState state, ccl_global float *ccl_restrict render_buffer)
ccl_device_inline bool is_zero(const float2 a)
static ulong state[N]
#define PROFILING_INIT(kg, event)
Definition profiler.h:14
@ PROFILING_SHADE_SHADOW_SURFACE
Definition profiling.h:39
@ PROFILING_SHADE_SHADOW_VOLUME
Definition profiling.h:40
@ PROFILING_SHADE_SHADOW_SETUP
Definition profiling.h:38
ccl_device void integrator_shade_shadow(KernelGlobals kg, IntegratorShadowState state, ccl_global float *ccl_restrict render_buffer)
CCL_NAMESPACE_BEGIN ccl_device_inline bool shadow_intersections_has_remaining(const uint num_hits)
ccl_device_inline void shader_setup_from_ray(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const ccl_private Ray *ccl_restrict ray, const ccl_private Intersection *ccl_restrict isect)
Definition shader_data.h:39
#define min(a, b)
Definition sort.cc:36
IntegratorShadowStateCPU * IntegratorShadowState
Definition state.h:230
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
Definition state.h:236
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition state.h:235
#define INTEGRATOR_STATE_ARRAY(state, nested_struct, array_index, member)
Definition state.h:238
ccl_device_forceinline void integrator_shadow_path_terminate(KernelGlobals kg, IntegratorShadowState state, const DeviceKernel current_kernel)
Definition state_flow.h:221
ccl_device_forceinline void integrator_shadow_path_next(KernelGlobals kg, IntegratorShadowState state, const DeviceKernel current_kernel, const DeviceKernel next_kernel)
Definition state_flow.h:212
ccl_device_forceinline void integrator_state_read_shadow_ray(ConstIntegratorShadowState state, ccl_private Ray *ccl_restrict ray)
Definition state_util.h:86
ccl_device_forceinline void integrator_state_read_shadow_isect(ConstIntegratorShadowState state, ccl_private Intersection *ccl_restrict isect, const int index)
Definition state_util.h:297
ccl_device void surface_shader_eval(KernelGlobals kg, ConstIntegratorGenericState state, ccl_private ShaderData *ccl_restrict sd, ccl_global float *ccl_restrict buffer, const uint32_t path_flag, bool use_caustics_storage=false)
ccl_device Spectrum surface_shader_transparency(KernelGlobals kg, const ccl_private ShaderData *sd)
i
Definition text_draw.cc:230
float3 Spectrum