Blender V5.0
distant.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
11#include "util/math_fast.h"
12
14
16 const ccl_global KernelLight *klight,
17 const float3 D,
18 ccl_private float *u,
19 ccl_private float *v)
20{
21 /* Map direction (x, y, z) to disk [-0.5, 0.5]^2:
22 * r^2 = (1 - z) / (1 - cos(klight->distant.angle))
23 * u_ = 0.5 * x * r / sin_angle(D, -klight->co)
24 * v_ = 0.5 * y * r / sin_angle(D, -klight->co) */
25 const float fac = klight->distant.half_inv_sin_half_angle / len(D - klight->co);
26
27 /* Get u axis and v axis. */
28 const Transform itfm = lamp_get_inverse_transform(kg, klight);
29 const float u_ = dot(D, make_float3(itfm.x)) * fac;
30 const float v_ = dot(D, make_float3(itfm.y)) * fac;
31
32 /* NOTE: Return barycentric coordinates in the same notation as Embree and OptiX. */
33 *u = v_ + 0.5f;
34 *v = -u_ - v_;
35}
36
38 const ccl_global KernelLight *klight,
39 const float2 rand,
41{
42 float unused;
43 ls->Ng = sample_uniform_cone(
44 klight->co, klight->distant.one_minus_cosangle, rand, &unused, &ls->pdf);
45
46 ls->P = ls->Ng;
47 ls->D = -ls->Ng;
48 ls->t = FLT_MAX;
49
50 ls->eval_fac = klight->distant.eval_fac;
51
52 distant_light_uv(kg, klight, ls->D, &ls->u, &ls->v);
53
54 return true;
55}
56
57/* Special intersection check.
58 * Returns true if the distant_light_sample_from_intersection() for this light would return true.
59 *
60 * The intersection parameters t, u, v are optimized for the shadow ray towards a dedicated light:
61 * u = v = 0, t = FLT_MAX.
62 */
64 const ccl_private Ray *ccl_restrict ray,
65 ccl_private float *t,
66 ccl_private float *u,
67 ccl_private float *v)
68{
69 kernel_assert(klight->type == LIGHT_DISTANT);
70
71 if (klight->distant.angle == 0.0f) {
72 return false;
73 }
74
75 if (vector_angle(-klight->co, ray->D) > klight->distant.angle) {
76 return false;
77 }
78
79 *t = FLT_MAX;
80 *u = 0.0f;
81 *v = 0.0f;
82
83 return true;
84}
85
87 const float3 ray_D,
88 const int lamp,
90{
91 const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
92 const int shader = klight->shader_id;
93 const LightType type = (LightType)klight->type;
94
95 if (type != LIGHT_DISTANT) {
96 return false;
97 }
98 if (!(shader & SHADER_USE_MIS)) {
99 return false;
100 }
101 if (klight->distant.angle == 0.0f) {
102 return false;
103 }
104
105 /* Workaround to prevent a hang in the classroom scene with AMD HIP drivers 22.10,
106 * Remove when a compiler fix is available. */
107#ifdef __HIP__
108 ls->shader = klight->shader_id;
109#endif
110
111 if (vector_angle(-klight->co, ray_D) > klight->distant.angle) {
112 return false;
113 }
114
115 ls->type = type;
116#ifndef __HIP__
117 ls->shader = klight->shader_id;
118#endif
119 ls->object = klight->object_id;
120 ls->prim = lamp;
121 ls->t = FLT_MAX;
122 ls->P = -ray_D;
123 ls->Ng = -ray_D;
124 ls->D = ray_D;
125 ls->group = object_lightgroup(kg, ls->object);
126
127 ls->pdf = klight->distant.pdf;
128 ls->eval_fac = klight->distant.eval_fac;
129
130 distant_light_uv(kg, klight, ray_D, &ls->u, &ls->v);
131
132 return true;
133}
134
135template<bool in_volume_segment>
137 const float theta_e,
138 const float t,
139 ccl_private float &cos_theta_u,
141 ccl_private float3 &point_to_centroid,
142 ccl_private float &theta_d)
143{
144 if (in_volume_segment) {
145 if (t == FLT_MAX) {
146 /* In world volumes, distant lights can contribute to the lighting of the volume with
147 * specific configurations of procedurally generated volumes. Use a ray length of 1.0 in this
148 * case to give the distant light some weight, but one that isn't too high for a typical
149 * world volume use case. */
150 theta_d = 1.0f;
151 }
152 else {
153 theta_d = t;
154 }
155 }
156
157 /* Treating it as a disk light 1 unit away */
158 cos_theta_u = fast_cosf(theta_e);
159
160 distance = make_float2(1.0f / cos_theta_u, 1.0f);
161
162 point_to_centroid = -centroid;
163
164 return true;
165}
166
#define D
ATTR_WARN_UNUSED_RESULT const BMVert * v
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define kernel_assert(cond)
#define ccl_restrict
#define ccl_device_forceinline
#define kernel_data_fetch(name, index)
#define ccl_private
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 bool distant_light_tree_parameters(const float3 centroid, const float theta_e, const float t, ccl_private float &cos_theta_u, ccl_private float2 &distance, ccl_private float3 &point_to_centroid, ccl_private float &theta_d)
Definition distant.h:136
ccl_device_inline bool distant_light_sample(KernelGlobals kg, const ccl_global KernelLight *klight, const float2 rand, ccl_private LightSample *ls)
Definition distant.h:37
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:86
CCL_NAMESPACE_BEGIN ccl_device_inline void distant_light_uv(KernelGlobals kg, const ccl_global KernelLight *klight, const float3 D, ccl_private float *u, ccl_private float *v)
Definition distant.h:15
ccl_device bool distant_light_intersect(const ccl_global KernelLight *klight, const ccl_private Ray *ccl_restrict ray, ccl_private float *t, ccl_private float *u, ccl_private float *v)
Definition distant.h:63
float distance(VecOp< float, D >, VecOp< float, D >) RET
ccl_device_inline Transform lamp_get_inverse_transform(KernelGlobals kg, const ccl_global KernelLight *klight)
ccl_device_inline int object_lightgroup(KernelGlobals kg, const int object)
@ SHADER_USE_MIS
LightType
@ LIGHT_DISTANT
ccl_device_inline float vector_angle(const float3 a, const float3 b)
Definition math_fast.h:339
ccl_device float fast_cosf(float x)
Definition math_fast.h:118
#define ccl_device
#define make_float2
ccl_device_inline float3 sample_uniform_cone(const float3 N, const float one_minus_cos_angle, const float2 rand, ccl_private float *cos_theta, ccl_private float *pdf)
#define FLT_MAX
Definition stdcycles.h:14
float4 y
Definition transform.h:23
float4 x
Definition transform.h:23
uint len