2023-06-14 16:52:36 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2024-12-26 17:53:56 +01:00
|
|
|
#pragma once
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
|
#ifndef __KERNEL_GPU__
|
2024-12-26 17:53:59 +01:00
|
|
|
# include <cstring>
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "util/math.h"
|
|
|
|
|
#include "util/types.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2022-08-09 14:28:19 +02:00
|
|
|
#ifndef __KERNEL_GPU__
|
|
|
|
|
# include "util/system.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
2018-03-08 06:48:14 +01:00
|
|
|
/* Affine transformation, stored as 4x3 matrix. */
|
2012-04-30 12:49:26 +00:00
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
struct Transform {
|
2018-03-08 06:48:14 +01:00
|
|
|
float4 x, y, z;
|
2011-09-19 11:57:31 +00:00
|
|
|
|
|
|
|
|
#ifndef __KERNEL_GPU__
|
|
|
|
|
float4 operator[](int i) const
|
|
|
|
|
{
|
|
|
|
|
return *(&x + i);
|
|
|
|
|
}
|
|
|
|
|
float4 &operator[](int i)
|
|
|
|
|
{
|
|
|
|
|
return *(&x + i);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2024-12-26 17:53:59 +01:00
|
|
|
};
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2018-03-08 06:19:17 +01:00
|
|
|
/* Transform decomposed in rotation/translation/scale. we use the same data
|
|
|
|
|
* structure as Transform, and tightly pack decomposition into it. first the
|
|
|
|
|
* rotation (4), then translation (3), then 3x3 scale matrix (9). */
|
|
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
struct DecomposedTransform {
|
2018-03-08 06:19:17 +01:00
|
|
|
float4 x, y, z, w;
|
2024-12-26 17:53:59 +01:00
|
|
|
};
|
2018-03-08 06:19:17 +01:00
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
/* Functions */
|
|
|
|
|
|
2021-11-18 14:25:05 +01:00
|
|
|
#ifdef __KERNEL_METAL__
|
|
|
|
|
/* transform_point specialized for ccl_global */
|
2024-12-29 17:32:00 +01:00
|
|
|
ccl_device_inline float3 transform_point(const ccl_global Transform *t, const float3 a)
|
2021-11-18 14:25:05 +01:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const ccl_global float3x3 &b(*(const ccl_global float3x3 *)t);
|
2021-11-18 14:25:05 +01:00
|
|
|
return (a * b).xyz + make_float3(t->x.w, t->y.w, t->z.w);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
ccl_device_inline float3 transform_point(const ccl_private Transform *t, const float3 a)
|
2012-04-16 08:35:21 +00:00
|
|
|
{
|
2016-10-26 15:23:58 +02:00
|
|
|
/* TODO(sergey): Disabled for now, causes crashes in certain cases. */
|
2016-12-02 10:15:24 +01:00
|
|
|
#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__)
|
2022-11-01 15:16:55 +01:00
|
|
|
const float4 aa(a.m128);
|
2016-10-25 14:47:34 +02:00
|
|
|
|
2022-11-01 15:16:55 +01:00
|
|
|
float4 x(_mm_loadu_ps(&t->x.x));
|
|
|
|
|
float4 y(_mm_loadu_ps(&t->y.x));
|
|
|
|
|
float4 z(_mm_loadu_ps(&t->z.x));
|
|
|
|
|
float4 w(_mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f));
|
2016-10-25 14:47:34 +02:00
|
|
|
|
2022-11-01 15:16:55 +01:00
|
|
|
_MM_TRANSPOSE4_PS(x.m128, y.m128, z.m128, w.m128);
|
2016-10-25 14:47:34 +02:00
|
|
|
|
2022-11-01 15:16:55 +01:00
|
|
|
float4 tmp = w;
|
2016-10-26 14:27:31 +02:00
|
|
|
tmp = madd(shuffle<2>(aa), z, tmp);
|
2022-07-21 15:49:00 +02:00
|
|
|
tmp = madd(shuffle<1>(aa), y, tmp);
|
|
|
|
|
tmp = madd(shuffle<0>(aa), x, tmp);
|
2016-10-25 14:47:34 +02:00
|
|
|
|
|
|
|
|
return float3(tmp.m128);
|
2021-11-18 14:25:05 +01:00
|
|
|
#elif defined(__KERNEL_METAL__)
|
2024-12-29 17:32:00 +01:00
|
|
|
const ccl_private float3x3 &b(*(const ccl_private float3x3 *)t);
|
2021-11-18 14:25:05 +01:00
|
|
|
return (a * b).xyz + make_float3(t->x.w, t->y.w, t->z.w);
|
2016-10-25 14:47:34 +02:00
|
|
|
#else
|
2012-05-28 19:21:13 +00:00
|
|
|
float3 c = make_float3(a.x * t->x.x + a.y * t->x.y + a.z * t->x.z + t->x.w,
|
|
|
|
|
a.x * t->y.x + a.y * t->y.y + a.z * t->y.z + t->y.w,
|
|
|
|
|
a.x * t->z.x + a.y * t->z.y + a.z * t->z.z + t->z.w);
|
2012-04-16 08:35:21 +00:00
|
|
|
|
|
|
|
|
return c;
|
2016-10-25 14:47:34 +02:00
|
|
|
#endif
|
2012-04-16 08:35:21 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
ccl_device_inline float3 transform_direction(const ccl_private Transform *t, const float3 a)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2016-12-02 10:15:24 +01:00
|
|
|
#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__)
|
2022-11-01 15:16:55 +01:00
|
|
|
const float4 aa(a.m128);
|
2016-10-25 14:47:34 +02:00
|
|
|
|
2022-11-01 15:16:55 +01:00
|
|
|
float4 x(_mm_loadu_ps(&t->x.x));
|
|
|
|
|
float4 y(_mm_loadu_ps(&t->y.x));
|
|
|
|
|
float4 z(_mm_loadu_ps(&t->z.x));
|
|
|
|
|
float4 w(_mm_setzero_ps());
|
2016-10-25 14:47:34 +02:00
|
|
|
|
2022-11-01 15:16:55 +01:00
|
|
|
_MM_TRANSPOSE4_PS(x.m128, y.m128, z.m128, w.m128);
|
|
|
|
|
|
|
|
|
|
float4 tmp = shuffle<2>(aa) * z;
|
2016-10-26 14:27:31 +02:00
|
|
|
tmp = madd(shuffle<1>(aa), y, tmp);
|
2022-07-21 15:49:00 +02:00
|
|
|
tmp = madd(shuffle<0>(aa), x, tmp);
|
2016-10-25 14:47:34 +02:00
|
|
|
|
|
|
|
|
return float3(tmp.m128);
|
2021-11-18 14:25:05 +01:00
|
|
|
#elif defined(__KERNEL_METAL__)
|
2024-12-29 17:32:00 +01:00
|
|
|
const ccl_private float3x3 &b(*(const ccl_private float3x3 *)t);
|
2021-11-18 14:25:05 +01:00
|
|
|
return (a * b).xyz;
|
2016-10-25 14:47:34 +02:00
|
|
|
#else
|
2012-05-28 19:21:13 +00:00
|
|
|
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);
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
|
return c;
|
2016-10-25 14:47:34 +02:00
|
|
|
#endif
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
ccl_device_inline float3 transform_direction_transposed(const ccl_private Transform *t,
|
Cycles: Kernel address space changes for MSL
This is the first of a sequence of changes to support compiling Cycles kernels as MSL (Metal Shading Language) in preparation for a Metal GPU device implementation.
MSL requires that all pointer types be declared with explicit address space attributes (device, thread, etc...). There is already precedent for this with Cycles' address space macros (ccl_global, ccl_private, etc...), therefore the first step of MSL-enablement is to apply these consistently. Line-for-line this represents the largest change required to enable MSL. Applying this change first will simplify future patches as well as offering the emergent benefit of enhanced descriptiveness.
The vast majority of deltas in this patch fall into one of two cases:
- Ensuring ccl_private is specified for thread-local pointer types
- Ensuring ccl_global is specified for device-wide pointer types
Additionally, the ccl_addr_space qualifier can be removed. Prior to Cycles X, ccl_addr_space was used as a context-dependent address space qualifier, but now it is either redundant (e.g. in struct typedefs), or can be replaced by ccl_global in the case of pointer types. Associated function variants (e.g. lcg_step_float_addrspace) are also redundant.
In cases where address space qualifiers are chained with "const", this patch places the address space qualifier first. The rationale for this is that the choice of address space is likely to have the greater impact on runtime performance and overall architecture.
The final part of this patch is the addition of a metal/compat.h header. This is partially complete and will be extended in future patches, paving the way for the full Metal implementation.
Ref T92212
Reviewed By: brecht
Maniphest Tasks: T92212
Differential Revision: https://developer.blender.org/D12864
2021-10-14 13:53:40 +01:00
|
|
|
const float3 a)
|
2012-04-30 12:49:26 +00:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 x = make_float3(t->x.x, t->y.x, t->z.x);
|
|
|
|
|
const float3 y = make_float3(t->x.y, t->y.y, t->z.y);
|
|
|
|
|
const float3 z = make_float3(t->x.z, t->y.z, t->z.z);
|
2012-04-30 12:49:26 +00:00
|
|
|
|
|
|
|
|
return make_float3(dot(x, a), dot(y, a), dot(z, a));
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline Transform make_transform(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)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
Transform t;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
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;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-25 13:02:02 +01:00
|
|
|
ccl_device_inline Transform make_transform(const float3 x, const float3 y, const float3 z)
|
|
|
|
|
{
|
|
|
|
|
Transform t;
|
|
|
|
|
|
2024-12-19 09:41:55 +01:00
|
|
|
t.x = make_float4(x, 0.0f);
|
|
|
|
|
t.y = make_float4(y, 0.0f);
|
|
|
|
|
t.z = make_float4(z, 0.0f);
|
2024-03-25 13:02:02 +01:00
|
|
|
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-04 23:17:13 +02:00
|
|
|
ccl_device_inline Transform euler_to_transform(const float3 euler)
|
|
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const float cx = cosf(euler.x);
|
|
|
|
|
const float cy = cosf(euler.y);
|
|
|
|
|
const float cz = cosf(euler.z);
|
|
|
|
|
const float sx = sinf(euler.x);
|
|
|
|
|
const float sy = sinf(euler.y);
|
|
|
|
|
const float sz = sinf(euler.z);
|
2019-09-04 23:17:13 +02:00
|
|
|
|
|
|
|
|
Transform t;
|
|
|
|
|
t.x.x = cy * cz;
|
|
|
|
|
t.y.x = cy * sz;
|
|
|
|
|
t.z.x = -sy;
|
|
|
|
|
|
|
|
|
|
t.x.y = sy * sx * cz - cx * sz;
|
|
|
|
|
t.y.y = sy * sx * sz + cx * cz;
|
|
|
|
|
t.z.y = cy * sx;
|
|
|
|
|
|
|
|
|
|
t.x.z = sy * cx * cz + sx * sz;
|
|
|
|
|
t.y.z = sy * cx * sz - sx * cz;
|
|
|
|
|
t.z.z = cy * cx;
|
|
|
|
|
|
|
|
|
|
t.x.w = t.y.w = t.z.w = 0.0f;
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-07 12:18:57 +02:00
|
|
|
/* Constructs a coordinate frame from a normalized normal. */
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline Transform make_transform_frame(const float3 N)
|
2016-07-07 12:18:57 +02:00
|
|
|
{
|
|
|
|
|
const float3 dx0 = cross(make_float3(1.0f, 0.0f, 0.0f), N);
|
|
|
|
|
const float3 dx1 = cross(make_float3(0.0f, 1.0f, 0.0f), N);
|
|
|
|
|
const float3 dx = normalize((dot(dx0, dx0) > dot(dx1, dx1)) ? dx0 : dx1);
|
|
|
|
|
const float3 dy = normalize(cross(N, dx));
|
|
|
|
|
return make_transform(dx.x, dx.y, dx.z, 0.0f, dy.x, dy.y, dy.z, 0.0f, N.x, N.y, N.z, 0.0f);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-09 14:25:32 +01:00
|
|
|
#if !defined(__KERNEL_METAL__)
|
2013-11-16 00:17:10 +01:00
|
|
|
ccl_device_inline Transform operator*(const Transform a, const Transform b)
|
2013-05-09 14:05:40 +00:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const float4 c_x = make_float4(b.x.x, b.y.x, b.z.x, 0.0f);
|
|
|
|
|
const float4 c_y = make_float4(b.x.y, b.y.y, b.z.y, 0.0f);
|
|
|
|
|
const float4 c_z = make_float4(b.x.z, b.y.z, b.z.z, 0.0f);
|
|
|
|
|
const float4 c_w = make_float4(b.x.w, b.y.w, b.z.w, 1.0f);
|
2013-05-09 14:05:40 +00:00
|
|
|
|
2018-03-08 06:48:14 +01:00
|
|
|
Transform 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));
|
2013-05-09 14:05:40 +00:00
|
|
|
|
|
|
|
|
return t;
|
|
|
|
|
}
|
2022-11-09 14:25:32 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ccl_device_inline Transform transform_zero()
|
|
|
|
|
{
|
|
|
|
|
Transform zero = {zero_float4(), zero_float4(), zero_float4()};
|
|
|
|
|
return zero;
|
|
|
|
|
}
|
2013-05-09 14:05:40 +00:00
|
|
|
|
2024-12-27 21:50:31 +01:00
|
|
|
#ifndef __KERNEL_GPU__
|
|
|
|
|
|
2013-11-16 00:17:10 +01:00
|
|
|
ccl_device_inline void print_transform(const char *label, const Transform &t)
|
2013-05-08 17:33:25 +00:00
|
|
|
{
|
|
|
|
|
print_float4(label, t.x);
|
|
|
|
|
print_float4(label, t.y);
|
|
|
|
|
print_float4(label, t.z);
|
|
|
|
|
printf("\n");
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline Transform transform_translate(const float3 t)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
return make_transform(1, 0, 0, t.x, 0, 1, 0, t.y, 0, 0, 1, t.z);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline Transform transform_translate(const float x, const float y, float z)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
return transform_translate(make_float3(x, y, z));
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline Transform transform_scale(const float3 s)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
return make_transform(s.x, 0, 0, 0, 0, s.y, 0, 0, 0, 0, s.z, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline Transform transform_scale(const float x, const float y, float z)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
return transform_scale(make_float3(x, y, z));
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline Transform transform_rotate(const float angle, float3 axis)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const float s = sinf(angle);
|
|
|
|
|
const float c = cosf(angle);
|
|
|
|
|
const float t = 1.0f - c;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
axis = normalize(axis);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
return make_transform(axis.x * axis.x * t + c,
|
|
|
|
|
axis.x * axis.y * t - s * axis.z,
|
|
|
|
|
axis.x * axis.z * t + s * axis.y,
|
|
|
|
|
0.0f,
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
axis.y * axis.x * t + s * axis.z,
|
|
|
|
|
axis.y * axis.y * t + c,
|
|
|
|
|
axis.y * axis.z * t - s * axis.x,
|
|
|
|
|
0.0f,
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
axis.z * axis.x * t - s * axis.y,
|
|
|
|
|
axis.z * axis.y * t + s * axis.x,
|
|
|
|
|
axis.z * axis.z * t + c,
|
2018-03-08 06:48:14 +01:00
|
|
|
0.0f);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2015-01-15 13:23:33 +05:00
|
|
|
/* Euler is assumed to be in XYZ order. */
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline Transform transform_euler(const float3 euler)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2015-01-15 13:23:33 +05:00
|
|
|
return transform_rotate(euler.z, make_float3(0.0f, 0.0f, 1.0f)) *
|
2011-05-12 11:34:16 +00:00
|
|
|
transform_rotate(euler.y, make_float3(0.0f, 1.0f, 0.0f)) *
|
2015-01-15 13:23:33 +05:00
|
|
|
transform_rotate(euler.x, make_float3(1.0f, 0.0f, 0.0f));
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-16 00:17:10 +01:00
|
|
|
ccl_device_inline Transform transform_identity()
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
return transform_scale(1.0f, 1.0f, 1.0f);
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-16 00:17:10 +01:00
|
|
|
ccl_device_inline bool operator==(const Transform &A, const Transform &B)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2024-12-27 21:50:31 +01:00
|
|
|
return A.x == B.x && A.y == B.y && A.z == B.z;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-16 00:17:10 +01:00
|
|
|
ccl_device_inline bool operator!=(const Transform &A, const Transform &B)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
return !(A == B);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-22 20:41:46 +01:00
|
|
|
ccl_device_inline bool transform_equal_threshold(const Transform &A,
|
|
|
|
|
const Transform &B,
|
|
|
|
|
const float threshold)
|
|
|
|
|
{
|
|
|
|
|
for (int x = 0; x < 3; x++) {
|
|
|
|
|
for (int y = 0; y < 4; y++) {
|
|
|
|
|
if (fabsf(A[x][y] - B[x][y]) > threshold) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline float3 transform_get_column(const Transform *t, const int column)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
return make_float3(t->x[column], t->y[column], t->z[column]);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline void transform_set_column(Transform *t, const int column, const float3 value)
|
2011-12-19 14:23:24 +00:00
|
|
|
{
|
|
|
|
|
t->x[column] = value.x;
|
|
|
|
|
t->y[column] = value.y;
|
|
|
|
|
t->z[column] = value.z;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
Transform transform_transposed_inverse(const Transform &tfm);
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2013-11-16 00:17:10 +01:00
|
|
|
ccl_device_inline bool transform_uniform_scale(const Transform &tfm, float &scale)
|
2011-09-02 16:15:18 +00:00
|
|
|
{
|
|
|
|
|
/* the epsilon here is quite arbitrary, but this function is only used for
|
2018-03-08 06:48:14 +01:00
|
|
|
* surface area and bump, where we expect it to not be so sensitive */
|
2024-12-29 17:32:00 +01:00
|
|
|
const float eps = 1e-6f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const float sx = len_squared(make_float3(tfm.x));
|
|
|
|
|
const float sy = len_squared(make_float3(tfm.y));
|
|
|
|
|
const float sz = len_squared(make_float3(tfm.z));
|
|
|
|
|
const float stx = len_squared(transform_get_column(&tfm, 0));
|
|
|
|
|
const float sty = len_squared(transform_get_column(&tfm, 1));
|
|
|
|
|
const float stz = len_squared(transform_get_column(&tfm, 2));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-09-02 16:15:18 +00:00
|
|
|
if (fabsf(sx - sy) < eps && fabsf(sx - sz) < eps && fabsf(sx - stx) < eps &&
|
|
|
|
|
fabsf(sx - sty) < eps && fabsf(sx - stz) < eps)
|
|
|
|
|
{
|
|
|
|
|
scale = sx;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-02-03 13:55:26 +11:00
|
|
|
return false;
|
2011-09-02 16:15:18 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-16 00:17:10 +01:00
|
|
|
ccl_device_inline bool transform_negative_scale(const Transform &tfm)
|
2011-11-12 14:29:52 +00:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 c0 = transform_get_column(&tfm, 0);
|
|
|
|
|
const float3 c1 = transform_get_column(&tfm, 1);
|
|
|
|
|
const float3 c2 = transform_get_column(&tfm, 2);
|
2011-11-12 14:29:52 +00:00
|
|
|
|
|
|
|
|
return (dot(cross(c0, c1), c2) < 0.0f);
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-16 00:17:10 +01:00
|
|
|
ccl_device_inline Transform transform_clear_scale(const Transform &tfm)
|
2011-12-19 14:23:24 +00:00
|
|
|
{
|
|
|
|
|
Transform ntfm = tfm;
|
|
|
|
|
|
|
|
|
|
transform_set_column(&ntfm, 0, normalize(transform_get_column(&ntfm, 0)));
|
|
|
|
|
transform_set_column(&ntfm, 1, normalize(transform_get_column(&ntfm, 1)));
|
|
|
|
|
transform_set_column(&ntfm, 2, normalize(transform_get_column(&ntfm, 2)));
|
|
|
|
|
|
|
|
|
|
return ntfm;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-04 23:24:29 +02:00
|
|
|
ccl_device_inline Transform transform_empty()
|
|
|
|
|
{
|
|
|
|
|
return make_transform(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
/* Motion Transform */
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline float4 quat_interpolate(const float4 q1, const float4 q2, const float t)
|
2012-04-30 12:49:26 +00:00
|
|
|
{
|
2023-05-12 19:55:46 +02:00
|
|
|
/* Optix and MetalRT are using linear interpolation to interpolate motion transformations. */
|
2021-11-29 15:06:22 +00:00
|
|
|
#if defined(__KERNEL_GPU_RAYTRACING__)
|
2012-11-29 13:07:45 +00:00
|
|
|
return normalize((1.0f - t) * q1 + t * q2);
|
2024-12-26 17:53:59 +01:00
|
|
|
#else /* defined(__KERNEL_GPU_RAYTRACING__) */
|
2021-11-30 09:10:05 +11:00
|
|
|
/* NOTE: this does not ensure rotation around shortest angle, q1 and q2
|
2012-11-11 15:02:05 +00:00
|
|
|
* are assumed to be matched already in transform_motion_decompose */
|
2024-12-29 17:32:00 +01:00
|
|
|
const float costheta = dot(q1, q2);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-11 15:02:05 +00:00
|
|
|
/* possible optimization: it might be possible to precompute theta/qperp */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:16:53 +02:00
|
|
|
if (costheta > 0.9995f) {
|
2012-10-15 17:56:40 +00:00
|
|
|
/* linear interpolation in degenerate case */
|
2019-04-17 08:16:53 +02:00
|
|
|
return normalize((1.0f - t) * q1 + t * q2);
|
2012-04-30 12:49:26 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
/* slerp */
|
2024-12-29 17:32:00 +01:00
|
|
|
const float theta = acosf(clamp(costheta, -1.0f, 1.0f));
|
|
|
|
|
const float4 qperp = normalize(q2 - q1 * costheta);
|
|
|
|
|
const float thetap = theta * t;
|
2024-12-26 17:53:59 +01:00
|
|
|
return q1 * cosf(thetap) + qperp * sinf(thetap);
|
|
|
|
|
|
2021-11-29 15:06:22 +00:00
|
|
|
#endif /* defined(__KERNEL_GPU_RAYTRACING__) */
|
2012-04-30 12:49:26 +00:00
|
|
|
}
|
|
|
|
|
|
2022-08-09 14:28:19 +02:00
|
|
|
#ifndef __KERNEL_GPU__
|
|
|
|
|
void transform_inverse_cpu_avx2(const Transform &tfm, Transform &itfm);
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-12-27 22:40:46 +01:00
|
|
|
/* Custom cross and dot implementations that match Embree bit for bit.
|
|
|
|
|
* Normally we don't use SSE41/AVX outside the kernel, but for this it's
|
|
|
|
|
* important to match exactly for ray tracing precision. */
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline float3 transform_inverse_cross(const float3 a_, const float3 b_)
|
|
|
|
|
{
|
|
|
|
|
#if defined(__AVX2__) && defined(__KERNEL_SSE2__)
|
|
|
|
|
const __m128 a = (const __m128 &)a_;
|
|
|
|
|
const __m128 b = (const __m128 &)b_;
|
|
|
|
|
const __m128 a_shuffle = _mm_castsi128_ps(
|
|
|
|
|
_mm_shuffle_epi32(_mm_castps_si128(a), _MM_SHUFFLE(3, 0, 2, 1)));
|
|
|
|
|
const __m128 b_shuffle = _mm_castsi128_ps(
|
|
|
|
|
_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(3, 0, 2, 1)));
|
|
|
|
|
const __m128 r = _mm_castsi128_ps(
|
|
|
|
|
_mm_shuffle_epi32(_mm_castps_si128(_mm_fmsub_ps(a, b_shuffle, _mm_mul_ps(a_shuffle, b))),
|
|
|
|
|
_MM_SHUFFLE(3, 0, 2, 1)));
|
|
|
|
|
return (const float3 &)r;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return cross(a_, b_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline float transform_inverse_dot(const float3 a_, const float3 b_)
|
|
|
|
|
{
|
|
|
|
|
#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE42__)
|
|
|
|
|
const __m128 a = (const __m128 &)a_;
|
|
|
|
|
const __m128 b = (const __m128 &)b_;
|
|
|
|
|
return _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7F));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return dot(a_, b_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline Transform transform_inverse_impl(const Transform tfm)
|
|
|
|
|
{
|
|
|
|
|
/* This implementation matches the one in Embree exactly, to ensure consistent
|
|
|
|
|
* results with the ray intersection of instances. */
|
|
|
|
|
float3 x = make_float3(tfm.x.x, tfm.y.x, tfm.z.x);
|
|
|
|
|
float3 y = make_float3(tfm.x.y, tfm.y.y, tfm.z.y);
|
|
|
|
|
float3 z = make_float3(tfm.x.z, tfm.y.z, tfm.z.z);
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 w = make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
|
2024-12-27 22:40:46 +01:00
|
|
|
|
|
|
|
|
/* Compute determinant. */
|
|
|
|
|
float det = transform_inverse_dot(x, transform_inverse_cross(y, z));
|
|
|
|
|
|
|
|
|
|
if (det == 0.0f) {
|
|
|
|
|
/* Matrix is degenerate (e.g. 0 scale on some axis), ideally we should
|
|
|
|
|
* never be in this situation, but try to invert it anyway with tweak.
|
|
|
|
|
*
|
|
|
|
|
* This logic does not match Embree which would just give an invalid
|
|
|
|
|
* matrix. A better solution would be to remove this and ensure any object
|
|
|
|
|
* matrix is valid. */
|
|
|
|
|
x.x += 1e-8f;
|
|
|
|
|
y.y += 1e-8f;
|
|
|
|
|
z.z += 1e-8f;
|
|
|
|
|
|
|
|
|
|
det = transform_inverse_dot(x, cross(y, z));
|
|
|
|
|
if (det == 0.0f) {
|
|
|
|
|
det = FLT_MAX;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Divide adjoint matrix by the determinant to compute inverse of 3x3 matrix. */
|
|
|
|
|
const float3 inverse_x = transform_inverse_cross(y, z) / det;
|
|
|
|
|
const float3 inverse_y = transform_inverse_cross(z, x) / det;
|
|
|
|
|
const float3 inverse_z = transform_inverse_cross(x, y) / det;
|
|
|
|
|
|
|
|
|
|
/* Compute translation and fill transform. */
|
|
|
|
|
Transform itfm;
|
|
|
|
|
itfm.x = make_float4(inverse_x, -transform_inverse_dot(inverse_x, w));
|
|
|
|
|
itfm.y = make_float4(inverse_y, -transform_inverse_dot(inverse_y, w));
|
|
|
|
|
itfm.z = make_float4(inverse_z, -transform_inverse_dot(inverse_z, w));
|
|
|
|
|
|
|
|
|
|
return itfm;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-21 15:49:00 +02:00
|
|
|
ccl_device_inline Transform transform_inverse(const Transform tfm)
|
2012-04-30 12:49:26 +00:00
|
|
|
{
|
2022-08-09 14:28:19 +02:00
|
|
|
/* Optimized transform implementations. */
|
|
|
|
|
#ifndef __KERNEL_GPU__
|
|
|
|
|
if (system_cpu_support_avx2()) {
|
|
|
|
|
Transform itfm;
|
|
|
|
|
transform_inverse_cpu_avx2(tfm, itfm);
|
|
|
|
|
return itfm;
|
2015-10-08 21:14:14 +05:00
|
|
|
}
|
2022-08-09 14:28:19 +02:00
|
|
|
#endif
|
2022-07-21 15:49:00 +02:00
|
|
|
|
2022-08-09 14:28:19 +02:00
|
|
|
return transform_inverse_impl(tfm);
|
2012-04-30 12:49:26 +00:00
|
|
|
}
|
|
|
|
|
|
Cycles: Kernel address space changes for MSL
This is the first of a sequence of changes to support compiling Cycles kernels as MSL (Metal Shading Language) in preparation for a Metal GPU device implementation.
MSL requires that all pointer types be declared with explicit address space attributes (device, thread, etc...). There is already precedent for this with Cycles' address space macros (ccl_global, ccl_private, etc...), therefore the first step of MSL-enablement is to apply these consistently. Line-for-line this represents the largest change required to enable MSL. Applying this change first will simplify future patches as well as offering the emergent benefit of enhanced descriptiveness.
The vast majority of deltas in this patch fall into one of two cases:
- Ensuring ccl_private is specified for thread-local pointer types
- Ensuring ccl_global is specified for device-wide pointer types
Additionally, the ccl_addr_space qualifier can be removed. Prior to Cycles X, ccl_addr_space was used as a context-dependent address space qualifier, but now it is either redundant (e.g. in struct typedefs), or can be replaced by ccl_global in the case of pointer types. Associated function variants (e.g. lcg_step_float_addrspace) are also redundant.
In cases where address space qualifiers are chained with "const", this patch places the address space qualifier first. The rationale for this is that the choice of address space is likely to have the greater impact on runtime performance and overall architecture.
The final part of this patch is the addition of a metal/compat.h header. This is partially complete and will be extended in future patches, paving the way for the full Metal implementation.
Ref T92212
Reviewed By: brecht
Maniphest Tasks: T92212
Differential Revision: https://developer.blender.org/D12864
2021-10-14 13:53:40 +01:00
|
|
|
ccl_device_inline void transform_compose(ccl_private Transform *tfm,
|
2024-12-29 17:32:00 +01:00
|
|
|
const ccl_private DecomposedTransform *decomp)
|
2012-04-30 12:49:26 +00:00
|
|
|
{
|
|
|
|
|
/* rotation */
|
2024-12-29 17:32:00 +01:00
|
|
|
float q0;
|
|
|
|
|
float q1;
|
|
|
|
|
float q2;
|
|
|
|
|
float q3;
|
|
|
|
|
float qda;
|
|
|
|
|
float qdb;
|
|
|
|
|
float qdc;
|
|
|
|
|
float qaa;
|
|
|
|
|
float qab;
|
|
|
|
|
float qac;
|
|
|
|
|
float qbb;
|
|
|
|
|
float qbc;
|
|
|
|
|
float qcc;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
q0 = M_SQRT2_F * decomp->x.w;
|
|
|
|
|
q1 = M_SQRT2_F * decomp->x.x;
|
|
|
|
|
q2 = M_SQRT2_F * decomp->x.y;
|
|
|
|
|
q3 = M_SQRT2_F * decomp->x.z;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
qda = q0 * q1;
|
|
|
|
|
qdb = q0 * q2;
|
|
|
|
|
qdc = q0 * q3;
|
|
|
|
|
qaa = q1 * q1;
|
|
|
|
|
qab = q1 * q2;
|
|
|
|
|
qac = q1 * q3;
|
|
|
|
|
qbb = q2 * q2;
|
|
|
|
|
qbc = q2 * q3;
|
|
|
|
|
qcc = q3 * q3;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 rotation_x = make_float3(1.0f - qbb - qcc, -qdc + qab, qdb + qac);
|
|
|
|
|
const float3 rotation_y = make_float3(qdc + qab, 1.0f - qaa - qcc, -qda + qbc);
|
|
|
|
|
const float3 rotation_z = make_float3(-qdb + qac, qda + qbc, 1.0f - qaa - qbb);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
/* scale */
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 scale_x = make_float3(decomp->y.w, decomp->z.z, decomp->w.y);
|
|
|
|
|
const float3 scale_y = make_float3(decomp->z.x, decomp->z.w, decomp->w.z);
|
|
|
|
|
const float3 scale_z = make_float3(decomp->z.y, decomp->w.x, decomp->w.w);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
/* compose with translation */
|
|
|
|
|
tfm->x = make_float4(
|
|
|
|
|
dot(rotation_x, scale_x), dot(rotation_x, scale_y), dot(rotation_x, scale_z), decomp->y.x);
|
|
|
|
|
tfm->y = make_float4(
|
|
|
|
|
dot(rotation_y, scale_x), dot(rotation_y, scale_y), dot(rotation_y, scale_z), decomp->y.y);
|
|
|
|
|
tfm->z = make_float4(
|
|
|
|
|
dot(rotation_z, scale_x), dot(rotation_z, scale_y), dot(rotation_z, scale_z), decomp->y.z);
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-10 01:36:09 +01:00
|
|
|
/* Interpolate from array of decomposed transforms. */
|
2021-11-18 14:25:05 +01:00
|
|
|
ccl_device void transform_motion_array_interpolate(ccl_private Transform *tfm,
|
2024-12-29 17:32:00 +01:00
|
|
|
const ccl_global DecomposedTransform *motion,
|
2025-01-01 18:15:54 +01:00
|
|
|
const uint numsteps,
|
|
|
|
|
const float time)
|
2018-03-07 23:52:26 +01:00
|
|
|
{
|
2018-03-10 01:36:09 +01:00
|
|
|
/* Figure out which steps we need to interpolate. */
|
2024-12-29 17:32:00 +01:00
|
|
|
const int maxstep = numsteps - 1;
|
|
|
|
|
const int step = min((int)(time * maxstep), maxstep - 1);
|
|
|
|
|
const float t = time * maxstep - step;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const ccl_global DecomposedTransform *a = motion + step;
|
|
|
|
|
const ccl_global DecomposedTransform *b = motion + step + 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-03-10 01:36:09 +01:00
|
|
|
/* Interpolate rotation, translation and scale. */
|
2018-03-08 06:19:17 +01:00
|
|
|
DecomposedTransform decomp;
|
2018-03-10 01:36:09 +01:00
|
|
|
decomp.x = quat_interpolate(a->x, b->x, t);
|
|
|
|
|
decomp.y = (1.0f - t) * a->y + t * b->y;
|
|
|
|
|
decomp.z = (1.0f - t) * a->z + t * b->z;
|
|
|
|
|
decomp.w = (1.0f - t) * a->w + t * b->w;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-03-10 01:36:09 +01:00
|
|
|
/* Compose rotation, translation, scale into matrix. */
|
2012-04-30 12:49:26 +00:00
|
|
|
transform_compose(tfm, &decomp);
|
|
|
|
|
}
|
|
|
|
|
|
Cycles: Kernel address space changes for MSL
This is the first of a sequence of changes to support compiling Cycles kernels as MSL (Metal Shading Language) in preparation for a Metal GPU device implementation.
MSL requires that all pointer types be declared with explicit address space attributes (device, thread, etc...). There is already precedent for this with Cycles' address space macros (ccl_global, ccl_private, etc...), therefore the first step of MSL-enablement is to apply these consistently. Line-for-line this represents the largest change required to enable MSL. Applying this change first will simplify future patches as well as offering the emergent benefit of enhanced descriptiveness.
The vast majority of deltas in this patch fall into one of two cases:
- Ensuring ccl_private is specified for thread-local pointer types
- Ensuring ccl_global is specified for device-wide pointer types
Additionally, the ccl_addr_space qualifier can be removed. Prior to Cycles X, ccl_addr_space was used as a context-dependent address space qualifier, but now it is either redundant (e.g. in struct typedefs), or can be replaced by ccl_global in the case of pointer types. Associated function variants (e.g. lcg_step_float_addrspace) are also redundant.
In cases where address space qualifiers are chained with "const", this patch places the address space qualifier first. The rationale for this is that the choice of address space is likely to have the greater impact on runtime performance and overall architecture.
The final part of this patch is the addition of a metal/compat.h header. This is partially complete and will be extended in future patches, paving the way for the full Metal implementation.
Ref T92212
Reviewed By: brecht
Maniphest Tasks: T92212
Differential Revision: https://developer.blender.org/D12864
2021-10-14 13:53:40 +01:00
|
|
|
ccl_device_inline bool transform_isfinite_safe(ccl_private Transform *tfm)
|
2020-08-03 11:04:10 +02:00
|
|
|
{
|
2022-06-23 14:29:17 +02:00
|
|
|
return isfinite_safe(tfm->x) && isfinite_safe(tfm->y) && isfinite_safe(tfm->z);
|
2020-08-03 11:04:10 +02:00
|
|
|
}
|
|
|
|
|
|
Cycles: Kernel address space changes for MSL
This is the first of a sequence of changes to support compiling Cycles kernels as MSL (Metal Shading Language) in preparation for a Metal GPU device implementation.
MSL requires that all pointer types be declared with explicit address space attributes (device, thread, etc...). There is already precedent for this with Cycles' address space macros (ccl_global, ccl_private, etc...), therefore the first step of MSL-enablement is to apply these consistently. Line-for-line this represents the largest change required to enable MSL. Applying this change first will simplify future patches as well as offering the emergent benefit of enhanced descriptiveness.
The vast majority of deltas in this patch fall into one of two cases:
- Ensuring ccl_private is specified for thread-local pointer types
- Ensuring ccl_global is specified for device-wide pointer types
Additionally, the ccl_addr_space qualifier can be removed. Prior to Cycles X, ccl_addr_space was used as a context-dependent address space qualifier, but now it is either redundant (e.g. in struct typedefs), or can be replaced by ccl_global in the case of pointer types. Associated function variants (e.g. lcg_step_float_addrspace) are also redundant.
In cases where address space qualifiers are chained with "const", this patch places the address space qualifier first. The rationale for this is that the choice of address space is likely to have the greater impact on runtime performance and overall architecture.
The final part of this patch is the addition of a metal/compat.h header. This is partially complete and will be extended in future patches, paving the way for the full Metal implementation.
Ref T92212
Reviewed By: brecht
Maniphest Tasks: T92212
Differential Revision: https://developer.blender.org/D12864
2021-10-14 13:53:40 +01:00
|
|
|
ccl_device_inline bool transform_decomposed_isfinite_safe(ccl_private DecomposedTransform *decomp)
|
2020-08-03 11:04:10 +02:00
|
|
|
{
|
2022-06-23 14:29:17 +02:00
|
|
|
return isfinite_safe(decomp->x) && isfinite_safe(decomp->y) && isfinite_safe(decomp->z) &&
|
|
|
|
|
isfinite_safe(decomp->w);
|
2020-08-03 11:04:10 +02:00
|
|
|
}
|
|
|
|
|
|
2018-11-07 13:29:20 +01:00
|
|
|
#ifndef __KERNEL_GPU__
|
|
|
|
|
|
2015-04-10 15:52:40 +05:00
|
|
|
class BoundBox2D;
|
|
|
|
|
|
2018-03-08 06:19:17 +01:00
|
|
|
ccl_device_inline bool operator==(const DecomposedTransform &A, const DecomposedTransform &B)
|
|
|
|
|
{
|
2024-12-27 21:50:31 +01:00
|
|
|
return A.x == B.x && A.y == B.y && A.z == B.z && A.w == B.w;
|
2018-03-08 06:19:17 +01:00
|
|
|
}
|
|
|
|
|
|
2013-04-05 23:03:10 +00:00
|
|
|
float4 transform_to_quat(const Transform &tfm);
|
2025-01-01 18:15:54 +01:00
|
|
|
void transform_motion_decompose(DecomposedTransform *decomp,
|
|
|
|
|
const Transform *motion,
|
|
|
|
|
const size_t size);
|
2015-04-10 15:52:40 +05:00
|
|
|
Transform transform_from_viewplane(BoundBox2D &viewplane);
|
2012-04-30 12:49:26 +00:00
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
/* TODO: This can be removed when we know if no devices will require explicit
|
|
|
|
|
* address space qualifiers for this case. */
|
2015-05-14 18:19:21 +05:00
|
|
|
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
#define transform_point_auto transform_point
|
|
|
|
|
#define transform_direction_auto transform_direction
|
|
|
|
|
#define transform_direction_transposed_auto transform_direction_transposed
|
2015-05-14 18:19:21 +05:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_END
|