Blender V5.0
cycles/util/projection.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 "util/transform.h"
8
10
12{
13 const float theta = safe_acosf(dir.z);
14 const float phi = atan2f(dir.y, dir.x);
15
16 return make_float2(theta, phi);
17}
18
19ccl_device float3 spherical_to_direction(const float theta, const float phi)
20{
21 return make_float3(sinf(theta) * cosf(phi), sinf(theta) * sinf(phi), cosf(theta));
22}
23
25{
26 const float sin_theta = sin_from_cos(cos_theta);
27 return make_float3(sin_theta * cosf(phi), sin_theta * sinf(phi), cos_theta);
28}
29
30ccl_device_inline float2 polar_to_cartesian(const float r, const float phi)
31{
32 return make_float2(r * cosf(phi), r * sinf(phi));
33}
34
35/* Transform p from a local coordinate system (spanned by X and Y) into global coordinates. */
36template<class T> ccl_device_inline T to_global(const float2 p, const T X, const T Y)
37{
38 return p.x * X + p.y * Y;
39}
40
41/* Transform p from a local coordinate system (spanned by X, Y and Z) into global coordinates. */
42template<class T> ccl_device_inline T to_global(const float3 p, const T X, const T Y, const T Z)
43{
44 return p.x * X + p.y * Y + p.z * Z;
45}
46
47/* Transform p from global coordinates into a local coordinate system (spanned by X and Y). */
48template<class T> ccl_device_inline float2 to_local(const T p, const T X, const T Y)
49{
50 return make_float2(dot(p, X), dot(p, Y));
51}
52
53/* Transform p from global coordinates into a local coordinate system (spanned by X, Y and Z). */
54template<class T> ccl_device_inline float3 to_local(const T p, const T X, const T Y, const T Z)
55{
56 return make_float3(dot(p, X), dot(p, Y), dot(p, Z));
57}
58
63
64/* 4x4 projection matrix, perspective or orthographic. */
65
67 float4 x, y, z, w; /* rows */
68
69#ifndef __KERNEL_GPU__
71
72 explicit ProjectionTransform(const Transform &tfm)
73 : x(tfm.x), y(tfm.y), z(tfm.z), w(make_float4(0.0f, 0.0f, 0.0f, 1.0f))
74 {
75 }
76#endif
77};
78
83
85
86#if !defined(__KERNEL_METAL__)
88#endif
89
91
92/* Functions */
93
95 const float3 a)
96{
97 const float4 b = make_float4(a.x, a.y, a.z, 1.0f);
98 const float3 c = make_float3(dot(t->x, b), dot(t->y, b), dot(t->z, b));
99 const float w = dot(t->w, b);
100
101 return (w != 0.0f) ? c / w : zero_float3();
102}
103
105 const float3 a)
106{
107 const float3 c = make_float3(a.x * t->x.x + a.y * t->x.y + a.z * t->x.z,
108 a.x * t->y.x + a.y * t->y.y + a.z * t->y.z,
109 a.x * t->z.x + a.y * t->z.y + a.z * t->z.z);
110
111 return c;
112}
113
114/* Applies transform t to point a with given derivatives `da/dx` and `da/dy`.
115 * Returns t(a) and sets `out_dx/dy` to the values of `dt(a)/dx` and `dt(a)/dy`, respectively. */
117 const float3 a,
118 const float3 dx,
119 const float3 dy,
120 ccl_private float3 &out_dx,
121 ccl_private float3 &out_dy)
122{
123 const float4 b = make_float4(a.x, a.y, a.z, 1.0f);
124 const float3 c = make_float3(dot(t->x, b), dot(t->y, b), dot(t->z, b));
125 const float w = dot(t->w, b);
126
127 if (w != 0.0f) {
128 out_dx = (transform_perspective_direction(t, dx) - dot(make_float3(t->w), dx) * c) / w;
129 out_dy = (transform_perspective_direction(t, dy) - dot(make_float3(t->w), dy) * c) / w;
130 return c / w;
131 }
132 else {
133 out_dx = zero_float3();
134 out_dy = zero_float3();
135 return zero_float3();
136 }
137}
138
140 const float b,
141 const float c,
142 const float d,
143 const float e,
144 const float f,
145 const float g,
146 const float h,
147 const float i,
148 const float j,
149 const float k,
150 const float l,
151 const float m,
152 const float n,
153 const float o,
154 const float p)
155{
157
158 t.x.x = a;
159 t.x.y = b;
160 t.x.z = c;
161 t.x.w = d;
162 t.y.x = e;
163 t.y.y = f;
164 t.y.z = g;
165 t.y.w = h;
166 t.z.x = i;
167 t.z.y = j;
168 t.z.z = k;
169 t.z.w = l;
170 t.w.x = m;
171 t.w.y = n;
172 t.w.z = o;
173 t.w.w = p;
174
175 return t;
176}
177
179{
180 return make_projection(1.0f,
181 0.0f,
182 0.0f,
183 0.0f,
184 0.0f,
185 1.0f,
186 0.0f,
187 0.0f,
188 0.0f,
189 0.0f,
190 1.0f,
191 0.0f,
192 0.0f,
193 0.0f,
194 0.0f,
195 1.0f);
196}
197
198#ifndef __KERNEL_GPU__
200{
201 Transform tfm = {a.x, a.y, a.z};
202 return tfm;
203}
204#endif
205
207{
209
210 t.x.x = a.x.x;
211 t.x.y = a.y.x;
212 t.x.z = a.z.x;
213 t.x.w = a.w.x;
214 t.y.x = a.x.y;
215 t.y.y = a.y.y;
216 t.y.z = a.z.y;
217 t.y.w = a.w.y;
218 t.z.x = a.x.z;
219 t.z.y = a.y.z;
220 t.z.z = a.z.z;
221 t.z.w = a.w.z;
222 t.w.x = a.x.w;
223 t.w.y = a.y.w;
224 t.w.z = a.z.w;
225 t.w.w = a.w.w;
226
227 return t;
228}
229
230#if !defined(__KERNEL_METAL__)
232{
234 float M[4][4];
235 float R[4][4];
236
237 memcpy(R, (const float *)&tfmR, sizeof(R));
238 memcpy(M, (const float *)&tfm, sizeof(M));
239
241 return projection_identity();
242 }
243
244 memcpy((void *)&tfmR, R, sizeof(R));
245
246 return tfmR;
247}
248
251{
254
255 t.x = make_float4(dot(a.x, c.x), dot(a.x, c.y), dot(a.x, c.z), dot(a.x, c.w));
256 t.y = make_float4(dot(a.y, c.x), dot(a.y, c.y), dot(a.y, c.z), dot(a.y, c.w));
257 t.z = make_float4(dot(a.z, c.x), dot(a.z, c.y), dot(a.z, c.z), dot(a.z, c.w));
258 t.w = make_float4(dot(a.w, c.x), dot(a.w, c.y), dot(a.w, c.z), dot(a.w, c.w));
259
260 return t;
261}
262#endif
263
264#ifndef __KERNEL_GPU__
265
270
275
277{
278 print_float4(label, t.x);
279 print_float4(label, t.y);
280 print_float4(label, t.z);
281 print_float4(label, t.w);
282 printf("\n");
283}
284
286 const float n,
287 float f)
288{
290 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, f / (f - n), -f * n / (f - n), 0, 0, 1, 0);
291
292 const float inv_angle = 1.0f / tanf(0.5f * fov);
293
294 const Transform scale = transform_scale(inv_angle, inv_angle, 1);
295
296 return scale * persp;
297}
298
300{
301 const Transform t = transform_scale(1.0f, 1.0f, 1.0f / (zfar - znear));
302
303 return ProjectionTransform(t);
304}
305
306#endif /* __KERNEL_GPU__ */
307
MINLINE float safe_sqrtf(float a)
MINLINE float safe_acosf(float a)
#define UNLIKELY(x)
#define X
#define Z
#define Y
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ccl_device_inline float cos_theta(const float3 w)
ccl_device_inline float sin_theta(const float3 w)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
ccl_device_inline float3 transform_perspective_direction(const ccl_private ProjectionTransform *t, const float3 a)
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_perspective(const ccl_private ProjectionTransform *t, const float3 a)
ccl_device float3 spherical_cos_to_direction(const float cos_theta, const float phi)
CCL_NAMESPACE_BEGIN ccl_device float2 direction_to_spherical(const float3 dir)
ccl_device_inline float3 disk_to_hemisphere(const float2 p)
ccl_device_inline T to_global(const float2 p, const T X, const T Y)
ccl_device_inline float3 transform_perspective_deriv(const ccl_private ProjectionTransform *t, const float3 a, const float3 dx, const float3 dy, ccl_private float3 &out_dx, ccl_private float3 &out_dy)
ccl_device_inline ProjectionTransform operator*(const ProjectionTransform a, const ProjectionTransform b)
ccl_device_inline Transform projection_to_transform(const ProjectionTransform &a)
ccl_device_inline float2 to_local(const T p, const T X, const T Y)
ccl_device_inline ProjectionTransform projection_identity()
ccl_device float3 spherical_to_direction(const float theta, const float phi)
ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform a)
ccl_device_inline ProjectionTransform make_projection(const float a, const float b, const float c, const float d, const float e, const float f, const float g, const float h, const float i, const float j, const float k, const float l, const float m, const float n, const float o, const float p)
ccl_device_inline ProjectionTransform projection_inverse(const ProjectionTransform tfm)
ccl_device_inline ProjectionTransform projection_perspective(const float fov, const float n, float f)
ccl_device_inline void print_projection(const char *label, const ProjectionTransform &t)
ccl_device_inline ProjectionTransform projection_orthographic(const float znear, const float zfar)
ccl_device_inline float2 polar_to_cartesian(const float r, const float phi)
#define ccl_private
#define ccl_device_inline
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define printf(...)
ccl_device_inline float sin_from_cos(const float c)
Definition math_base.h:609
ccl_device_inline float len_squared(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:17
#define M
#define T
#define R
CCL_NAMESPACE_BEGIN ccl_device_forceinline bool projection_inverse_impl(ccl_private float R[4][4], ccl_private float M[4][4])
#define ccl_device
#define sinf
#define make_float2
#define tanf
#define make_float4
#define cosf
#define atan2f
ProjectionTransform(const Transform &tfm)
ProjectionTransform()=default
float x
float y
float z
Definition sky_math.h:136
float y
Definition sky_math.h:136
float x
Definition sky_math.h:136
float y
Definition sky_math.h:225
float z
Definition sky_math.h:225
float x
Definition sky_math.h:225
float w
Definition sky_math.h:225
i
Definition text_draw.cc:230
ccl_device_inline Transform transform_scale(const float3 s)
Definition transform.h:280
ccl_device_inline void print_float4(const ccl_private char *label, const float4 a)