17#define SET_CUBIC_SPLINE_WEIGHTS(u, t) \
19 u[0] = (((-1.0f / 6.0f) * t + 0.5f) * t - 0.5f) * t + (1.0f / 6.0f); \
20 u[1] = ((0.5f * t - 1.0f) * t) * t + (2.0f / 3.0f); \
21 u[2] = ((-0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f / 6.0f); \
22 u[3] = (1.0f / 6.0f) * t * t * t; \
37 if constexpr (std::is_same<OutT, float4>::value) {
52 const float f = 1.0f / 255.0f;
58 return r * (1.0f / 255.0f);
78 return r * (1.0f / 65535.0f);
83 const float f = 1.0f / 65535.0f;
91 return read(data[y * width + x]);
101 return read(data[y * width + x]);
107 read(
const TexT *data,
int x,
int y,
int z,
int width,
int height,
int depth)
109 return read(data[x + y * width +
z * width * height]);
115 read_clip(
const TexT *data,
int x,
int y,
int z,
int width,
int height,
int depth)
120 return read(data[x + y * width +
z * width * height]);
138 OutT read(
const TexT *,
int,
int,
int,
int,
int,
int))
140 OutT r = (1.0f - tz) * (1.0f - ty) * (1.0f - tx) *
141 read(data, ix, iy, iz, width, height, depth);
142 r += (1.0f - tz) * (1.0f - ty) * tx * read(data, nix, iy, iz, width, height, depth);
143 r += (1.0f - tz) * ty * (1.0f - tx) * read(data, ix, niy, iz, width, height, depth);
144 r += (1.0f - tz) * ty * tx * read(data, nix, niy, iz, width, height, depth);
146 r += tz * (1.0f - ty) * (1.0f - tx) * read(data, ix, iy, niz, width, height, depth);
147 r += tz * (1.0f - ty) * tx * read(data, nix, iy, niz, width, height, depth);
148 r += tz * ty * (1.0f - tx) * read(data, ix, niy, niz, width, height, depth);
149 r += tz * ty * tx * read(data, nix, niy, niz, width, height, depth);
165 OutT read(
const TexT *,
int,
int,
int,
int,
int,
int))
167 float u[4],
v[4],
w[4];
172#define DATA(x, y, z) (read(data, xc[x], yc[y], zc[z], width, height, depth))
173#define COL_TERM(col, row) \
174 (v[col] * (u[0] * DATA(0, col, row) + u[1] * DATA(1, col, row) + u[2] * DATA(2, col, row) + \
175 u[3] * DATA(3, col, row)))
176#define ROW_TERM(row) \
177 (w[row] * (COL_TERM(0, row) + COL_TERM(1, row) + COL_TERM(2, row) + COL_TERM(3, row)))
201 return clamp(x, 0, width - 1);
206 const int m =
abs(x + (x < 0)) % (2 * width);
208 return 2 * width - m - 1;
216 const int width = info.
width;
217 const int height = info.
height;
219 frac(x * (
float)width, &ix);
220 frac(y * (
float)height, &iy);
223 ix = wrap_periodic(ix, width);
224 iy = wrap_periodic(iy, height);
228 if (ix < 0 || ix >= width || iy < 0 || iy >= height) {
233 ix = wrap_clamp(ix, width);
234 iy = wrap_clamp(iy, height);
237 ix = wrap_mirror(ix, width);
238 iy = wrap_mirror(iy, height);
245 const TexT *data = (
const TexT *)info.
data;
246 return read((
const TexT *)data, ix, iy, width, height);
251 const int width = info.
width;
252 const int height = info.
height;
257 const float tx =
frac(x * (
float)width - 0.5f, &ix);
258 const float ty =
frac(y * (
float)height - 0.5f, &iy);
259 const TexT *data = (
const TexT *)info.
data;
263 ix = wrap_periodic(ix, width);
264 nix = wrap_periodic(ix + 1, width);
266 iy = wrap_periodic(iy, height);
267 niy = wrap_periodic(iy + 1, height);
271 if (ix < -1 || ix >= width || iy < -1 || iy >= height) {
276 return (1.0f - ty) * (1.0f - tx) * read_clip(data, ix, iy, width, height) +
277 (1.0f - ty) * tx * read_clip(data, nix, iy, width, height) +
278 ty * (1.0f - tx) * read_clip(data, ix, niy, width, height) +
279 ty * tx * read_clip(data, nix, niy, width, height);
281 nix = wrap_clamp(ix + 1, width);
282 ix = wrap_clamp(ix, width);
283 niy = wrap_clamp(iy + 1, height);
284 iy = wrap_clamp(iy, height);
287 nix = wrap_mirror(ix + 1, width);
288 ix = wrap_mirror(ix, width);
289 niy = wrap_mirror(iy + 1, height);
290 iy = wrap_mirror(iy, height);
297 return (1.0f - ty) * (1.0f - tx) * read(data, ix, iy, width, height) +
298 (1.0f - ty) * tx * read(data, nix, iy, width, height) +
299 ty * (1.0f - tx) * read(data, ix, niy, width, height) +
300 ty * tx * read(data, nix, niy, width, height);
305 const int width = info.
width;
306 const int height = info.
height;
310 const float tx =
frac(x * (
float)width - 0.5f, &ix);
311 const float ty =
frac(y * (
float)height - 0.5f, &iy);
319 ix = wrap_periodic(ix, width);
320 pix = wrap_periodic(ix - 1, width);
321 nix = wrap_periodic(ix + 1, width);
322 nnix = wrap_periodic(ix + 2, width);
324 iy = wrap_periodic(iy, height);
325 piy = wrap_periodic(iy - 1, height);
326 niy = wrap_periodic(iy + 1, height);
327 nniy = wrap_periodic(iy + 2, height);
331 if (ix < -2 || ix > width || iy < -2 || iy > height) {
344 pix = wrap_clamp(ix - 1, width);
345 nix = wrap_clamp(ix + 1, width);
346 nnix = wrap_clamp(ix + 2, width);
347 ix = wrap_clamp(ix, width);
349 piy = wrap_clamp(iy - 1, height);
350 niy = wrap_clamp(iy + 1, height);
351 nniy = wrap_clamp(iy + 2, height);
352 iy = wrap_clamp(iy, height);
355 pix = wrap_mirror(ix - 1, width);
356 nix = wrap_mirror(ix + 1, width);
357 nnix = wrap_mirror(ix + 2, width);
358 ix = wrap_mirror(ix, width);
360 piy = wrap_mirror(iy - 1, height);
361 niy = wrap_mirror(iy + 1, height);
362 nniy = wrap_mirror(iy + 2, height);
363 iy = wrap_mirror(iy, height);
370 const TexT *data = (
const TexT *)info.
data;
371 const int xc[4] = {pix, ix, nix, nnix};
372 const int yc[4] = {piy, iy, niy, nniy};
378#define DATA(x, y) (read_clip(data, xc[x], yc[y], width, height))
381 (u[0] * DATA(0, col) + u[1] * DATA(1, col) + u[2] * DATA(2, col) + u[3] * DATA(3, col)))
396 return interp_closest(info, x, y);
398 return interp_linear(info, x, y);
400 return interp_cubic(info, x, y);
411 const int width = info.
width;
412 const int height = info.
height;
413 const int depth = info.
depth;
416 frac(x * (
float)width, &ix);
417 frac(y * (
float)height, &iy);
418 frac(
z * (
float)depth, &iz);
422 ix = wrap_periodic(ix, width);
423 iy = wrap_periodic(iy, height);
424 iz = wrap_periodic(iz, depth);
428 if (ix < 0 || ix >= width || iy < 0 || iy >= height || iz < 0 || iz >= depth) {
433 ix = wrap_clamp(ix, width);
434 iy = wrap_clamp(iy, height);
435 iz = wrap_clamp(iz, depth);
438 ix = wrap_mirror(ix, width);
439 iy = wrap_mirror(iy, height);
440 iz = wrap_mirror(iz, depth);
447 const TexT *data = (
const TexT *)info.
data;
448 return read(data, ix, iy, iz, width, height, depth);
456 const int width = info.
width;
457 const int height = info.
height;
458 const int depth = info.
depth;
463 float tx =
frac(x * (
float)width - 0.5f, &ix);
464 float ty =
frac(y * (
float)height - 0.5f, &iy);
465 float tz =
frac(
z * (
float)depth - 0.5f, &iz);
469 ix = wrap_periodic(ix, width);
470 nix = wrap_periodic(ix + 1, width);
472 iy = wrap_periodic(iy, height);
473 niy = wrap_periodic(iy + 1, height);
475 iz = wrap_periodic(iz, depth);
476 niz = wrap_periodic(iz + 1, depth);
480 if (ix < -1 || ix >= width || iy < -1 || iy >= height || iz < -1 || iz >= depth) {
489 if (ix >= 0 && nix < width && iy >= 0 && niy < height && iz >= 0 && niz < depth) {
495 return trilinear_lookup((
const TexT *)info.
data,
510 nix = wrap_clamp(ix + 1, width);
511 ix = wrap_clamp(ix, width);
513 niy = wrap_clamp(iy + 1, height);
514 iy = wrap_clamp(iy, height);
516 niz = wrap_clamp(iz + 1, depth);
517 iz = wrap_clamp(iz, depth);
520 nix = wrap_mirror(ix + 1, width);
521 ix = wrap_mirror(ix, width);
523 niy = wrap_mirror(iy + 1, height);
524 iy = wrap_mirror(iy, height);
526 niz = wrap_mirror(iz + 1, depth);
527 iz = wrap_mirror(iz, depth);
534 return trilinear_lookup((
const TexT *)info.
data,
558#if defined(__GNUC__) || defined(__clang__)
566 int width = info.
width;
568 int depth = info.
depth;
572 const float tx =
frac(x * (
float)width - 0.5f, &ix);
573 const float ty =
frac(y * (
float)height - 0.5f, &iy);
574 const float tz =
frac(
z * (
float)depth - 0.5f, &iz);
578 int nnix, nniy, nniz;
582 ix = wrap_periodic(ix, width);
583 pix = wrap_periodic(ix - 1, width);
584 nix = wrap_periodic(ix + 1, width);
585 nnix = wrap_periodic(ix + 2, width);
587 iy = wrap_periodic(iy, height);
588 niy = wrap_periodic(iy + 1, height);
589 piy = wrap_periodic(iy - 1, height);
590 nniy = wrap_periodic(iy + 2, height);
592 iz = wrap_periodic(iz, depth);
593 piz = wrap_periodic(iz - 1, depth);
594 niz = wrap_periodic(iz + 1, depth);
595 nniz = wrap_periodic(iz + 2, depth);
599 if (ix < -2 || ix > width || iy < -2 || iy > height || iz < -2 || iz > depth) {
616 if (pix >= 0 && nnix < width && piy >= 0 && nniy < height && piz >= 0 && nniz < depth) {
622 const int xc[4] = {pix, ix, nix, nnix};
623 const int yc[4] = {piy, iy, niy, nniy};
624 const int zc[4] = {piz, iz, niz, nniz};
625 return tricubic_lookup(
626 (
const TexT *)info.
data, tx, ty, tz, xc, yc, zc, width, height, depth, read_clip);
629 pix = wrap_clamp(ix - 1, width);
630 nix = wrap_clamp(ix + 1, width);
631 nnix = wrap_clamp(ix + 2, width);
632 ix = wrap_clamp(ix, width);
634 piy = wrap_clamp(iy - 1, height);
635 niy = wrap_clamp(iy + 1, height);
636 nniy = wrap_clamp(iy + 2, height);
637 iy = wrap_clamp(iy, height);
639 piz = wrap_clamp(iz - 1, depth);
640 niz = wrap_clamp(iz + 1, depth);
641 nniz = wrap_clamp(iz + 2, depth);
642 iz = wrap_clamp(iz, depth);
645 pix = wrap_mirror(ix - 1, width);
646 nix = wrap_mirror(ix + 1, width);
647 nnix = wrap_mirror(ix + 2, width);
648 ix = wrap_mirror(ix, width);
650 piy = wrap_mirror(iy - 1, height);
651 niy = wrap_mirror(iy + 1, height);
652 nniy = wrap_mirror(iy + 2, height);
653 iy = wrap_mirror(iy, height);
655 piz = wrap_mirror(iz - 1, depth);
656 niz = wrap_mirror(iz + 1, depth);
657 nniz = wrap_mirror(iz + 2, depth);
658 iz = wrap_mirror(iz, depth);
664 const int xc[4] = {pix, ix, nix, nnix};
665 const int yc[4] = {piy, iy, niy, nniy};
666 const int zc[4] = {piz, iz, niz, nniz};
667 const TexT *data = (
const TexT *)info.
data;
668 return tricubic_lookup(data, tx, ty, tz, xc, yc, zc, width, height, depth, read);
676 return interp_3d_closest(info, x, y,
z);
678 return interp_3d_linear(info, x, y,
z);
680 return interp_3d_cubic(info, x, y,
z);
686template<
typename TexT,
typename OutT>
struct NanoVDBInterpolator {
698 template<
typename Acc>
699 static ccl_always_inline OutT interp_3d_closest(
const Acc &acc,
float x,
float y,
float z)
702 return read(acc.getValue(coord));
705 template<
typename Acc>
706 static ccl_always_inline OutT interp_3d_linear(
const Acc &acc,
float x,
float y,
float z)
709 const float tx =
frac(x - 0.5f, &ix);
710 const float ty =
frac(y - 0.5f, &iy);
711 const float tz =
frac(
z - 0.5f, &iz);
731 template<
typename Acc>
732# if defined(__GNUC__) || defined(__clang__)
738 interp_3d_cubic(
const Acc &acc,
float x,
float y,
float z)
743 int nnix, nniy, nniz;
746 const float tx =
frac(x - 0.5f, &ix);
747 const float ty =
frac(y - 0.5f, &iy);
748 const float tz =
frac(
z - 0.5f, &iz);
760 const int xc[4] = {pix, ix, nix, nnix};
761 const int yc[4] = {piy, iy, niy, nniy};
762 const int zc[4] = {piz, iz, niz, nniz};
763 float u[4],
v[4],
w[4];
768# define DATA(x, y, z) (read(acc.getValue(nanovdb::Coord(xc[x], yc[y], zc[z]))))
769# define COL_TERM(col, row) \
770 (v[col] * (u[0] * DATA(0, col, row) + u[1] * DATA(1, col, row) + u[2] * DATA(2, col, row) + \
771 u[3] * DATA(3, col, row)))
772# define ROW_TERM(row) \
773 (w[row] * (COL_TERM(0, row) + COL_TERM(1, row) + COL_TERM(2, row) + COL_TERM(3, row)))
797 return interp_3d_closest(acc, x, y,
z);
801 return interp_3d_linear(acc, x, y,
z);
805 return interp_3d_cubic(acc, x, y,
z);
812#undef SET_CUBIC_SPLINE_WEIGHTS
895 const float f = NanoVDBInterpolator<float, float>::interp_3d(info,
P.x,
P.y,
P.z,
interp);
899 return NanoVDBInterpolator<packed_float3, float4>::interp_3d(info,
P.x,
P.y,
P.z,
interp);
901 const float f = NanoVDBInterpolator<nanovdb::FpN, float>::interp_3d(
906 const float f = NanoVDBInterpolator<nanovdb::Fp16, float>::interp_3d(
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
#define SET_CUBIC_SPLINE_WEIGHTS(u, t)
CCL_NAMESPACE_BEGIN ccl_device_inline float frac(float x, ccl_private int *ix)
ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals kg, int id, float3 P, InterpolationType interp)
ccl_device float4 kernel_tex_image_interp(KernelGlobals kg, int id, float x, float y)
#define kernel_assert(cond)
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_device_inline
#define CCL_NAMESPACE_END
#define ccl_always_inline
draw_view in_light_buf[] float
ccl_device_inline float4 half4_to_float4_image(const half4 h)
ccl_device_inline float half_to_float_image(half h)
ccl_device_inline float2 interp(const float2 a, const float2 b, float t)
CCL_NAMESPACE_BEGIN ccl_device_inline float4 zero_float4()
VecBase< float, 4 > float4
static ccl_always_inline OutT interp_closest(const TextureInfo &info, float x, float y)
static ccl_always_inline float read(uchar r)
static ccl_always_inline OutT read(const TexT *data, int x, int y, int width, int height)
static ccl_always_inline OutT read(const TexT *data, int x, int y, int z, int width, int height, int depth)
static ccl_always_inline OutT interp(const TextureInfo &info, float x, float y)
static ccl_never_inline OutT interp_3d_cubic(const TextureInfo &info, float x, float y, float z)
static ccl_always_inline OutT interp_linear(const TextureInfo &info, float x, float y)
static ccl_always_inline float4 read(uchar4 r)
static ccl_always_inline float read(float r)
static ccl_always_inline int wrap_mirror(int x, int width)
static ccl_always_inline float4 read(float4 r)
static ccl_always_inline OutT zero()
static ccl_always_inline OutT read_clip(const TexT *data, int x, int y, int z, int width, int height, int depth)
static ccl_always_inline OutT read_clip(const TexT *data, int x, int y, int width, int height)
static ccl_always_inline OutT interp_3d_linear(const TextureInfo &info, float x, float y, float z)
static ccl_always_inline OutT interp_3d(const TextureInfo &info, float x, float y, float z, InterpolationType interp)
static ccl_always_inline OutT interp_3d_closest(const TextureInfo &info, float x, float y, float z)
static ccl_always_inline float4 read(ushort4 r)
static ccl_always_inline int wrap_periodic(int x, int width)
static ccl_always_inline float4 read(half4 r)
static ccl_always_inline OutT trilinear_lookup(const TexT *data, float tx, float ty, float tz, int ix, int iy, int iz, int nix, int niy, int niz, int width, int height, int depth, OutT read(const TexT *, int, int, int, int, int, int))
static ccl_always_inline OutT interp_cubic(const TextureInfo &info, float x, float y)
static ccl_always_inline OutT tricubic_lookup(const TexT *data, float tx, float ty, float tz, const int xc[4], const int yc[4], const int zc[4], int width, int height, int depth, OutT read(const TexT *, int, int, int, int, int, int))
static ccl_always_inline int wrap_clamp(int x, int width)
static ccl_always_inline float read(half r)
static ccl_always_inline float read(uint16_t r)
ccl_device_inline int abs(int x)
ccl_device_inline int float_to_int(float f)
ccl_device_inline int clamp(int a, int mn, int mx)
@ IMAGE_DATA_TYPE_NANOVDB_FP16
@ IMAGE_DATA_TYPE_USHORT4
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT3
@ IMAGE_DATA_TYPE_NANOVDB_FPN
#define TEX_IMAGE_MISSING_R
#define TEX_IMAGE_MISSING_B
#define TEX_IMAGE_MISSING_A
#define TEX_IMAGE_MISSING_G