Add Chromium-only Blender WebEngine parity work
This commit is contained in:
284
blender-5.2.0/intern/cycles/util/projection.h
Normal file
284
blender-5.2.0/intern/cycles/util/projection.h
Normal file
@@ -0,0 +1,284 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/transform.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device float2 direction_to_spherical(const float3 dir)
|
||||
{
|
||||
const float theta = safe_acosf(dir.z);
|
||||
const float phi = atan2f(dir.y, dir.x);
|
||||
|
||||
return make_float2(theta, phi);
|
||||
}
|
||||
|
||||
ccl_device float3 spherical_to_direction(const float theta, const float phi)
|
||||
{
|
||||
return make_float3(sinf(theta) * cosf(phi), sinf(theta) * sinf(phi), cosf(theta));
|
||||
}
|
||||
|
||||
ccl_device float3 spherical_cos_to_direction(const float cos_theta, const float phi)
|
||||
{
|
||||
const float sin_theta = sin_from_cos(cos_theta);
|
||||
return make_float3(sin_theta * cosf(phi), sin_theta * sinf(phi), cos_theta);
|
||||
}
|
||||
|
||||
ccl_device_inline float2 polar_to_cartesian(const float r, const float phi)
|
||||
{
|
||||
return make_float2(r * cosf(phi), r * sinf(phi));
|
||||
}
|
||||
|
||||
ccl_device_inline float3 disk_to_hemisphere(const float2 p)
|
||||
{
|
||||
return make_float3(p.x, p.y, safe_sqrtf(1.0f - len_squared(p)));
|
||||
}
|
||||
|
||||
/* 4x4 projection matrix, perspective or orthographic. */
|
||||
|
||||
struct ProjectionTransform {
|
||||
float4 x, y, z, w; /* rows */
|
||||
|
||||
#ifndef __KERNEL_GPU__
|
||||
ProjectionTransform() = default;
|
||||
|
||||
explicit ProjectionTransform(const Transform &tfm)
|
||||
: x(tfm.x), y(tfm.y), z(tfm.z), w(make_float4(0.0f, 0.0f, 0.0f, 1.0f))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct PerspectiveMotionTransform {
|
||||
ProjectionTransform pre;
|
||||
ProjectionTransform post;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#if !defined(__KERNEL_METAL__)
|
||||
# include "util/projection_inverse.h"
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Functions */
|
||||
|
||||
ccl_device_inline float3 transform_perspective(const ccl_private ProjectionTransform *t,
|
||||
const float3 a)
|
||||
{
|
||||
const float4 b = make_float4(a.x, a.y, a.z, 1.0f);
|
||||
const float3 c = make_float3(dot(t->x, b), dot(t->y, b), dot(t->z, b));
|
||||
const float w = dot(t->w, b);
|
||||
|
||||
return (w != 0.0f) ? c / w : zero_float3();
|
||||
}
|
||||
|
||||
ccl_device_inline float3 transform_perspective_direction(const ccl_private ProjectionTransform *t,
|
||||
const float3 a)
|
||||
{
|
||||
const float3 c = make_float3(a.x * t->x.x + a.y * t->x.y + a.z * t->x.z,
|
||||
a.x * t->y.x + a.y * t->y.y + a.z * t->y.z,
|
||||
a.x * t->z.x + a.y * t->z.y + a.z * t->z.z);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Applies transform t to point a with given derivatives `da/dx` and `da/dy`.
|
||||
* Returns t(a) and sets `out_dx/dy` to the values of `dt(a)/dx` and `dt(a)/dy`, respectively. */
|
||||
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)
|
||||
{
|
||||
const float4 b = make_float4(a.x, a.y, a.z, 1.0f);
|
||||
const float3 c = make_float3(dot(t->x, b), dot(t->y, b), dot(t->z, b));
|
||||
const float w = dot(t->w, b);
|
||||
|
||||
if (w != 0.0f) {
|
||||
out_dx = (transform_perspective_direction(t, dx) - dot(make_float3(t->w), dx) * c) / w;
|
||||
out_dy = (transform_perspective_direction(t, dy) - dot(make_float3(t->w), dy) * c) / w;
|
||||
return c / w;
|
||||
}
|
||||
else {
|
||||
out_dx = zero_float3();
|
||||
out_dy = zero_float3();
|
||||
return zero_float3();
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ProjectionTransform t;
|
||||
|
||||
t.x.x = a;
|
||||
t.x.y = b;
|
||||
t.x.z = c;
|
||||
t.x.w = d;
|
||||
t.y.x = e;
|
||||
t.y.y = f;
|
||||
t.y.z = g;
|
||||
t.y.w = h;
|
||||
t.z.x = i;
|
||||
t.z.y = j;
|
||||
t.z.z = k;
|
||||
t.z.w = l;
|
||||
t.w.x = m;
|
||||
t.w.y = n;
|
||||
t.w.z = o;
|
||||
t.w.w = p;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform projection_identity()
|
||||
{
|
||||
return make_projection(1.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.0f);
|
||||
}
|
||||
|
||||
#ifndef __KERNEL_GPU__
|
||||
ccl_device_inline Transform projection_to_transform(const ProjectionTransform &a)
|
||||
{
|
||||
Transform tfm = {a.x, a.y, a.z};
|
||||
return tfm;
|
||||
}
|
||||
#endif
|
||||
|
||||
ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform a)
|
||||
{
|
||||
ProjectionTransform t;
|
||||
|
||||
t.x.x = a.x.x;
|
||||
t.x.y = a.y.x;
|
||||
t.x.z = a.z.x;
|
||||
t.x.w = a.w.x;
|
||||
t.y.x = a.x.y;
|
||||
t.y.y = a.y.y;
|
||||
t.y.z = a.z.y;
|
||||
t.y.w = a.w.y;
|
||||
t.z.x = a.x.z;
|
||||
t.z.y = a.y.z;
|
||||
t.z.z = a.z.z;
|
||||
t.z.w = a.w.z;
|
||||
t.w.x = a.x.w;
|
||||
t.w.y = a.y.w;
|
||||
t.w.z = a.z.w;
|
||||
t.w.w = a.w.w;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
#if !defined(__KERNEL_METAL__)
|
||||
ccl_device_inline ProjectionTransform projection_inverse(const ProjectionTransform tfm)
|
||||
{
|
||||
ProjectionTransform tfmR = projection_identity();
|
||||
float M[4][4];
|
||||
float R[4][4];
|
||||
|
||||
memcpy(R, (const float *)&tfmR, sizeof(R));
|
||||
memcpy(M, (const float *)&tfm, sizeof(M));
|
||||
|
||||
if (UNLIKELY(!projection_inverse_impl(R, M))) {
|
||||
return projection_identity();
|
||||
}
|
||||
|
||||
memcpy((void *)&tfmR, R, sizeof(R));
|
||||
|
||||
return tfmR;
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform operator*(const ProjectionTransform a,
|
||||
const ProjectionTransform b)
|
||||
{
|
||||
const ProjectionTransform c = projection_transpose(b);
|
||||
ProjectionTransform t;
|
||||
|
||||
t.x = make_float4(dot(a.x, c.x), dot(a.x, c.y), dot(a.x, c.z), dot(a.x, c.w));
|
||||
t.y = make_float4(dot(a.y, c.x), dot(a.y, c.y), dot(a.y, c.z), dot(a.y, c.w));
|
||||
t.z = make_float4(dot(a.z, c.x), dot(a.z, c.y), dot(a.z, c.z), dot(a.z, c.w));
|
||||
t.w = make_float4(dot(a.w, c.x), dot(a.w, c.y), dot(a.w, c.z), dot(a.w, c.w));
|
||||
|
||||
return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __KERNEL_GPU__
|
||||
|
||||
ccl_device_inline ProjectionTransform operator*(const ProjectionTransform &a, const Transform &b)
|
||||
{
|
||||
return a * ProjectionTransform(b);
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform operator*(const Transform &a, const ProjectionTransform &b)
|
||||
{
|
||||
return ProjectionTransform(a) * b;
|
||||
}
|
||||
|
||||
ccl_device_inline void print_projection(const char *label, const ProjectionTransform &t)
|
||||
{
|
||||
print_float4(label, t.x);
|
||||
print_float4(label, t.y);
|
||||
print_float4(label, t.z);
|
||||
print_float4(label, t.w);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform projection_perspective(const float fov,
|
||||
const float n,
|
||||
float f)
|
||||
{
|
||||
const ProjectionTransform persp = make_projection(
|
||||
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, f / (f - n), -f * n / (f - n), 0, 0, 1, 0);
|
||||
|
||||
const float inv_angle = 1.0f / tanf(0.5f * fov);
|
||||
|
||||
const Transform scale = transform_scale(inv_angle, inv_angle, 1);
|
||||
|
||||
return scale * persp;
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform projection_orthographic(const float znear, const float zfar)
|
||||
{
|
||||
const Transform t = transform_scale(1.0f, 1.0f, 1.0f / (zfar - znear));
|
||||
|
||||
return ProjectionTransform(t);
|
||||
}
|
||||
|
||||
#endif /* __KERNEL_GPU__ */
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
Reference in New Issue
Block a user