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