Blender V4.3
cycles/kernel/light/sample.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
11#include "kernel/light/light.h"
12
13#ifdef __LIGHT_TREE__
14# include "kernel/light/tree.h"
15#endif
16
18#include "kernel/sample/mis.h"
19
21
22/* Evaluate shader on light. */
28 float time)
29{
30 /* setup shading at emitter */
31 Spectrum eval = zero_spectrum();
32
33 if (surface_shader_constant_emission(kg, ls->shader, &eval)) {
34 if ((ls->prim != PRIM_NONE) && dot(ls->Ng, ls->D) > 0.0f) {
35 ls->Ng = -ls->Ng;
36 }
37 }
38 else {
39 /* Setup shader data and call surface_shader_eval once, better
40 * for GPU coherence and compile times. */
42 if (ls->type == LIGHT_BACKGROUND) {
43 shader_setup_from_background(kg, emission_sd, ls->P, ls->D, time);
44 }
45 else {
47 emission_sd,
48 ls->P,
49 ls->Ng,
50 -ls->D,
51 ls->shader,
52 ls->object,
53 ls->prim,
54 ls->u,
55 ls->v,
56 ls->t,
57 time,
58 false,
59 ls->lamp);
60
61 ls->Ng = emission_sd->Ng;
62 }
63
64 PROFILING_SHADER(emission_sd->object, emission_sd->shader);
66
67 /* No proper path flag, we're evaluating this for all closures. that's
68 * weak but we'd have to do multiple evaluations otherwise. */
70 kg, state, emission_sd, NULL, PATH_RAY_EMISSION);
71
72 /* Evaluate closures. */
73 if (ls->type == LIGHT_BACKGROUND) {
74 eval = surface_shader_background(emission_sd);
75 }
76 else {
77 eval = surface_shader_emission(emission_sd);
78 }
79 }
80
81 eval *= ls->eval_fac;
82
83 if (ls->lamp != LAMP_NONE) {
84 ccl_global const KernelLight *klight = &kernel_data_fetch(lights, ls->lamp);
85 eval *= rgb_to_spectrum(
86 make_float3(klight->strength[0], klight->strength[1], klight->strength[2]));
87 }
88
89 return eval;
90}
91
92/* Early path termination of shadow rays. */
95 const float rand_terminate)
96{
97 if (bsdf_eval_is_zero(eval)) {
98 return true;
99 }
100
101 if (kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
102 float probability = reduce_max(fabs(bsdf_eval_sum(eval))) *
103 kernel_data.integrator.light_inv_rr_threshold;
104 if (probability < 1.0f) {
105 if (rand_terminate >= probability) {
106 return true;
107 }
108 bsdf_eval_mul(eval, 1.0f / probability);
109 }
110 }
111
112 return false;
113}
114
115/* This function should be used to compute a modified ray start position for
116 * rays leaving from a surface. The algorithm slightly distorts flat surface
117 * of a triangle. Surface is lifted by amount h along normal n in the incident
118 * point. */
119
122{
123 float3 V[3], N[3];
124
125 if (sd->type == PRIMITIVE_MOTION_TRIANGLE) {
126 motion_triangle_vertices_and_normals(kg, sd->object, sd->prim, sd->time, V, N);
127 }
128 else {
130 triangle_vertices_and_normals(kg, sd->prim, V, N);
131 }
132
133 const float u = 1.0f - sd->u - sd->v;
134 const float v = sd->u;
135 const float w = sd->v;
136 float3 P = V[0] * u + V[1] * v + V[2] * w; /* Local space */
137 float3 n = N[0] * u + N[1] * v + N[2] * w; /* We get away without normalization */
138
139 if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
140 object_dir_transform(kg, sd, &n); /* Normal x scale, to world space */
141 }
142
143 /* Parabolic approximation */
144 float a = dot(N[2] - N[0], V[0] - V[2]);
145 float b = dot(N[2] - N[1], V[1] - V[2]);
146 float c = dot(N[1] - N[0], V[1] - V[0]);
147 float h = a * u * (u - 1) + (a + b + c) * u * v + b * v * (v - 1);
148
149 /* Check flipped normals */
150 if (dot(n, Ng) > 0) {
151 /* Local linear envelope */
152 float h0 = max(max(dot(V[1] - V[0], N[0]), dot(V[2] - V[0], N[0])), 0.0f);
153 float h1 = max(max(dot(V[0] - V[1], N[1]), dot(V[2] - V[1], N[1])), 0.0f);
154 float h2 = max(max(dot(V[0] - V[2], N[2]), dot(V[1] - V[2], N[2])), 0.0f);
155 h0 = max(dot(V[0] - P, N[0]) + h0, 0.0f);
156 h1 = max(dot(V[1] - P, N[1]) + h1, 0.0f);
157 h2 = max(dot(V[2] - P, N[2]) + h2, 0.0f);
158 h = max(min(min(h0, h1), h2), h * 0.5f);
159 }
160 else {
161 float h0 = max(max(dot(V[0] - V[1], N[0]), dot(V[0] - V[2], N[0])), 0.0f);
162 float h1 = max(max(dot(V[1] - V[0], N[1]), dot(V[1] - V[2], N[1])), 0.0f);
163 float h2 = max(max(dot(V[2] - V[0], N[2]), dot(V[2] - V[1], N[2])), 0.0f);
164 h0 = max(dot(P - V[0], N[0]) + h0, 0.0f);
165 h1 = max(dot(P - V[1], N[1]) + h1, 0.0f);
166 h2 = max(dot(P - V[2], N[2]) + h2, 0.0f);
167 h = min(-min(min(h0, h1), h2), h * 0.5f);
168 }
169
170 return n * h;
171}
172
173/* Ray offset to avoid shadow terminator artifact. */
174
177 float3 L,
178 ccl_private bool *r_skip_self)
179{
180 float3 P = sd->P;
181
182 if ((sd->type & PRIMITIVE_TRIANGLE) && (sd->shader & SHADER_SMOOTH_NORMAL)) {
183 const float offset_cutoff =
184 kernel_data_fetch(objects, sd->object).shadow_terminator_geometry_offset;
185 /* Do ray offset (heavy stuff) only for close to be terminated triangles:
186 * offset_cutoff = 0.1f means that 10-20% of rays will be affected. Also
187 * make a smooth transition near the threshold. */
188 if (offset_cutoff > 0.0f) {
189 float NL = dot(sd->N, L);
190 const bool transmit = (NL < 0.0f);
191 if (NL < 0) {
192 NL = -NL;
193 }
194
195 const float3 Ng = (transmit ? -sd->Ng : sd->Ng);
196 const float NgL = dot(Ng, L);
197
198 const float offset_amount = (NL < offset_cutoff) ?
199 clamp(2.0f - (NgL + NL) / offset_cutoff, 0.0f, 1.0f) :
200 clamp(1.0f - NgL / offset_cutoff, 0.0f, 1.0f);
201
202 if (offset_amount > 0.0f) {
203 P += shadow_ray_smooth_surface_offset(kg, sd, Ng) * offset_amount;
204
205 /* Only skip self intersections if light direction and geometric normal point in the same
206 * direction, otherwise we're meant to hit this surface. */
207 *r_skip_self = (NgL > 0.0f);
208 }
209 }
210 }
211
212 return P;
213}
214
217 const float3 P,
218 ccl_private Ray *ray,
219 const bool skip_self)
220{
221 if (ls->shader & SHADER_CAST_SHADOW) {
222 /* setup ray */
223 ray->P = P;
224 ray->tmin = 0.0f;
225
226 if (ls->t == FLT_MAX) {
227 /* distant light */
228 ray->D = ls->D;
229 ray->tmax = ls->t;
230 }
231 else {
232 /* other lights, avoid self-intersection */
233 ray->D = ls->P - P;
234 ray->D = normalize_len(ray->D, &ray->tmax);
235 }
236 }
237 else {
238 /* signal to not cast shadow ray */
239 ray->P = zero_float3();
240 ray->D = zero_float3();
241 ray->tmax = 0.0f;
242 }
243
244 ray->dP = differential_make_compact(sd->dP);
245 ray->dD = differential_zero_compact();
246 ray->time = sd->time;
247
248 /* Fill in intersection surface and light details. */
249 ray->self.object = (skip_self) ? sd->object : OBJECT_NONE;
250 ray->self.prim = (skip_self) ? sd->prim : PRIM_NONE;
251 ray->self.light_object = ls->object;
252 ray->self.light_prim = ls->prim;
253 ray->self.light = ls->lamp;
254}
255
256/* Create shadow ray towards light sample. */
258 KernelGlobals kg,
261 ccl_private Ray *ray)
262{
263 bool skip_self = true;
264 const float3 P = shadow_ray_offset(kg, sd, ls->D, &skip_self);
265 shadow_ray_setup(sd, ls, P, ray, skip_self);
266}
267
268/* Create shadow ray towards light sample. */
270 KernelGlobals kg,
273 const float3 P,
274 ccl_private Ray *ray)
275{
276 shadow_ray_setup(sd, ls, P, ray, false);
277}
278
279/* Multiple importance sampling weights. */
280
282 const float forward_pdf,
283 const float nee_pdf)
284{
285#ifdef WITH_CYCLES_DEBUG
286 if (kernel_data.integrator.direct_light_sampling_type == DIRECT_LIGHT_SAMPLING_FORWARD) {
287 return 1.0f;
288 }
289 else if (kernel_data.integrator.direct_light_sampling_type == DIRECT_LIGHT_SAMPLING_NEE) {
290 return 0.0f;
291 }
292 else
293#endif
294 return power_heuristic(forward_pdf, nee_pdf);
295}
296
298 const float nee_pdf,
299 const float forward_pdf)
300{
301#ifdef WITH_CYCLES_DEBUG
302 if (kernel_data.integrator.direct_light_sampling_type == DIRECT_LIGHT_SAMPLING_FORWARD) {
303 /* Return 0.0f to only account for the contribution in forward path tracing, unless when the
304 * light can not be forward sampled, in which case return 1.0f so it converges to the same
305 * result. */
306 return (forward_pdf == 0.0f);
307 }
308 else if (kernel_data.integrator.direct_light_sampling_type == DIRECT_LIGHT_SAMPLING_NEE) {
309 return 1.0f;
310 }
311 else
312#endif
313 return power_heuristic(nee_pdf, forward_pdf);
314}
315
316/* Next event estimation sampling.
317 *
318 * Sample a position on a light in the scene, from a position on a surface or
319 * from a volume segment.
320 *
321 * Uses either a flat distribution or light tree. */
322
324 const float3 rand,
325 const float time,
326 const float3 P,
327 const float3 D,
328 const float t,
329 const int object_receiver,
330 const int bounce,
331 const uint32_t path_flag,
333{
334 const int shader_flags = SD_BSDF_HAS_TRANSMISSION;
335
336#ifdef __LIGHT_TREE__
337 if (kernel_data.integrator.use_light_tree) {
338 if (!light_tree_sample<true>(kg, rand.z, P, D, t, object_receiver, shader_flags, ls)) {
339 return false;
340 }
341 }
342 else
343#endif
344 {
345 if (!light_distribution_sample(kg, rand.z, ls)) {
346 return false;
347 }
348 }
349
350 /* Sample position on the selected light. */
351 return light_sample<true>(
352 kg, rand, time, P, D, object_receiver, shader_flags, bounce, path_flag, ls);
353}
354
356 const float3 rand,
357 const float time,
358 const float3 P,
359 const float3 N,
360 const int object_receiver,
361 const int shader_flags,
362 const int bounce,
363 const uint32_t path_flag,
365{
366 /* Randomly select a light. */
367#ifdef __LIGHT_TREE__
368 if (kernel_data.integrator.use_light_tree) {
369 if (!light_tree_sample<false>(kg, rand.z, P, N, 0.0f, object_receiver, shader_flags, ls)) {
370 return false;
371 }
372 }
373 else
374#endif
375 {
376 if (!light_distribution_sample(kg, rand.z, ls)) {
377 return false;
378 }
379 }
380
381 /* Sample position on the selected light. */
382 return light_sample<false>(
383 kg, rand, time, P, N, object_receiver, shader_flags, bounce, path_flag, ls);
384}
385
386/* Update light sample with new shading point position for MNEE. The position on the light is fixed
387 * except for directional light. */
390 const float3 P,
391 const float3 N,
392 const uint32_t path_flag)
393{
394 const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ls->lamp);
395
396 if (ls->type == LIGHT_POINT) {
397 point_light_mnee_sample_update(klight, ls, P, N, path_flag);
398 }
399 else if (ls->type == LIGHT_SPOT) {
400 spot_light_mnee_sample_update(klight, ls, P, N, path_flag);
401 }
402 else if (ls->type == LIGHT_AREA) {
403 area_light_mnee_sample_update(klight, ls, P);
404 }
405 else {
406 /* Keep previous values. */
407 }
408
409 /* Re-apply already computed selection pdf. */
410 ls->pdf *= ls->pdf_selection;
411}
412
413/* Forward sampling.
414 *
415 * Multiple importance sampling weights for hitting surface, light or background
416 * through indirect light ray.
417 *
418 * The BSDF or phase pdf from the previous bounce was stored in mis_ray_pdf and
419 * is used for balancing with the light sampling pdf. */
420
423 const uint32_t path_flag,
424 const ccl_private ShaderData *sd)
425{
426 bool has_mis = !(path_flag & PATH_RAY_MIS_SKIP) &&
427 (sd->flag & ((sd->flag & SD_BACKFACING) ? SD_MIS_BACK : SD_MIS_FRONT));
428
429#ifdef __HAIR__
430 has_mis &= (sd->type & PRIMITIVE_TRIANGLE);
431#endif
432
433 if (!has_mis) {
434 return 1.0f;
435 }
436
437 const float bsdf_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
438 const float t = sd->ray_length;
439 float pdf = triangle_light_pdf(kg, sd, t);
440
441 /* Light selection pdf. */
442#ifdef __LIGHT_TREE__
443 if (kernel_data.integrator.use_light_tree) {
444 float3 ray_P = INTEGRATOR_STATE(state, ray, P);
445 const float dt = INTEGRATOR_STATE(state, ray, previous_dt);
446 const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
447
448 uint lookup_offset = kernel_data_fetch(object_lookup_offset, sd->object);
449 uint prim_offset = kernel_data_fetch(object_prim_offset, sd->object);
450 uint triangle = kernel_data_fetch(triangle_to_tree, sd->prim - prim_offset + lookup_offset);
451
452 pdf *= light_tree_pdf(
453 kg, ray_P, N, dt, path_flag, sd->object, triangle, light_link_receiver_forward(kg, state));
454 }
455 else
456#endif
457 {
458 /* Handled in triangle_light_pdf for efficiency. */
459 }
460
461 return light_sample_mis_weight_forward(kg, bsdf_pdf, pdf);
462}
463
466 const uint32_t path_flag,
467 const ccl_private LightSample *ls,
468 const float3 P)
469{
470 if (path_flag & PATH_RAY_MIS_SKIP) {
471 return 1.0f;
472 }
473
474 const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
475 float pdf = ls->pdf;
476
477 /* Light selection pdf. */
478#ifdef __LIGHT_TREE__
479 if (kernel_data.integrator.use_light_tree) {
480 const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
481 const float dt = INTEGRATOR_STATE(state, ray, previous_dt);
482 pdf *= light_tree_pdf(kg,
483 P,
484 N,
485 dt,
486 path_flag,
487 0,
488 kernel_data_fetch(light_to_tree, ls->lamp),
490 }
491 else
492#endif
493 {
495 }
496
497 return light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf);
498}
499
502 const uint32_t path_flag,
503 const ccl_private LightSample *ls)
504{
505 const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
506 return light_sample_mis_weight_forward_lamp(kg, state, path_flag, ls, ray_P);
507}
508
511 const uint32_t path_flag)
512{
513 /* Check if background light exists or if we should skip PDF. */
514 if (!kernel_data.background.use_mis || (path_flag & PATH_RAY_MIS_SKIP)) {
515 return 1.0f;
516 }
517
518 const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
519 const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
520 const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
521
522 float pdf = background_light_pdf(kg, ray_P, ray_D);
523
524 /* Light selection pdf. */
525#ifdef __LIGHT_TREE__
526 if (kernel_data.integrator.use_light_tree) {
527 const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
528 const float dt = INTEGRATOR_STATE(state, ray, previous_dt);
529 uint light = kernel_data_fetch(light_to_tree, kernel_data.background.light_index);
530 pdf *= light_tree_pdf(
531 kg, ray_P, N, dt, path_flag, 0, light, light_link_receiver_forward(kg, state));
532 }
533 else
534#endif
535 {
537 }
538
539 return light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf);
540}
541
unsigned int uint
ccl_device_forceinline void area_light_mnee_sample_update(const ccl_global KernelLight *klight, ccl_private LightSample *ls, const float3 P)
Definition area.h:374
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
local_group_size(16, 16) .push_constant(Type b
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
ccl_device_inline bool light_sample_terminate(KernelGlobals kg, ccl_private BsdfEval *ccl_restrict eval, const float rand_terminate)
ccl_device_forceinline void light_sample_update(KernelGlobals kg, ccl_private LightSample *ls, const float3 P, const float3 N, const uint32_t path_flag)
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(KernelGlobals kg, const float forward_pdf, const float nee_pdf)
ccl_device_inline float light_sample_mis_weight_forward_background(KernelGlobals kg, IntegratorState state, const uint32_t path_flag)
ccl_device bool light_sample_from_position(KernelGlobals kg, const float3 rand, const float time, const float3 P, const float3 N, const int object_receiver, const int shader_flags, const int bounce, const uint32_t path_flag, ccl_private LightSample *ls)
ccl_device_inline float light_sample_mis_weight_nee(KernelGlobals kg, const float nee_pdf, const float forward_pdf)
ccl_device_inline float3 shadow_ray_offset(KernelGlobals kg, ccl_private const ShaderData *ccl_restrict sd, float3 L, ccl_private bool *r_skip_self)
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 light_sample_to_volume_shadow_ray(KernelGlobals kg, ccl_private const ShaderData *ccl_restrict sd, ccl_private const LightSample *ccl_restrict ls, const float3 P, ccl_private Ray *ray)
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)
ccl_device_inline float3 shadow_ray_smooth_surface_offset(KernelGlobals kg, ccl_private const ShaderData *ccl_restrict sd, float3 Ng)
ccl_device_inline void shadow_ray_setup(ccl_private const ShaderData *ccl_restrict sd, ccl_private const LightSample *ccl_restrict ls, const float3 P, ccl_private Ray *ray, const bool skip_self)
ccl_device_inline void light_sample_to_surface_shadow_ray(KernelGlobals kg, ccl_private const ShaderData *ccl_restrict sd, ccl_private const LightSample *ccl_restrict ls, ccl_private Ray *ray)
ccl_device_inline float light_sample_mis_weight_forward_surface(KernelGlobals kg, IntegratorState state, const uint32_t path_flag, const ccl_private ShaderData *sd)
ccl_device_inline bool light_sample_from_volume_segment(KernelGlobals kg, const float3 rand, const float time, const float3 P, const float3 D, const float t, const int object_receiver, const int bounce, const uint32_t path_flag, ccl_private LightSample *ls)
#define NL
#define kernel_assert(cond)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_restrict
#define ccl_device_forceinline
#define ccl_device
#define ccl_private
#define ccl_device_noinline_cpu
#define ccl_device_inline
#define ccl_global
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define NULL
ccl_device_forceinline float differential_make_compact(const float dD)
ccl_device_forceinline float differential_zero_compact()
ccl_device_inline float light_distribution_pdf_lamp(KernelGlobals kg)
CCL_NAMESPACE_BEGIN ccl_device int light_distribution_sample(KernelGlobals kg, const float rand)
ccl_device_inline void triangle_vertices_and_normals(KernelGlobals kg, int prim, float3 P[3], float3 N[3])
ccl_device_inline void object_dir_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *D)
ccl_device float background_light_pdf(KernelGlobals kg, float3 P, float3 direction)
ccl_device_inline bool light_sample(KernelGlobals kg, const int lamp, const float2 rand, const float3 P, const float3 N, const int shader_flags, const uint32_t path_flag, ccl_private LightSample *ls)
ccl_device_inline int light_link_receiver_forward(KernelGlobals kg, IntegratorState state)
@ SD_MIS_BACK
@ SD_BACKFACING
@ SD_MIS_FRONT
@ SD_BSDF_HAS_TRANSMISSION
@ PRIMITIVE_MOTION_TRIANGLE
@ PRIMITIVE_TRIANGLE
@ DIRECT_LIGHT_SAMPLING_NEE
@ DIRECT_LIGHT_SAMPLING_FORWARD
#define PRIM_NONE
@ PATH_RAY_EMISSION
@ PATH_RAY_MIS_SKIP
#define OBJECT_NONE
ShaderData
@ SHADER_SMOOTH_NORMAL
@ SHADER_CAST_SHADOW
@ SD_OBJECT_TRANSFORM_APPLIED
@ LIGHT_AREA
@ LIGHT_SPOT
@ LIGHT_BACKGROUND
@ LIGHT_POINT
#define LAMP_NONE
ccl_device_inline Spectrum rgb_to_spectrum(float3 rgb)
#define PROFILING_INIT_FOR_SHADER(kg, event)
#define PROFILING_EVENT(event)
#define PROFILING_SHADER(object, shader)
ccl_device_forceinline void point_light_mnee_sample_update(const ccl_global KernelLight *klight, ccl_private LightSample *ls, const float3 P, const float3 N, const uint32_t path_flag)
Definition light/point.h:93
ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg, ccl_private const ShaderData *sd, float t)
ccl_device_inline Spectrum bsdf_eval_sum(ccl_private const BsdfEval *eval)
ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float value)
ccl_device_inline bool bsdf_eval_is_zero(ccl_private BsdfEval *eval)
ccl_device_inline float reduce_max(const float2 a)
ccl_device_inline float2 normalize_len(const float2 a, ccl_private float *t)
ccl_device_inline float2 fabs(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
static ulong state[N]
#define N
#define L
ccl_device float power_heuristic(float a, float b)
Definition mis.h:24
ccl_device_inline void motion_triangle_vertices_and_normals(KernelGlobals kg, int object, int prim, float time, float3 verts[3], float3 normals[3])
ccl_device_inline void shader_setup_from_sample(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const float3 P, const float3 Ng, const float3 I, int shader, int object, int prim, float u, float v, float t, float time, bool object_space, int lamp)
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)
#define min(a, b)
Definition sort.c:32
ccl_device_forceinline void spot_light_mnee_sample_update(const ccl_global KernelLight *klight, ccl_private LightSample *ls, const float3 P, const float3 N, const uint32_t path_flag)
Definition spot.h:166
IntegratorStateCPU *ccl_restrict IntegratorState
Definition state.h:228
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition state.h:235
#define FLT_MAX
Definition stdcycles.h:14
unsigned int uint32_t
Definition stdint.h:80
float z
Definition sky_float3.h:27
ccl_device Spectrum surface_shader_emission(ccl_private const ShaderData *sd)
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)
float max
ccl_device_noinline bool light_tree_sample(KernelGlobals kg, const float rand, const float3 P, float3 N_or_D, float t, const int object_receiver, const int shader_flags, ccl_private LightSample *ls)
Definition tree.h:709
ccl_device float light_tree_pdf(KernelGlobals kg, float3 P, float3 N, const float dt, const int path_flag, const int object_emitter, const uint index_emitter, const int object_receiver)
Definition tree.h:780
#define zero_spectrum
SPECTRUM_DATA_TYPE Spectrum
ccl_device_inline int clamp(int a, int mn, int mx)
Definition util/math.h:379
@ PROFILING_SHADE_LIGHT_SETUP
@ PROFILING_SHADE_LIGHT_EVAL
CCL_NAMESPACE_BEGIN struct Window V