22 transformed_ray.
z = -transformed_ray.
z;
24 return transformed_ray;
30 return smoothstepf((ray.
z - spot->cos_half_spot_angle) * spot->spot_smooth);
34 const float half_cot_half_spot_angle,
39 const float factor = half_cot_half_spot_angle / ray.
z;
42 *u = ray.
y * factor + 0.5f;
43 *
v = -(ray.
x + ray.
y) * factor;
46template<
bool in_volume_segment>
52 const int shader_flags,
55 const float r_sq =
sqr(klight->spot.radius);
59 const float d =
sqrtf(d_sq);
62 ls->eval_fac = klight->spot.eval_fac;
64 if (klight->spot.is_sphere) {
70 const float one_minus_cos_half_spot_spread = 1.0f - klight->spot.cos_half_larger_spread;
73 if (in_volume_segment || one_minus_cos_half_angle < one_minus_cos_half_spot_spread) {
80 -klight->spot.dir, one_minus_cos_half_spot_spread, rand, &
cos_theta, &ls->pdf);
83 P, ls->D, 0.0f,
FLT_MAX, klight->co, klight->spot.radius, &ls->P, &ls->t))
93 if (has_transmission) {
108 if (!in_volume_segment && ls->eval_fac == 0.0f) {
116 ls->P =
P + ls->D * ls->t;
124 ls->P = ls->Ng * klight->spot.radius + klight->co;
127 spot_light_uv(local_ray, klight->spot.half_cot_half_spot_angle, &ls->u, &ls->v);
142 if (!in_volume_segment && ls->eval_fac == 0.0f) {
147 const float invarea = (r_sq > 0.0f) ? 1.0f / (r_sq *
M_PI_F) : 1.0f;
151 spot_light_uv(local_ray, klight->spot.half_cot_half_spot_angle, &ls->u, &ls->v);
162 const uint32_t path_flag)
178 const uint32_t path_flag)
182 ls->eval_fac = klight->spot.eval_fac;
184 const float radius = klight->spot.radius;
185 bool use_attenuation =
true;
187 if (klight->spot.is_sphere) {
189 const float r_sq =
sqr(radius);
190 const float t_sq =
sqr(ls->t);
193 const float jacobian_solid_angle_to_area = 0.5f *
fabsf(d_sq - r_sq - t_sq) /
194 (radius * ls->t * t_sq);
195 ls->pdf =
spot_light_pdf(&klight->spot, d_sq, r_sq,
N, ls->D, path_flag) *
196 jacobian_solid_angle_to_area;
200 use_attenuation = (d_sq > r_sq);
204 ls->pdf = ls->eval_fac * 4.0f *
M_PI_F;
211 if (use_attenuation) {
216 spot_light_uv(local_ray, klight->spot.half_cot_half_spot_angle, &ls->u, &ls->v);
224 if (
dot(ray->D, ray->P - klight->co) >= 0.0f) {
236 const uint32_t path_flag,
240 const float r_sq =
sqr(klight->spot.radius);
241 const float d_sq =
len_squared(ray_P - klight->co);
243 ls->eval_fac = klight->spot.eval_fac;
245 if (klight->spot.is_sphere) {
246 ls->pdf =
spot_light_pdf(&klight->spot, d_sq, r_sq,
N, ray_D, path_flag);
252 const float invarea = (r_sq > 0.0f) ? 1.0f / (r_sq *
M_PI_F) : 1.0f;
263 if (!klight->spot.is_sphere || d_sq > r_sq) {
266 if (ls->eval_fac == 0) {
271 spot_light_uv(local_ray, klight->spot.half_cot_half_spot_angle, &ls->u, &ls->v);
285 float3 local_P =
P + klight->spot.dir * klight->spot.ray_segment_dp;
292 axis, local_P, local_D,
sqr(klight->spot.cos_half_spot_angle), t_range);
295template<
bool in_volume_segment>
309 const float radius = klight->spot.radius;
311 if (klight->spot.is_sphere) {
312 cos_theta_u = (min_distance > radius) ?
cos_from_sin(radius / min_distance) : -1.0f;
314 if (in_volume_segment) {
318 distance = (min_distance > radius) ? min_distance *
make_float2(1.0f / cos_theta_u, 1.0f) :
322 const float hypotenus =
sqrtf(
sqr(radius) +
sqr(min_distance));
323 cos_theta_u = min_distance / hypotenus;
325 if (in_volume_segment) {
336 const float cos_min_outgoing_angle =
cosf(
341 klight->spot.spot_smooth);
MINLINE float safe_sqrtf(float a)
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float cos_theta(const float3 w)
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define ccl_device_forceinline
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CCL_NAMESPACE_END
VecBase< float, D > normalize(VecOp< float, D >) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
ccl_device_inline Transform lamp_get_inverse_transform(KernelGlobals kg, const ccl_global KernelLight *klight)
@ SD_BSDF_HAS_TRANSMISSION
@ PATH_RAY_MIS_HAD_TRANSMISSION
ccl_device float3 disk_light_sample(const float3 n, const float2 rand)
ccl_device float light_pdf_area_to_solid_angle(const float3 Ng, const float3 I, const float t)
ccl_device_inline bool point_light_intersect(const ccl_global KernelLight *klight, const ccl_private Ray *ccl_restrict ray, ccl_private float *t)
ccl_device_inline float smoothstepf(const float f)
ccl_device_inline float sin_sqr_to_one_minus_cos(const float s_sq)
ccl_device_inline float cos_from_sin(const float s)
ccl_device float fast_acosf(const float x)
ccl_device_inline float2 one_float2()
ccl_device_inline float len_squared(const float2 a)
ccl_device_inline float2 safe_normalize(const float2 a)
ccl_device_inline float3 safe_normalize_len(const float3 a, ccl_private float *t)
ccl_device_inline bool ray_cone_intersect(const float3 axis, const float3 P, float3 D, const float cos_angle_sq, ccl_private Interval< float > *t_range)
CCL_NAMESPACE_BEGIN ccl_device bool ray_sphere_intersect(const float3 ray_P, const float3 ray_D, const float ray_tmin, const float ray_tmax, const float3 sphere_P, const float sphere_radius, ccl_private float3 *isect_P, ccl_private float *isect_t)
ccl_device_inline void sample_cos_hemisphere(const float3 N, const float2 rand_in, ccl_private float3 *wo, ccl_private float *pdf)
ccl_device float3 sample_uniform_sphere(const float2 rand)
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)
ccl_device_inline float pdf_cos_hemisphere(const float3 N, const float3 D)
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)
ccl_device void spot_light_uv(const float3 ray, const float half_cot_half_spot_angle, ccl_private float *u, ccl_private float *v)
ccl_device float spot_light_attenuation(const ccl_global KernelSpotLight *spot, const float3 ray)
ccl_device_inline bool spot_light_sample(KernelGlobals kg, const ccl_global KernelLight *klight, const float2 rand, const float3 P, const float3 N, const int shader_flags, ccl_private LightSample *ls)
CCL_NAMESPACE_BEGIN ccl_device float3 spot_light_to_local(KernelGlobals kg, const ccl_global KernelLight *klight, const float3 ray)
ccl_device_inline bool spot_light_intersect(const ccl_global KernelLight *klight, const ccl_private Ray *ccl_restrict ray, ccl_private float *t)
ccl_device_inline bool spot_light_sample_from_intersection(KernelGlobals kg, const ccl_global KernelLight *klight, const float3 ray_P, const float3 ray_D, const float3 N, const uint32_t path_flag, ccl_private LightSample *ccl_restrict ls)
ccl_device_forceinline bool spot_light_tree_parameters(const ccl_global KernelLight *klight, const float3 centroid, const float3 P, const ccl_private KernelBoundingCone &bcone, ccl_private float &cos_theta_u, ccl_private float2 &distance, ccl_private float3 &point_to_centroid, ccl_private float &energy)
ccl_device_forceinline float spot_light_pdf(const ccl_global KernelSpotLight *spot, const float d_sq, const float r_sq, const float3 N, const float3 D, const uint32_t path_flag)
ccl_device_inline bool spot_light_valid_ray_segment(KernelGlobals kg, const ccl_global KernelLight *klight, const float3 P, const float3 D, ccl_private Interval< float > *t_range)