Skip to content

Commit

Permalink
implement primitive.id array in helide, add option to random spheres …
Browse files Browse the repository at this point in the history
…scene
  • Loading branch information
jeffamstutz committed Nov 8, 2024
1 parent 23f0564 commit fa4352c
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 30 deletions.
18 changes: 14 additions & 4 deletions src/anari_test_scenes/scenes/test/random_spheres.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "random_spheres.h"
// std
#include <algorithm>
#include <random>

namespace anari {
Expand All @@ -24,7 +25,8 @@ std::vector<ParameterInfo> RandomSpheres::parameters()
// clang-format off
{makeParameterInfo("numSpheres", "Number of spheres to generate", int(1e3), int(1), int(1e6))},
{makeParameterInfo("radius", "Radius of all spheres", 1.5e-2f)},
{makeParameterInfo("randomizeRadii", "Randomize per-sphere radius", true)}
{makeParameterInfo("randomizeRadii", "Randomize per-sphere radius", true)},
{makeParameterInfo("remapPrimitiveIds", "remap primitive ids using primitive.id array", false)}
// clang-format on
};
}
Expand Down Expand Up @@ -54,9 +56,10 @@ void RandomSpheres::commit()
anari::setParameter(d, surface, "geometry", geom);
anari::setParameter(d, surface, "material", mat);

int numSpheres = getParam<int>("numSpheres", 2e4);
float radius = getParam<float>("radius", 1.5e-2f);
bool randomizeRadii = getParam<bool>("randomizeRadii", true);
const int numSpheres = getParam<int>("numSpheres", 2e4);
const float radius = getParam<float>("radius", 1.5e-2f);
const bool randomizeRadii = getParam<bool>("randomizeRadii", true);
const bool remapPrimitiveIds = getParam<bool>("remapPrimitiveIds", false);

if (numSpheres < 1)
throw std::runtime_error("'numSpheres' must be >= 1");
Expand All @@ -70,6 +73,7 @@ void RandomSpheres::commit()

std::vector<math::float3> spherePositions((size_t(numSpheres)));
std::vector<math::float4> sphereColors((size_t(numSpheres)));
std::vector<uint32_t> sphereIds((size_t(numSpheres)));

for (auto &s : spherePositions) {
s.x = vert_dist(rng);
Expand All @@ -84,13 +88,19 @@ void RandomSpheres::commit()
s.w = 1.f;
}

std::fill(sphereIds.begin(), sphereIds.end(), 1);

anari::setParameterArray1D(d,
geom,
"vertex.position",
spherePositions.data(),
spherePositions.size());
anari::setParameterArray1D(
d, geom, "vertex.color", sphereColors.data(), sphereColors.size());
if (remapPrimitiveIds) {
anari::setParameterArray1D(
d, geom, "primitive.id", sphereIds.data(), sphereIds.size());
}

