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