Blender  V2.93
kernel_projection.h
Go to the documentation of this file.
1 /*
2  * Parts adapted from Open Shading Language with this license:
3  *
4  * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
5  * All Rights Reserved.
6  *
7  * Modifications Copyright 2011, Blender Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are
11  * met:
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  * * Neither the name of Sony Pictures Imageworks nor the names of its
18  * contributors may be used to endorse or promote products derived from
19  * this software without specific prior written permission.
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef __KERNEL_PROJECTION_CL__
34 #define __KERNEL_PROJECTION_CL__
35 
37 
38 /* Spherical coordinates <-> Cartesian direction */
39 
41 {
42  float theta = safe_acosf(dir.z);
43  float phi = atan2f(dir.x, dir.y);
44 
45  return make_float2(theta, phi);
46 }
47 
48 ccl_device float3 spherical_to_direction(float theta, float phi)
49 {
50  float sin_theta = sinf(theta);
51  return make_float3(sin_theta * cosf(phi), sin_theta * sinf(phi), cosf(theta));
52 }
53 
54 /* Equirectangular coordinates <-> Cartesian direction */
55 
57 {
58  if (is_zero(dir))
59  return zero_float2();
60 
61  float u = (atan2f(dir.y, dir.x) - range.y) / range.x;
62  float v = (acosf(dir.z / len(dir)) - range.w) / range.z;
63 
64  return make_float2(u, v);
65 }
66 
68 {
69  float phi = range.x * u + range.y;
70  float theta = range.z * v + range.w;
71  float sin_theta = sinf(theta);
72  return make_float3(sin_theta * cosf(phi), sin_theta * sinf(phi), cosf(theta));
73 }
74 
76 {
78 }
79 
81 {
83 }
84 
85 /* Fisheye <-> Cartesian direction */
86 
88 {
89  float r = atan2f(sqrtf(dir.y * dir.y + dir.z * dir.z), dir.x) / fov;
90  float phi = atan2f(dir.z, dir.y);
91 
92  float u = r * cosf(phi) + 0.5f;
93  float v = r * sinf(phi) + 0.5f;
94 
95  return make_float2(u, v);
96 }
97 
98 ccl_device float3 fisheye_to_direction(float u, float v, float fov)
99 {
100  u = (u - 0.5f) * 2.0f;
101  v = (v - 0.5f) * 2.0f;
102 
103  float r = sqrtf(u * u + v * v);
104 
105  if (r > 1.0f)
106  return zero_float3();
107 
108  float phi = safe_acosf((r != 0.0f) ? u / r : 0.0f);
109  float theta = r * fov * 0.5f;
110 
111  if (v < 0.0f)
112  phi = -phi;
113 
114  return make_float3(cosf(theta), -cosf(phi) * sinf(theta), sinf(phi) * sinf(theta));
115 }
116 
118 {
119  float theta = safe_acosf(dir.x);
120  float r = 2.0f * lens * sinf(theta * 0.5f);
121  float phi = atan2f(dir.z, dir.y);
122 
123  float u = r * cosf(phi) / width + 0.5f;
124  float v = r * sinf(phi) / height + 0.5f;
125 
126  return make_float2(u, v);
127 }
128 
130 fisheye_equisolid_to_direction(float u, float v, float lens, float fov, float width, float height)
131 {
132  u = (u - 0.5f) * width;
133  v = (v - 0.5f) * height;
134 
135  float rmax = 2.0f * lens * sinf(fov * 0.25f);
136  float r = sqrtf(u * u + v * v);
137 
138  if (r > rmax)
139  return zero_float3();
140 
141  float phi = safe_acosf((r != 0.0f) ? u / r : 0.0f);
142  float theta = 2.0f * asinf(r / (2.0f * lens));
143 
144  if (v < 0.0f)
145  phi = -phi;
146 
147  return make_float3(cosf(theta), -cosf(phi) * sinf(theta), sinf(phi) * sinf(theta));
148 }
149 
150 /* Mirror Ball <-> Cartesion direction */
151 
153 {
154  /* point on sphere */
155  float3 dir;
156 
157  dir.x = 2.0f * u - 1.0f;
158  dir.z = 2.0f * v - 1.0f;
159 
160  if (dir.x * dir.x + dir.z * dir.z > 1.0f)
161  return zero_float3();
162 
163  dir.y = -sqrtf(max(1.0f - dir.x * dir.x - dir.z * dir.z, 0.0f));
164 
165  /* reflection */
166  float3 I = make_float3(0.0f, -1.0f, 0.0f);
167 
168  return 2.0f * dot(dir, I) * dir - I;
169 }
170 
172 {
173  /* inverse of mirrorball_to_direction */
174  dir.y -= 1.0f;
175 
176  float div = 2.0f * sqrtf(max(-0.5f * dir.y, 0.0f));
177  if (div > 0.0f)
178  dir /= div;
179 
180  float u = 0.5f * (dir.x + 1.0f);
181  float v = 0.5f * (dir.z + 1.0f);
182 
183  return make_float2(u, v);
184 }
185 
187 {
188  switch (cam->panorama_type) {
190  return equirectangular_range_to_direction(u, v, cam->equirectangular_range);
191  case PANORAMA_MIRRORBALL:
192  return mirrorball_to_direction(u, v);
194  return fisheye_to_direction(u, v, cam->fisheye_fov);
196  default:
198  u, v, cam->fisheye_lens, cam->fisheye_fov, cam->sensorwidth, cam->sensorheight);
199  }
200 }
201 
203 {
204  switch (cam->panorama_type) {
206  return direction_to_equirectangular_range(dir, cam->equirectangular_range);
207  case PANORAMA_MIRRORBALL:
208  return direction_to_mirrorball(dir);
210  return direction_to_fisheye(dir, cam->fisheye_fov);
212  default:
214  dir, cam->fisheye_lens, cam->sensorwidth, cam->sensorheight);
215  }
216 }
217 
219  float3 *P,
220  float3 *D)
221 {
222  float interocular_offset = cam->interocular_offset;
223 
224  /* Interocular offset of zero means either non stereo, or stereo without
225  * spherical stereo. */
226  kernel_assert(interocular_offset != 0.0f);
227 
228  if (cam->pole_merge_angle_to > 0.0f) {
229  const float pole_merge_angle_from = cam->pole_merge_angle_from,
230  pole_merge_angle_to = cam->pole_merge_angle_to;
231  float altitude = fabsf(safe_asinf((*D).z));
232  if (altitude > pole_merge_angle_to) {
233  interocular_offset = 0.0f;
234  }
235  else if (altitude > pole_merge_angle_from) {
236  float fac = (altitude - pole_merge_angle_from) /
237  (pole_merge_angle_to - pole_merge_angle_from);
238  float fade = cosf(fac * M_PI_2_F);
239  interocular_offset *= fade;
240  }
241  }
242 
243  float3 up = make_float3(0.0f, 0.0f, 1.0f);
244  float3 side = normalize(cross(*D, up));
245  float3 stereo_offset = side * interocular_offset;
246 
247  *P += stereo_offset;
248 
249  /* Convergence distance is FLT_MAX in the case of parallel convergence mode,
250  * no need to modify direction in this case either. */
251  const float convergence_distance = cam->convergence_distance;
252 
253  if (convergence_distance != FLT_MAX) {
254  float3 screen_offset = convergence_distance * (*D);
255  *D = normalize(screen_offset - stereo_offset);
256  }
257 }
258 
260 
261 #endif /* __KERNEL_PROJECTION_CL__ */
MINLINE float safe_acosf(float a)
MINLINE float safe_asinf(float a)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define kernel_assert(cond)
#define sinf(x)
#define cosf(x)
#define ccl_device
#define ccl_constant
#define ccl_device_inline
#define CCL_NAMESPACE_END
#define atan2f(x, y)
#define asinf(x)
#define make_float2(x, y)
#define acosf(x)
#define make_float4(x, y, z, w)
#define fabsf(x)
#define sqrtf(x)
#define make_float3(x, y, z)
ccl_device float2 direction_to_fisheye(float3 dir, float fov)
ccl_device_inline void spherical_stereo_transform(ccl_constant KernelCamera *cam, float3 *P, float3 *D)
ccl_device float3 fisheye_to_direction(float u, float v, float fov)
ccl_device float2 direction_to_mirrorball(float3 dir)
CCL_NAMESPACE_BEGIN ccl_device float2 direction_to_spherical(float3 dir)
ccl_device_inline float3 panorama_to_direction(ccl_constant KernelCamera *cam, float u, float v)
ccl_device float2 direction_to_equirectangular_range(float3 dir, float4 range)
ccl_device_inline float2 direction_to_panorama(ccl_constant KernelCamera *cam, float3 dir)
ccl_device float3 equirectangular_to_direction(float u, float v)
ccl_device float2 direction_to_equirectangular(float3 dir)
ccl_device float2 direction_to_fisheye_equisolid(float3 dir, float lens, float width, float height)
ccl_device_inline float3 fisheye_equisolid_to_direction(float u, float v, float lens, float fov, float width, float height)
ccl_device float3 spherical_to_direction(float theta, float phi)
ccl_device float3 equirectangular_range_to_direction(float u, float v, float4 range)
ccl_device float3 mirrorball_to_direction(float u, float v)
@ PANORAMA_MIRRORBALL
Definition: kernel_types.h:618
@ PANORAMA_FISHEYE_EQUISOLID
Definition: kernel_types.h:617
@ PANORAMA_FISHEYE_EQUIDISTANT
Definition: kernel_types.h:616
@ PANORAMA_EQUIRECTANGULAR
Definition: kernel_types.h:615
static float P(float k)
Definition: math_interp.c:41
#define I
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
CCL_NAMESPACE_BEGIN ccl_device float fade(float t)
Definition: svm_noise.h:37
float max
__forceinline avxf cross(const avxf &a, const avxf &b)
Definition: util_avxf.h:119
#define M_PI_2_F
Definition: util_math.h:46
#define M_2PI_F
Definition: util_math.h:69
#define M_PI_F
Definition: util_math.h:43
ccl_device_inline float2 normalize(const float2 &a)
ccl_device_inline float dot(const float2 &a, const float2 &b)
ccl_device_inline float2 zero_float2()
ccl_device_inline bool is_zero(const float2 &a)
ccl_device_inline float3 zero_float3()
uint len
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
Definition: voxel.c:29