if (randomizeRadii) {
std::normal_distribution<float> radii_dist(radius / 10.f, radius);
Expand Down
9 changes: 6 additions & 3 deletions src/helide/HelideDefinitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,12 @@
"default": "default",
"values": [
"default",
"primID",
"geomID",
"instID",
"primitiveId",
"objectId",
"instanceId",
"embreePrimID",
"embreeGeomID",
"embreeInstID",
"Ng",
"Ng.abs",
"uvw",
Expand Down
2 changes: 1 addition & 1 deletion src/helide/HelideDeviceQueries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ static const void * ANARI_RENDERER_default_mode_info(ANARIDataType paramType, in
}
case 6: // value
if(paramType == ANARI_STRING && infoType == ANARI_STRING_LIST) {
static const char *values[] = {"default", "primID", "geomID", "instID", "Ng", "Ng.abs", "uvw", "backface", "hitSurface", "hitVolume", "geometry.attribute0", "geometry.attribute1", "geometry.attribute2", "geometry.attribute3", "geometry.color", "opacityHeatmap", nullptr};
static const char *values[] = {"default", "primitiveId", "objectId", "instanceId", "embreePrimID", "embreeGeomID", "embreeInstID", "Ng", "Ng.abs", "uvw", "backface", "hitSurface", "hitVolume", "geometry.attribute0", "geometry.attribute1", "geometry.attribute2", "geometry.attribute3", "geometry.color", "opacityHeatmap", nullptr};
return values;
} else {
return nullptr;
Expand Down
65 changes: 45 additions & 20 deletions src/helide/renderer/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@ namespace helide {

static RenderMode renderModeFromString(const std::string &name)
{
if (name == "primID")
if (name == "primitiveId")
return RenderMode::PRIM_ID;
else if (name == "geomID")
return RenderMode::GEOM_ID;
else if (name == "instID")
else if (name == "objectId")
return RenderMode::OBJ_ID;
else if (name == "instanceId")
return RenderMode::INST_ID;
else if (name == "embreePrimID")
return RenderMode::PRIM_INDEX;
else if (name == "embreeGeomID")
return RenderMode::GEOM_INDEX;
else if (name == "embreeInstID")
return RenderMode::INST_INDEX;
else if (name == "Ng")
return RenderMode::NG;
else if (name == "Ng.abs")
Expand Down Expand Up @@ -123,7 +129,6 @@ PixelSample Renderer::renderSample(
RTCIntersectArguments iargs;
rtcInitIntersectArguments(&iargs);
rtcIntersect1(w.embreeScene(), (RTCRayHit *)&ray, &iargs);
const bool hitGeometry = ray.geomID != RTC_INVALID_GEOMETRY_ID;

// Intersect Volumes //

Expand All @@ -132,18 +137,10 @@ PixelSample Renderer::renderSample(
vray.dir = ray.dir;
vray.t.upper = ray.tfar;
w.intersectVolumes(vray);
const bool hitVolume = vray.volume != nullptr;

// Shade //

retval.color = shadeRay(screen, ray, vray, w);
retval.depth = hitVolume ? std::min(ray.tfar, vray.t.lower) : ray.tfar;
if (hitGeometry || hitVolume) {
retval.primId = hitVolume ? 0 : ray.primID;
retval.objId = hitVolume ? vray.volume->id() : w.surfaceFromRay(ray)->id();
retval.instId = hitVolume ? w.instanceFromRay(vray)->id(vray.instArrayID)
: w.instanceFromRay(ray)->id(ray.instArrayID);
}
shadeRay(retval, screen, ray, vray, w);

return retval;
}
Expand All @@ -154,7 +151,8 @@ Renderer *Renderer::createInstance(
return new Renderer(s);
}

float4 Renderer::shadeRay(const float2 &screen,
void Renderer::shadeRay(PixelSample &retval,
const float2 &screen,
const Ray &ray,
const VolumeRay &vray,
const World &w) const
Expand All @@ -165,8 +163,26 @@ float4 Renderer::shadeRay(const float2 &screen,
const float4 bgColorOpacity =
m_bgImage ? backgroundColorFromImage(*m_bgImage, screen) : m_bgColor;

if (!hitGeometry && !hitVolume)
return bgColorOpacity;
if (!hitGeometry && !hitVolume) {
retval.color = bgColorOpacity;
return;
}

// Write depth //

retval.depth = hitVolume ? std::min(ray.tfar, vray.t.lower) : ray.tfar;

// Write ids //

if (hitGeometry || hitVolume) {
retval.primId =
hitVolume ? 0 : w.surfaceFromRay(ray)->geometry()->getPrimID(ray);
retval.objId = hitVolume ? vray.volume->id() : w.surfaceFromRay(ray)->id();
retval.instId = hitVolume ? w.instanceFromRay(vray)->id(vray.instArrayID)
: w.instanceFromRay(ray)->id(ray.instArrayID);
}

// Write color //

const float3 bgColor(bgColorOpacity.x, bgColorOpacity.y, bgColorOpacity.z);

Expand All @@ -180,12 +196,21 @@ float4 Renderer::shadeRay(const float2 &screen,

switch (m_mode) {
case RenderMode::PRIM_ID:
geometryColor = makeRandomColor(retval.primId);
break;
case RenderMode::OBJ_ID:
geometryColor = makeRandomColor(retval.objId);
break;
case RenderMode::INST_ID:
geometryColor = makeRandomColor(retval.instId);
break;
case RenderMode::PRIM_INDEX:
geometryColor = hitGeometry ? makeRandomColor(ray.primID) : bgColor;
break;
case RenderMode::GEOM_ID:
case RenderMode::GEOM_INDEX:
geometryColor = hitGeometry ? makeRandomColor(ray.geomID) : bgColor;
break;
case RenderMode::INST_ID:
case RenderMode::INST_INDEX:
geometryColor = hitGeometry ? makeRandomColor(ray.instID) : bgColor;
break;
case RenderMode::RAY_UVW:
Expand Down Expand Up @@ -285,7 +310,7 @@ float4 Renderer::shadeRay(const float2 &screen,
accumulateValue(color, bgColor, opacity);
accumulateValue(opacity, bgColorOpacity.w, opacity);

return {color, opacity};
retval.color = float4(color, opacity);
}

} // namespace helide
Expand Down
8 changes: 6 additions & 2 deletions src/helide/renderer/Renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ enum class RenderMode
{
DEFAULT,
PRIM_ID,
GEOM_ID,
OBJ_ID,
INST_ID,
PRIM_INDEX,
GEOM_INDEX,
INST_INDEX,
NG,
NG_ABS,
NS,
Expand Down Expand Up @@ -57,7 +60,8 @@ struct Renderer : public Object
std::string_view subtype, HelideGlobalState *d);

private:
float4 shadeRay(const float2 &screen,
void shadeRay(PixelSample &retval,
const float2 &screen,
const Ray &ray,
const VolumeRay &vray,
const World &w) const;
Expand Down
6 changes: 6 additions & 0 deletions src/helide/scene/surface/geometry/Geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ void Geometry::commit()
m_primitiveAttr[2] = getParamObject<Array1D>("primitive.attribute2");
m_primitiveAttr[3] = getParamObject<Array1D>("primitive.attribute3");
m_primitiveAttr[4] = getParamObject<Array1D>("primitive.color");
m_primitiveId = getParamObject<Array1D>("primitive.id");
if (m_primitiveId
&& !(m_primitiveId->elementType() != ANARI_UINT32
|| m_primitiveId->elementType() != ANARI_UINT64)) {
m_primitiveId = nullptr;
}
}

void Geometry::markCommitted()
Expand Down
14 changes: 14 additions & 0 deletions src/helide/scene/surface/geometry/Geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,28 @@ struct Geometry : public Object
void markCommitted() override;

virtual float4 getAttributeValue(const Attribute &attr, const Ray &ray) const;
uint32_t getPrimID(const Ray &ray) const;

protected:
RTCGeometry m_embreeGeometry{nullptr};

UniformAttributeSet m_uniformAttr;
std::array<helium::IntrusivePtr<Array1D>, 5> m_primitiveAttr;
helium::IntrusivePtr<Array1D> m_primitiveId;
};

// Inlined definitions ////////////////////////////////////////////////////////

inline uint32_t Geometry::getPrimID(const Ray &ray) const
{
if (m_primitiveId) {
return m_primitiveId->elementType() == ANARI_UINT32
? *m_primitiveId->valueAt<uint32_t>(ray.primID)
: uint32_t(*m_primitiveId->valueAt<uint64_t>(ray.primID));
} else
return ray.primID;
}

} // namespace helide

HELIDE_ANARI_TYPEFOR_SPECIALIZATION(helide::Geometry *, ANARI_GEOMETRY);

0 comments on commit fa4352c

Please sign in to comment.