Initial commit.
This commit is contained in:
commit
d3bb49b3f5
1073 changed files with 484757 additions and 0 deletions
19
Framework/external/embree/tutorials/common/texture/CMakeLists.txt
vendored
Normal file
19
Framework/external/embree/tutorials/common/texture/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
## Copyright 2009-2021 Intel Corporation
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ADD_LIBRARY(texture STATIC
|
||||
texture2d.cpp
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(texture sys math)
|
||||
SET_PROPERTY(TARGET texture PROPERTY FOLDER tutorials/common)
|
||||
SET_PROPERTY(TARGET texture APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
|
||||
|
||||
IF (EMBREE_ISPC_SUPPORT)
|
||||
ADD_ISPC_LIBRARY(texture_ispc STATIC
|
||||
texture2d.ispc
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(texture_ispc sys math)
|
||||
SET_TARGET_PROPERTIES(texture_ispc PROPERTIES LINKER_LANGUAGE CXX)
|
||||
SET_PROPERTY(TARGET texture_ispc PROPERTY FOLDER tutorials/common)
|
||||
SET_PROPERTY(TARGET texture_ispc APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
|
||||
ENDIF()
|
||||
91
Framework/external/embree/tutorials/common/texture/texture.cpp
vendored
Normal file
91
Framework/external/embree/tutorials/common/texture/texture.cpp
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
bool isPowerOf2 (unsigned int x)
|
||||
{
|
||||
while (((x % 2) == 0) && x > 1)
|
||||
x /= 2;
|
||||
return (x == 1);
|
||||
}
|
||||
|
||||
static std::map<std::string,std::shared_ptr<Texture>> texture_cache;
|
||||
|
||||
void Texture::clearTextureCache() {
|
||||
texture_cache.clear();
|
||||
}
|
||||
|
||||
Texture::Texture ()
|
||||
: width(-1), height(-1), format(INVALID), bytesPerTexel(0), width_mask(0), height_mask(0), data(nullptr) {}
|
||||
|
||||
Texture::Texture(Ref<Image> img, const std::string fileName)
|
||||
: width(unsigned(img->width)), height(unsigned(img->height)), format(RGBA8), bytesPerTexel(4), width_mask(0), height_mask(0), data(nullptr), fileName(fileName)
|
||||
{
|
||||
width_mask = isPowerOf2(width) ? width-1 : 0;
|
||||
height_mask = isPowerOf2(height) ? height-1 : 0;
|
||||
|
||||
data = alignedUSMMalloc(4*width*height,16);
|
||||
img->convertToRGBA8((unsigned char*)data);
|
||||
}
|
||||
|
||||
Texture::Texture (unsigned width, unsigned height, const Format format, const char* in)
|
||||
: width(width), height(height), format(format), bytesPerTexel(getFormatBytesPerTexel(format)), width_mask(0), height_mask(0), data(nullptr)
|
||||
{
|
||||
width_mask = isPowerOf2(width) ? width-1 : 0;
|
||||
height_mask = isPowerOf2(height) ? height-1 : 0;
|
||||
|
||||
data = alignedUSMMalloc(bytesPerTexel*width*height,16);
|
||||
if (in) {
|
||||
for (size_t i=0; i<bytesPerTexel*width*height; i++)
|
||||
((char*)data)[i] = in[i];
|
||||
}
|
||||
else {
|
||||
memset(data,0 ,bytesPerTexel*width*height);
|
||||
}
|
||||
}
|
||||
|
||||
Texture::~Texture () {
|
||||
alignedUSMFree(data);
|
||||
}
|
||||
|
||||
const char* Texture::format_to_string(const Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case RGBA8 : return "RGBA8";
|
||||
case RGB8 : return "RGB8";
|
||||
case FLOAT32: return "FLOAT32";
|
||||
default : THROW_RUNTIME_ERROR("invalid texture format");
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Format Texture::string_to_format(const std::string& str)
|
||||
{
|
||||
if (str == "RGBA8") return RGBA8;
|
||||
else if (str == "RGB8") return RGB8;
|
||||
else if (str == "FLOAT32") return FLOAT32;
|
||||
else THROW_RUNTIME_ERROR("invalid texture format string");
|
||||
}
|
||||
|
||||
unsigned Texture::getFormatBytesPerTexel(const Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case RGBA8 : return 4;
|
||||
case RGB8 : return 3;
|
||||
case FLOAT32: return 4;
|
||||
default : THROW_RUNTIME_ERROR("invalid texture format");
|
||||
}
|
||||
}
|
||||
|
||||
/*! read png texture from disk */
|
||||
std::shared_ptr<Texture> Texture::load(const FileName& fileName)
|
||||
{
|
||||
if (texture_cache.find(fileName.str()) != texture_cache.end())
|
||||
return texture_cache[fileName.str()];
|
||||
|
||||
std::shared_ptr<Texture> tex(new Texture(loadImage(fileName),fileName));
|
||||
return texture_cache[fileName.str()] = tex;
|
||||
}
|
||||
}
|
||||
31
Framework/external/embree/tutorials/common/texture/texture.h
vendored
Normal file
31
Framework/external/embree/tutorials/common/texture/texture.h
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*! This header is shared with ISPC. */
|
||||
#pragma once
|
||||
|
||||
/*! Embree format constants for Texture creation */
|
||||
typedef enum {
|
||||
TEXTURE_RGBA8,
|
||||
TEXTURE_SRGBA,
|
||||
TEXTURE_RGBA32F,
|
||||
TEXTURE_RGB8,
|
||||
TEXTURE_SRGB,
|
||||
TEXTURE_RGB32F,
|
||||
TEXTURE_R8,
|
||||
TEXTURE_R32F,
|
||||
/* TODO
|
||||
LogLuv,
|
||||
RGBA16F
|
||||
RGB16F
|
||||
RGBE, // radiance hdr
|
||||
compressed (RGTC, BPTC, ETC, ...)
|
||||
*/
|
||||
} TextureFormat;
|
||||
|
||||
/*! flags that can be passed to ospNewTexture2D(); can be OR'ed together */
|
||||
typedef enum {
|
||||
TEXTURE_SHARED_BUFFER = (1<<0),
|
||||
TEXTURE_FILTER_NEAREST = (1<<1) /*!< use nearest-neighbor interpolation rather than the default bilinear interpolation */
|
||||
} TextureCreationFlags;
|
||||
|
||||
203
Framework/external/embree/tutorials/common/texture/texture2d.cpp
vendored
Normal file
203
Framework/external/embree/tutorials/common/texture/texture2d.cpp
vendored
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "texture2d.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
|
||||
// Low-level texel accessors
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO blocking
|
||||
|
||||
inline Vec4f getTexel_RGBA8(const Texture2D *self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
const uint32_t c = ((const uint32_t *)self->data)[i.y*self->size.x + i.x];
|
||||
const uint32_t r = c & 0xff;
|
||||
const uint32_t g = (c >> 8) & 0xff;
|
||||
const uint32_t b = (c >> 16) & 0xff;
|
||||
const uint32_t a = c >> 24;
|
||||
return Vec4f((float)r, (float)g, (float)b, (float)a)*(1.f/255.f);
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_RGB8(const Texture2D *self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
const uint8_t *texel = (const uint8_t *)self->data;
|
||||
const uint32_t texelOfs = 3*(i.y*self->size.x + i.x);
|
||||
const uint32_t r = texel[texelOfs];
|
||||
const uint32_t g = texel[texelOfs+1];
|
||||
const uint32_t b = texel[texelOfs+2];
|
||||
return Vec4f(Vec3fa((float)r, (float)g, (float)b)*(1.f/255.f), 1.f);
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_R8(const Texture2D *self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
const uint8_t c = ((const uint8_t *)self->data)[i.y*self->size.x + i.x];
|
||||
return Vec4f(c*(1.f/255.f), 0.0f, 0.0f, 1.f);
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_SRGBA(const Texture2D *self, const Vec2i i)
|
||||
{
|
||||
return srgba_to_linear(getTexel_RGBA8(self, i));
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_SRGB(const Texture2D *self, const Vec2i i)
|
||||
{
|
||||
return srgba_to_linear(getTexel_RGB8(self, i));
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_RGBA32F(const Texture2D *self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
return ((const Vec4f *)self->data)[i.y*self->size.x + i.x];
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_RGB32F(const Texture2D *self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
Vec3fa v = ((const Vec3fa*)self->data)[i.y*self->size.x + i.x];
|
||||
return Vec4f(v, 1.f);
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_R32F(const Texture2D *self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
float v = ((const float*)self->data)[i.y*self->size.x + i.x];
|
||||
return Vec4f(v, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
|
||||
// Texture coordinate utilities
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec2i nearest_coords(const Texture2D *self, const Vec2f p)
|
||||
{
|
||||
// repeat: get remainder within [0..1] parameter space
|
||||
Vec2f tc = frac(p);
|
||||
tc = max(tc, Vec2f(0.0f)); // filter out inf/NaN
|
||||
|
||||
// scale by texture size
|
||||
tc = tc * self->sizef;
|
||||
|
||||
// nearest
|
||||
return Vec2i(tc);
|
||||
}
|
||||
|
||||
struct BilinCoords {
|
||||
Vec2i st0;
|
||||
Vec2i st1;
|
||||
Vec2f frac;
|
||||
};
|
||||
|
||||
inline BilinCoords bilinear_coords(const Texture2D *self, const Vec2f p)
|
||||
{
|
||||
BilinCoords coords;
|
||||
|
||||
// repeat: get remainder within [0..1] parameter space
|
||||
// lower sample shifted by half a texel
|
||||
Vec2f tc = frac(p - self->halfTexel);
|
||||
tc = max(tc, Vec2f(0.0f)); // filter out inf/NaN
|
||||
|
||||
// scale by texture size
|
||||
tc = tc * self->sizef;
|
||||
coords.frac = frac(tc);
|
||||
|
||||
coords.st0 = Vec2i(tc);
|
||||
coords.st1 = coords.st0 + 1;
|
||||
// handle border cases
|
||||
if (coords.st1.x >= self->size.x)
|
||||
coords.st1.x = 0;
|
||||
if (coords.st1.y >= self->size.y)
|
||||
coords.st1.y = 0;
|
||||
|
||||
return coords;
|
||||
}
|
||||
|
||||
inline Vec4f bilerp(const Vec2f frac, const Vec4f c00, const Vec4f c01, const Vec4f c10, const Vec4f c11)
|
||||
{
|
||||
return lerpr(frac.y,
|
||||
lerpr(frac.x, c00, c01),
|
||||
lerpr(frac.x, c10, c11));
|
||||
}
|
||||
|
||||
|
||||
// Implementations of Texture2D_get for different formats and filter modi
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define __define_tex_get(FMT) \
|
||||
\
|
||||
static Vec4f Texture2D_nearest_##FMT(const Texture2D *self, \
|
||||
const Vec2f &p) \
|
||||
{ \
|
||||
return getTexel_##FMT(self, nearest_coords(self, p)); \
|
||||
} \
|
||||
\
|
||||
static Vec4f Texture2D_bilinear_##FMT(const Texture2D *self, \
|
||||
const Vec2f &p) \
|
||||
{ \
|
||||
BilinCoords cs = bilinear_coords(self, p); \
|
||||
\
|
||||
const Vec4f c00 = getTexel_##FMT(self, Vec2i(cs.st0.x, cs.st0.y)); \
|
||||
const Vec4f c01 = getTexel_##FMT(self, Vec2i(cs.st1.x, cs.st0.y)); \
|
||||
const Vec4f c10 = getTexel_##FMT(self, Vec2i(cs.st0.x, cs.st1.y)); \
|
||||
const Vec4f c11 = getTexel_##FMT(self, Vec2i(cs.st1.x, cs.st1.y)); \
|
||||
\
|
||||
return bilerp(cs.frac, c00, c01, c10, c11); \
|
||||
}
|
||||
|
||||
#define __define_tex_get_case(FMT) \
|
||||
case TEXTURE_##FMT: return filter_nearest ? &Texture2D_nearest_##FMT : \
|
||||
&Texture2D_bilinear_##FMT;
|
||||
|
||||
#define __foreach_fetcher(FCT) \
|
||||
FCT(RGBA8) \
|
||||
FCT(SRGBA) \
|
||||
FCT(RGBA32F) \
|
||||
FCT(RGB8) \
|
||||
FCT(SRGB) \
|
||||
FCT(RGB32F) \
|
||||
FCT(R8) \
|
||||
FCT(R32F)
|
||||
|
||||
__foreach_fetcher(__define_tex_get)
|
||||
|
||||
static Texture2D_get Texture2D_get_addr(const uint32_t type,
|
||||
const bool filter_nearest)
|
||||
{
|
||||
switch (type) {
|
||||
__foreach_fetcher(__define_tex_get_case)
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
#undef __define_tex_get
|
||||
#undef __define_tex_get_addr
|
||||
#undef __foreach_fetcher
|
||||
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" void *Texture2D_create(Vec2i &size, void *data,
|
||||
uint32_t type, uint32_t flags)
|
||||
{
|
||||
Texture2D *self = (Texture2D*) alignedUSMMalloc(sizeof(Texture2D),16);
|
||||
self->size = size;
|
||||
|
||||
// Due to float rounding frac(x) can be exactly 1.0f (e.g. for very small
|
||||
// negative x), although it should be strictly smaller than 1.0f. We handle
|
||||
// this case by having sizef slightly smaller than size, such that
|
||||
// frac(x)*sizef is always < size.
|
||||
self->sizef = Vec2f(nextafter((float)size.x, -1.0f), nextafter((float)size.y, -1.0f));
|
||||
self->halfTexel = Vec2f(0.5f/size.x, 0.5f/size.y);
|
||||
self->data = data;
|
||||
self->get = Texture2D_get_addr(type, flags & TEXTURE_FILTER_NEAREST);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
} // namespace embree
|
||||
104
Framework/external/embree/tutorials/common/texture/texture2d.h
vendored
Normal file
104
Framework/external/embree/tutorials/common/texture/texture2d.h
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "texture.h"
|
||||
#include "../math/vec.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
struct Texture2D;
|
||||
|
||||
typedef Vec4f (*Texture2D_get)(const Texture2D *self,
|
||||
const Vec2f &p);
|
||||
|
||||
struct Texture2D {
|
||||
Vec2i size;
|
||||
Vec2f sizef; // size, as floats; slightly smaller than 'size' to avoid range checks
|
||||
Vec2f halfTexel; // 0.5/size, needed for bilinear filtering and clamp-to-edge
|
||||
Texture2D_get get;
|
||||
void *data;
|
||||
};
|
||||
|
||||
// XXX won't work with MIPmapping: clean implementation with clamping on integer coords needed then
|
||||
inline Vec2f clamp2edge(const Texture2D *self, const Vec2f p)
|
||||
{
|
||||
return clamp(p, self->halfTexel, 1.0f - self->halfTexel);
|
||||
}
|
||||
|
||||
/*! helper function that returns the sampled value for the first
|
||||
channel of the given texture
|
||||
|
||||
Right now, this function always asks the texture for all four
|
||||
channels, and then discards all but one; later implementations may
|
||||
have specialized 'get1f' methods with the texture
|
||||
|
||||
\note self may NOT be nullptr!
|
||||
*/
|
||||
inline float get1f(const Texture2D *self,
|
||||
const Vec2f where)
|
||||
{
|
||||
Vec4f ret = self->get(self, where);
|
||||
return ret.x;
|
||||
}
|
||||
|
||||
/*! helper function that returns the sampled value for the first three
|
||||
channels of the given texture
|
||||
|
||||
Right now, this function always asks the texture for all four
|
||||
channels, and then discards all but one; later implementations may
|
||||
have specialized 'get3f' methods with the texture
|
||||
|
||||
\note self may NOT be nullptr!
|
||||
*/
|
||||
inline Vec3fa get3f(const Texture2D *self,
|
||||
const Vec2f where)
|
||||
{
|
||||
Vec4f ret = self->get(self, where);
|
||||
return Vec3fa(ret);
|
||||
}
|
||||
|
||||
/*! helper function that returns the sampled value of the four
|
||||
channels of the given texture.
|
||||
|
||||
Note that it's up to the texture to define clearly what happens if
|
||||
we ask for four channels even if the texture has less physical
|
||||
channels.
|
||||
|
||||
\note self may NOT be nullptr!
|
||||
*/
|
||||
inline Vec4f get4f(const Texture2D *self,
|
||||
const Vec2f where)
|
||||
{
|
||||
return self->get(self, where);
|
||||
}
|
||||
|
||||
/*! helper function: get1f() with a default value if the texture is nullptr */
|
||||
inline float get1f(const Texture2D *self,
|
||||
const Vec2f where,
|
||||
const float defaultValue)
|
||||
{
|
||||
if (self == nullptr) return defaultValue;
|
||||
else return get1f(self,where);
|
||||
}
|
||||
|
||||
/*! helper function: get3f() with a default value if the texture is nullptr */
|
||||
inline Vec3fa get3f(const Texture2D *self,
|
||||
const Vec2f where,
|
||||
const Vec3fa& defaultValue)
|
||||
{
|
||||
if (self == nullptr) return defaultValue;
|
||||
else return get3f(self,where);
|
||||
}
|
||||
|
||||
/*! helper function: get4f() with a default value if the texture is nullptr */
|
||||
inline Vec4f get4f(const Texture2D *self,
|
||||
const Vec2f where,
|
||||
const Vec4f defaultValue)
|
||||
{
|
||||
if (self == nullptr) return defaultValue;
|
||||
else return get4f(self,where);
|
||||
}
|
||||
|
||||
} // namespace embree
|
||||
199
Framework/external/embree/tutorials/common/texture/texture2d.ispc
vendored
Normal file
199
Framework/external/embree/tutorials/common/texture/texture2d.ispc
vendored
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "texture2d.isph"
|
||||
|
||||
|
||||
// Low-level texel accessors
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO blocking
|
||||
|
||||
inline Vec4f getTexel_RGBA8(const uniform Texture2D *uniform self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
const uint32 c = ((const uniform uint32 *uniform)self->data)[i.y*self->size.x + i.x];
|
||||
const uint32 r = c & 0xff;
|
||||
const uint32 g = (c >> 8) & 0xff;
|
||||
const uint32 b = (c >> 16) & 0xff;
|
||||
const uint32 a = c >> 24;
|
||||
return make_Vec4f((float)r, (float)g, (float)b, (float)a)*(1.f/255.f);
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_RGB8(const uniform Texture2D *uniform self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
const uniform uint8 *uniform texel = (const uniform uint8 *uniform)self->data;
|
||||
const uint32 texelOfs = 3*(i.y*self->size.x + i.x);
|
||||
const uint32 r = texel[texelOfs];
|
||||
const uint32 g = texel[texelOfs+1];
|
||||
const uint32 b = texel[texelOfs+2];
|
||||
return make_Vec4f(make_Vec3f((float)r, (float)g, (float)b)*(1.f/255.f), 1.f);
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_R8(const uniform Texture2D *uniform self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
const uint8 c = ((const uniform uint8 *uniform)self->data)[i.y*self->size.x + i.x];
|
||||
return make_Vec4f(c*(1.f/255.f), 0.0f, 0.0f, 1.f);
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_SRGBA(const uniform Texture2D *uniform self, const Vec2i i)
|
||||
{
|
||||
return srgba_to_linear(getTexel_RGBA8(self, i));
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_SRGB(const uniform Texture2D *uniform self, const Vec2i i)
|
||||
{
|
||||
return srgba_to_linear(getTexel_RGB8(self, i));
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_RGBA32F(const uniform Texture2D *uniform self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
return ((const uniform Vec4f *uniform)self->data)[i.y*self->size.x + i.x];
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_RGB32F(const uniform Texture2D *uniform self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
Vec3f v = ((const uniform Vec3f*uniform )self->data)[i.y*self->size.x + i.x];
|
||||
return make_Vec4f(v, 1.f);
|
||||
}
|
||||
|
||||
inline Vec4f getTexel_R32F(const uniform Texture2D *uniform self, const Vec2i i)
|
||||
{
|
||||
assert(self);
|
||||
float v = ((const uniform float*uniform)self->data)[i.y*self->size.x + i.x];
|
||||
return make_Vec4f(v, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
|
||||
// Texture coordinate utilities
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec2i nearest_coords(const uniform Texture2D *uniform self, const Vec2f p)
|
||||
{
|
||||
// repeat: get remainder within [0..1] parameter space
|
||||
Vec2f tc = frac(p);
|
||||
tc = max(tc, make_Vec2f(0.0f)); // filter out inf/NaN
|
||||
|
||||
// scale by texture size
|
||||
tc = tc * self->sizef;
|
||||
|
||||
// nearest
|
||||
return make_Vec2i(tc);
|
||||
}
|
||||
|
||||
struct BilinCoords {
|
||||
Vec2i st0;
|
||||
Vec2i st1;
|
||||
Vec2f frac;
|
||||
};
|
||||
|
||||
inline BilinCoords bilinear_coords(const uniform Texture2D *uniform self, const Vec2f p)
|
||||
{
|
||||
BilinCoords coords;
|
||||
|
||||
// repeat: get remainder within [0..1] parameter space
|
||||
// lower sample shifted by half a texel
|
||||
Vec2f tc = frac(p - self->halfTexel);
|
||||
tc = max(tc, make_Vec2f(0.0f)); // filter out inf/NaN
|
||||
|
||||
// scale by texture size
|
||||
tc = tc * self->sizef;
|
||||
coords.frac = frac(tc);
|
||||
|
||||
coords.st0 = make_Vec2i(tc);
|
||||
coords.st1 = coords.st0 + 1;
|
||||
// handle border cases
|
||||
if (coords.st1.x >= self->size.x)
|
||||
coords.st1.x = 0;
|
||||
if (coords.st1.y >= self->size.y)
|
||||
coords.st1.y = 0;
|
||||
|
||||
return coords;
|
||||
}
|
||||
|
||||
inline Vec4f bilerp(const Vec2f frac, const Vec4f c00, const Vec4f c01, const Vec4f c10, const Vec4f c11)
|
||||
{
|
||||
return lerp(frac.y,
|
||||
lerp(frac.x, c00, c01),
|
||||
lerp(frac.x, c10, c11));
|
||||
}
|
||||
|
||||
|
||||
// Implementations of Texture2D_get for different formats and filter modi
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define __define_tex_get(FMT) \
|
||||
\
|
||||
static Vec4f Texture2D_nearest_##FMT(const uniform Texture2D *uniform self, \
|
||||
const Vec2f &p) \
|
||||
{ \
|
||||
return getTexel_##FMT(self, nearest_coords(self, p)); \
|
||||
} \
|
||||
\
|
||||
static Vec4f Texture2D_bilinear_##FMT(const uniform Texture2D *uniform self, \
|
||||
const Vec2f &p) \
|
||||
{ \
|
||||
BilinCoords cs = bilinear_coords(self, p); \
|
||||
\
|
||||
const Vec4f c00 = getTexel_##FMT(self, make_Vec2i(cs.st0.x, cs.st0.y)); \
|
||||
const Vec4f c01 = getTexel_##FMT(self, make_Vec2i(cs.st1.x, cs.st0.y)); \
|
||||
const Vec4f c10 = getTexel_##FMT(self, make_Vec2i(cs.st0.x, cs.st1.y)); \
|
||||
const Vec4f c11 = getTexel_##FMT(self, make_Vec2i(cs.st1.x, cs.st1.y)); \
|
||||
\
|
||||
return bilerp(cs.frac, c00, c01, c10, c11); \
|
||||
}
|
||||
|
||||
#define __define_tex_get_case(FMT) \
|
||||
case TEXTURE_##FMT: return filter_nearest ? &Texture2D_nearest_##FMT : \
|
||||
&Texture2D_bilinear_##FMT;
|
||||
|
||||
#define __foreach_fetcher(FCT) \
|
||||
FCT(RGBA8) \
|
||||
FCT(SRGBA) \
|
||||
FCT(RGBA32F) \
|
||||
FCT(RGB8) \
|
||||
FCT(SRGB) \
|
||||
FCT(RGB32F) \
|
||||
FCT(R8) \
|
||||
FCT(R32F)
|
||||
|
||||
__foreach_fetcher(__define_tex_get)
|
||||
|
||||
static uniform Texture2D_get Texture2D_get_addr(const uniform uint32 type,
|
||||
const uniform bool filter_nearest)
|
||||
{
|
||||
switch (type) {
|
||||
__foreach_fetcher(__define_tex_get_case)
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
#undef __define_tex_get
|
||||
#undef __define_tex_get_addr
|
||||
#undef __foreach_fetcher
|
||||
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
export void *uniform Texture2D_create(uniform Vec2i &size, void *uniform data,
|
||||
uniform uint32 type, uniform uint32 flags)
|
||||
{
|
||||
uniform Texture2D *uniform self = uniform new uniform Texture2D;
|
||||
self->size = size;
|
||||
|
||||
// Due to float rounding frac(x) can be exactly 1.0f (e.g. for very small
|
||||
// negative x), although it should be strictly smaller than 1.0f. We handle
|
||||
// this case by having sizef slightly smaller than size, such that
|
||||
// frac(x)*sizef is always < size.
|
||||
self->sizef = make_Vec2f(nextafter((float)size.x, -1.0f), nextafter((float)size.y, -1.0f));
|
||||
self->halfTexel = make_Vec2f(0.5f/size.x, 0.5f/size.y);
|
||||
self->data = data;
|
||||
self->get = Texture2D_get_addr(type, flags & TEXTURE_FILTER_NEAREST);
|
||||
|
||||
return self;
|
||||
}
|
||||
100
Framework/external/embree/tutorials/common/texture/texture2d.isph
vendored
Normal file
100
Framework/external/embree/tutorials/common/texture/texture2d.isph
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "texture.h"
|
||||
#include "../math/vec.isph"
|
||||
|
||||
struct Texture2D;
|
||||
|
||||
typedef varying Vec4f (*Texture2D_get)(const uniform Texture2D *uniform self,
|
||||
const varying Vec2f &p);
|
||||
|
||||
struct Texture2D {
|
||||
Vec2i size;
|
||||
Vec2f sizef; // size, as floats; slightly smaller than 'size' to avoid range checks
|
||||
Vec2f halfTexel; // 0.5/size, needed for bilinear filtering and clamp-to-edge
|
||||
Texture2D_get get;
|
||||
void *data;
|
||||
};
|
||||
|
||||
// XXX won't work with MIPmapping: clean implementation with clamping on integer coords needed then
|
||||
inline Vec2f clamp2edge(const uniform Texture2D *uniform self, const Vec2f p)
|
||||
{
|
||||
return clamp(p, self->halfTexel, 1.0f - self->halfTexel);
|
||||
}
|
||||
|
||||
/*! helper function that returns the sampled value for the first
|
||||
channel of the given texture
|
||||
|
||||
Right now, this function always asks the texture for all four
|
||||
channels, and then discards all but one; later implementations may
|
||||
have specialized 'get1f' methods with the texture
|
||||
|
||||
\note self may NOT be NULL!
|
||||
*/
|
||||
inline float get1f(const uniform Texture2D *uniform self,
|
||||
const varying Vec2f where)
|
||||
{
|
||||
Vec4f ret = self->get(self, where);
|
||||
return ret.x;
|
||||
}
|
||||
|
||||
/*! helper function that returns the sampled value for the first three
|
||||
channels of the given texture
|
||||
|
||||
Right now, this function always asks the texture for all four
|
||||
channels, and then discards all but one; later implementations may
|
||||
have specialized 'get3f' methods with the texture
|
||||
|
||||
\note self may NOT be NULL!
|
||||
*/
|
||||
inline Vec3f get3f(const uniform Texture2D *uniform self,
|
||||
const varying Vec2f where)
|
||||
{
|
||||
Vec4f ret = self->get(self, where);
|
||||
return make_Vec3f(ret);
|
||||
}
|
||||
|
||||
/*! helper function that returns the sampled value of the four
|
||||
channels of the given texture.
|
||||
|
||||
Note that it's up to the texture to define clearly what happens if
|
||||
we ask for four channels even if the texture has less physical
|
||||
channels.
|
||||
|
||||
\note self may NOT be NULL!
|
||||
*/
|
||||
inline Vec4f get4f(const uniform Texture2D *uniform self,
|
||||
const varying Vec2f where)
|
||||
{
|
||||
return self->get(self, where);
|
||||
}
|
||||
|
||||
/*! helper function: get1f() with a default value if the texture is NULL */
|
||||
inline float get1f(const uniform Texture2D *uniform self,
|
||||
const varying Vec2f where,
|
||||
const varying float defaultValue)
|
||||
{
|
||||
if (self == NULL) return defaultValue;
|
||||
else return get1f(self,where);
|
||||
}
|
||||
|
||||
/*! helper function: get3f() with a default value if the texture is NULL */
|
||||
inline Vec3f get3f(const uniform Texture2D *uniform self,
|
||||
const varying Vec2f where,
|
||||
const varying Vec3f defaultValue)
|
||||
{
|
||||
if (self == NULL) return defaultValue;
|
||||
else return get3f(self,where);
|
||||
}
|
||||
|
||||
/*! helper function: get4f() with a default value if the texture is NULL */
|
||||
inline Vec4f get4f(const uniform Texture2D *uniform self,
|
||||
const varying Vec2f where,
|
||||
const varying Vec4f defaultValue)
|
||||
{
|
||||
if (self == NULL) return defaultValue;
|
||||
else return get4f(self,where);
|
||||
}
|
||||
79
Framework/external/embree/tutorials/common/texture/texture_param.h
vendored
Normal file
79
Framework/external/embree/tutorials/common/texture/texture_param.h
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "texture2d.h"
|
||||
#include "ospray/math/AffineSpace.ih"
|
||||
|
||||
namespace embree {
|
||||
|
||||
|
||||
//! Texture2D including coordinate transformation, plus helpers
|
||||
|
||||
struct TextureParam
|
||||
{
|
||||
Texture2D* map;
|
||||
affine2f xform;
|
||||
};
|
||||
|
||||
inline TextureParam make_TextureParam(Texture2D * tex, const affine2f &xform)
|
||||
{
|
||||
TextureParam t;
|
||||
t.map = tex;
|
||||
t.xform = xform;
|
||||
return t;
|
||||
}
|
||||
|
||||
inline bool valid(const TextureParam &tex)
|
||||
{
|
||||
return tex.map;
|
||||
}
|
||||
|
||||
inline float get1f(const TextureParam &tex,
|
||||
const Vec2f uv)
|
||||
{
|
||||
return get1f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
inline float get1f(const TextureParam &tex,
|
||||
const Vec2f uv,
|
||||
const float defaultValue)
|
||||
{
|
||||
if (tex.map == nullptr)
|
||||
return defaultValue;
|
||||
return get1f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
inline Vec3fa get3f(const TextureParam &tex,
|
||||
const Vec2f uv)
|
||||
{
|
||||
return get3f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
inline Vec3fa get3f(const TextureParam &tex,
|
||||
const Vec2f uv,
|
||||
const Vec3fa& defaultValue)
|
||||
{
|
||||
if (tex.map == nullptr)
|
||||
return defaultValue;
|
||||
return get3f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
inline Vec4f get4f(const TextureParam &tex,
|
||||
const Vec2f uv)
|
||||
{
|
||||
return get4f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
inline Vec4f get4f(const TextureParam &tex,
|
||||
const Vec2f uv,
|
||||
const Vec4f defaultValue)
|
||||
{
|
||||
if (tex.map == nullptr)
|
||||
return defaultValue;
|
||||
return get4f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
|
||||
} // namespace embree
|
||||
75
Framework/external/embree/tutorials/common/texture/texture_param.isph
vendored
Normal file
75
Framework/external/embree/tutorials/common/texture/texture_param.isph
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "texture2d.isph"
|
||||
#include "ospray/math/AffineSpace.ih"
|
||||
|
||||
|
||||
//! Texture2D including coordinate transformation, plus helpers
|
||||
|
||||
struct TextureParam
|
||||
{
|
||||
uniform Texture2D* map;
|
||||
affine2f xform;
|
||||
};
|
||||
|
||||
inline uniform TextureParam make_TextureParam(uniform Texture2D * uniform tex, const uniform affine2f &xform)
|
||||
{
|
||||
uniform TextureParam t;
|
||||
t.map = tex;
|
||||
t.xform = xform;
|
||||
return t;
|
||||
}
|
||||
|
||||
inline bool valid(const uniform TextureParam uniform &tex)
|
||||
{
|
||||
return tex.map;
|
||||
}
|
||||
|
||||
inline float get1f(const uniform TextureParam uniform &tex,
|
||||
const varying Vec2f uv)
|
||||
{
|
||||
return get1f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
inline float get1f(const uniform TextureParam uniform &tex,
|
||||
const varying Vec2f uv,
|
||||
const varying float defaultValue)
|
||||
{
|
||||
if (tex.map == NULL)
|
||||
return defaultValue;
|
||||
return get1f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
inline Vec3f get3f(const uniform TextureParam uniform &tex,
|
||||
const varying Vec2f uv)
|
||||
{
|
||||
return get3f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
inline Vec3f get3f(const uniform TextureParam uniform &tex,
|
||||
const varying Vec2f uv,
|
||||
const varying Vec3f defaultValue)
|
||||
{
|
||||
if (tex.map == NULL)
|
||||
return defaultValue;
|
||||
return get3f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
inline Vec4f get4f(const uniform TextureParam uniform &tex,
|
||||
const varying Vec2f uv)
|
||||
{
|
||||
return get4f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
inline Vec4f get4f(const uniform TextureParam uniform &tex,
|
||||
const varying Vec2f uv,
|
||||
const varying Vec4f defaultValue)
|
||||
{
|
||||
if (tex.map == NULL)
|
||||
return defaultValue;
|
||||
return get4f(tex.map, tex.xform * uv);
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue