Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helide: add support for fixed point geometry attributes #83

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions libs/helide/frame/Frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ static uint32_t cvt_uint32(const float4 &v)

static uint32_t cvt_uint32_srgb(const float4 &v)
{
return cvt_uint32(float4(std::pow(v.x, 1.f / 2.2f),
std::pow(v.y, 1.f / 2.2f),
std::pow(v.z, 1.f / 2.2f),
v.w));
return cvt_uint32(float4(toneMap(v.x), toneMap(v.y), toneMap(v.z), v.w));
}

template <typename I, typename FUNC>
Expand Down
15 changes: 15 additions & 0 deletions libs/helide/helide_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,21 @@ inline mat3 extractRotation(const mat4 &m)
float3(m[2].x, m[2].y, m[2].z));
}

template <bool SRGB = true>
inline float toneMap(float v)
{
if constexpr (SRGB)
return std::pow(v, 1.f / 2.2f);
else
return v;
}

template <typename T, typename U>
inline T lerp(const T &x, const T &y, const U &a)
{
return static_cast<T>(x * (U(1) - a) + y * a);
}

} // namespace helide

namespace anari {
Expand Down
86 changes: 83 additions & 3 deletions libs/helide/scene/surface/geometry/Geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,41 @@

namespace helide {

// Helper functions ///////////////////////////////////////////////////////////

template <typename T>
static const T *typedOffset(const void *mem, uint32_t offset)
{
return ((const T *)mem) + offset;
}

template <typename ELEMENT_T, int NUM_COMPONENTS, bool SRGB = false>
static float4 getAttributeArrayAt_ufixed(void *data, uint32_t offset)
{
constexpr float m = std::numeric_limits<ELEMENT_T>::max();
float4 retval(0.f, 0.f, 0.f, 1.f);
switch (NUM_COMPONENTS) {
case 4:
retval.w = toneMap<SRGB>(
*typedOffset<ELEMENT_T>(data, NUM_COMPONENTS * offset + 3) / m);
case 3:
retval.z = toneMap<SRGB>(
*typedOffset<ELEMENT_T>(data, NUM_COMPONENTS * offset + 2) / m);
case 2:
retval.y = toneMap<SRGB>(
*typedOffset<ELEMENT_T>(data, NUM_COMPONENTS * offset + 1) / m);
case 1:
retval.x = toneMap<SRGB>(
*typedOffset<ELEMENT_T>(data, NUM_COMPONENTS * offset + 0) / m);
default:
break;
}

return retval;
}

// Geometry definitions ///////////////////////////////////////////////////////

Geometry::Geometry(HelideGlobalState *s) : Object(ANARI_GEOMETRY, s)
{
s->objectCounts.geometries++;
Expand Down Expand Up @@ -96,9 +131,54 @@ float4 Geometry::readAttributeArrayAt(Array1D *arr, uint32_t i) const
case ANARI_FLOAT32_VEC4:
std::memcpy(&retval, arr->beginAs<float4>() + i, sizeof(float4));
break;
/////////////////////////////////////////////////////////////////////////////
// TODO: add cases for other color types (fixed8/16/32, SRGB)
/////////////////////////////////////////////////////////////////////////////
case ANARI_UFIXED8_R_SRGB:
retval = getAttributeArrayAt_ufixed<uint8_t, 1, true>(arr->begin(), i);
break;
case ANARI_UFIXED8_RA_SRGB:
retval = getAttributeArrayAt_ufixed<uint8_t, 2, true>(arr->begin(), i);
break;
case ANARI_UFIXED8_RGB_SRGB:
retval = getAttributeArrayAt_ufixed<uint8_t, 3, true>(arr->begin(), i);
break;
case ANARI_UFIXED8_RGBA_SRGB:
retval = getAttributeArrayAt_ufixed<uint8_t, 4, true>(arr->begin(), i);
break;
case ANARI_UFIXED8:
retval = getAttributeArrayAt_ufixed<uint8_t, 1>(arr->begin(), i);
break;
case ANARI_UFIXED8_VEC2:
retval = getAttributeArrayAt_ufixed<uint8_t, 2>(arr->begin(), i);
break;
case ANARI_UFIXED8_VEC3:
retval = getAttributeArrayAt_ufixed<uint8_t, 3>(arr->begin(), i);
break;
case ANARI_UFIXED8_VEC4:
retval = getAttributeArrayAt_ufixed<uint8_t, 4>(arr->begin(), i);
break;
case ANARI_UFIXED16:
retval = getAttributeArrayAt_ufixed<uint16_t, 1>(arr->begin(), i);
break;
case ANARI_UFIXED16_VEC2:
retval = getAttributeArrayAt_ufixed<uint16_t, 2>(arr->begin(), i);
break;
case ANARI_UFIXED16_VEC3:
retval = getAttributeArrayAt_ufixed<uint16_t, 3>(arr->begin(), i);
break;
case ANARI_UFIXED16_VEC4:
retval = getAttributeArrayAt_ufixed<uint16_t, 4>(arr->begin(), i);
break;
case ANARI_UFIXED32:
retval = getAttributeArrayAt_ufixed<uint32_t, 1>(arr->begin(), i);
break;
case ANARI_UFIXED32_VEC2:
retval = getAttributeArrayAt_ufixed<uint32_t, 2>(arr->begin(), i);
break;
case ANARI_UFIXED32_VEC3:
retval = getAttributeArrayAt_ufixed<uint32_t, 3>(arr->begin(), i);
break;
case ANARI_UFIXED32_VEC4:
retval = getAttributeArrayAt_ufixed<uint32_t, 4>(arr->begin(), i);
break;
default:
break;
}
Expand Down
37 changes: 35 additions & 2 deletions libs/helide/scene/surface/geometry/Quad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ namespace helide {

Quad::Quad(HelideGlobalState *s) : Geometry(s)
{
m_embreeGeometry =
rtcNewGeometry(s->embreeDevice, RTC_GEOMETRY_TYPE_QUAD);
m_embreeGeometry = rtcNewGeometry(s->embreeDevice, RTC_GEOMETRY_TYPE_QUAD);
}

void Quad::commit()
Expand All @@ -21,6 +20,11 @@ void Quad::commit()

m_index = getParamObject<Array1D>("primitive.index");
m_vertexPosition = getParamObject<Array1D>("vertex.position");
m_vertexAttributes[0] = getParamObject<Array1D>("vertex.attribute0");
m_vertexAttributes[1] = getParamObject<Array1D>("vertex.attribute1");
m_vertexAttributes[2] = getParamObject<Array1D>("vertex.attribute2");
m_vertexAttributes[3] = getParamObject<Array1D>("vertex.attribute3");
m_vertexAttributes[4] = getParamObject<Array1D>("vertex.color");

if (!m_vertexPosition) {
reportMessage(ANARI_SEVERITY_WARNING,
Expand Down Expand Up @@ -64,6 +68,35 @@ void Quad::commit()
rtcCommitGeometry(embreeGeometry());
}

float4 Quad::getAttributeValueAt(const Attribute &attr, const Ray &ray) const
{
if (attr == Attribute::NONE)
return DEFAULT_ATTRIBUTE_VALUE;

auto attrIdx = static_cast<int>(attr);
auto *attributeArray = m_vertexAttributes[attrIdx].ptr;
if (!attributeArray)
return Geometry::getAttributeValueAt(attr, ray);

const float3 uvw(1.0f - ray.u - ray.v, ray.u, ray.v);

auto idx = m_index
? *(m_index->dataAs<uint4>() + ray.primID)
: uint4(ray.primID + 0, ray.primID + 1, ray.primID + 2, ray.primID + 3);

float4 uv((1 - ray.v) * (1 - ray.u),
(1 - ray.v) * ray.u,
ray.v * ray.u,
ray.v * (1 - ray.u));

auto a = readAttributeArrayAt(attributeArray, idx.x);
auto b = readAttributeArrayAt(attributeArray, idx.y);
auto c = readAttributeArrayAt(attributeArray, idx.z);
auto d = readAttributeArrayAt(attributeArray, idx.w);

return uv.x * a + uv.y * b + uv.z * c + uv.w * d;
}

void Quad::cleanup()
{
if (m_index)
Expand Down
4 changes: 4 additions & 0 deletions libs/helide/scene/surface/geometry/Quad.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ struct Quad : public Geometry

void commit() override;

float4 getAttributeValueAt(
const Attribute &attr, const Ray &ray) const override;

private:
void cleanup();

helium::IntrusivePtr<Array1D> m_index;
helium::IntrusivePtr<Array1D> m_vertexPosition;
std::array<helium::IntrusivePtr<Array1D>, 5> m_vertexAttributes;
};

} // namespace helide
6 changes: 5 additions & 1 deletion libs/helide/scene/surface/geometry/Sphere.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ float4 Sphere::getAttributeValueAt(
return Geometry::getAttributeValueAt(attr, ray);

auto attrIdx = static_cast<int>(attr);
return readAttributeArrayAt(m_vertexAttributes[attrIdx].ptr, ray.primID);
auto *attributeArray = m_vertexAttributes[attrIdx].ptr;
if (!attributeArray)
return Geometry::getAttributeValueAt(attr, ray);

return readAttributeArrayAt(attributeArray, ray.primID);
}

void Sphere::cleanup()
Expand Down