Skip to content

Commit

Permalink
Initial implementation of b-spline/linear curve shapes
Browse files Browse the repository at this point in the history
  • Loading branch information
akaqyd authored and njroussel committed Apr 25, 2023
1 parent e5abd7d commit e4c847f
Show file tree
Hide file tree
Showing 13 changed files with 1,388 additions and 58 deletions.
2 changes: 1 addition & 1 deletion ext/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ if (MI_ENABLE_EMBREE)
set(EMBREE_FILTER_FUNCTION OFF CACHE BOOL " " FORCE)
set(EMBREE_IGNORE_CMAKE_CXX_FLAGS OFF CACHE BOOL " " FORCE)
set(EMBREE_GEOMETRY_QUAD OFF CACHE BOOL " " FORCE)
set(EMBREE_GEOMETRY_CURVE OFF CACHE BOOL " " FORCE)
set(EMBREE_GEOMETRY_GRID OFF CACHE BOOL " " FORCE)
set(EMBREE_GEOMETRY_POINT OFF CACHE BOOL " " FORCE)
set(EMBREE_GEOMETRY_SUBDIVISION OFF CACHE BOOL " " FORCE)
set(EMBREE_GEOMETRY_CURVE ON CACHE BOOL " " FORCE)
set(EMBREE_GEOMETRY_INSTANCE ON CACHE BOOL " " FORCE)
set(EMBREE_GEOMETRY_USER ON CACHE BOOL " " FORCE)
set(EMBREE_IGNORE_INVALID_RAYS ON CACHE BOOL " " FORCE)
Expand Down
88 changes: 70 additions & 18 deletions include/mitsuba/render/optix/shapes.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "mesh.cuh"
#include "rectangle.cuh"
#include "sphere.cuh"
#include "bsplinecurve.cuh"
#include "linearcurve.cuh"
#else

#include <drjit-core/optix.h>
Expand All @@ -19,7 +21,7 @@
NAMESPACE_BEGIN(mitsuba)
/// List of the custom shapes supported by OptiX
static std::string CUSTOM_OPTIX_SHAPE_NAMES[] = {
"Disk", "Rectangle", "Sphere", "Cylinder",
"Disk", "Rectangle", "Sphere", "Cylinder", "BSplineCurve", "LinearCurve"
};
static constexpr size_t CUSTOM_OPTIX_SHAPE_COUNT = std::size(CUSTOM_OPTIX_SHAPE_NAMES);

Expand All @@ -35,19 +37,23 @@ size_t get_shape_descr_idx(Shape *shape) {
"'CUSTOM_OPTIX_SHAPE_NAMES' table.", name);
}

/// Stores two OptiXTraversables: one for the meshes and one for the custom shapes (e.g. sphere)
/// Stores multiple OptiXTraversables: one for the each type
struct OptixAccelData {
struct HandleData {
OptixTraversableHandle handle = 0ull;
void* buffer = nullptr;
uint32_t count = 0u;
};
HandleData meshes;
HandleData others;
HandleData bspline_curves;
HandleData linear_curves;
HandleData custom_shapes;

~OptixAccelData() {
if (meshes.buffer) jit_free(meshes.buffer);
if (others.buffer) jit_free(others.buffer);
if (bspline_curves.buffer) jit_free(bspline_curves.buffer);
if (linear_curves.buffer) jit_free(linear_curves.buffer);
if (custom_shapes.buffer) jit_free(custom_shapes.buffer);
}
};

Expand All @@ -56,11 +62,26 @@ template <typename Shape>
void fill_hitgroup_records(std::vector<ref<Shape>> &shapes,
std::vector<HitGroupSbtRecord> &out_hitgroup_records,
const OptixProgramGroup *program_groups) {
for (size_t i = 0; i < 2; i++) {
for (size_t i = 0; i < 4; i++) {
for (Shape* shape: shapes) {
// This trick allows meshes to be processed first
if (i == !shape->is_mesh())
shape->optix_fill_hitgroup_records(out_hitgroup_records, program_groups);
switch (i) {
case 0:
if (shape->is_mesh())
shape->optix_fill_hitgroup_records(out_hitgroup_records, program_groups);
break;
case 1:
if (shape->is_bspline_curve())
shape->optix_fill_hitgroup_records(out_hitgroup_records, program_groups);
break;
case 2:
if (shape->is_linear_curve())
shape->optix_fill_hitgroup_records(out_hitgroup_records, program_groups);
break;
case 3:
if (!shape->is_mesh() && !shape->is_curve())
shape->optix_fill_hitgroup_records(out_hitgroup_records, program_groups);
break;
}
}
}
}
Expand All @@ -76,13 +97,18 @@ void build_gas(const OptixDeviceContext &context,
const std::vector<ref<Shape>> &shapes,
OptixAccelData& out_accel) {

// Separate meshes and custom shapes
std::vector<ref<Shape>> shape_meshes, shape_others;
for (auto shape: shapes) {
// Separate geometry types
std::vector<ref<Shape>> meshes, bspline_curves,
linear_curves, custom_shapes;
for (auto shape : shapes) {
if (shape->is_mesh())
shape_meshes.push_back(shape);
meshes.push_back(shape);
else if (shape->is_bspline_curve())
bspline_curves.push_back(shape);
else if (shape->is_linear_curve())
linear_curves.push_back(shape);
else if (!shape->is_instance())
shape_others.push_back(shape);
custom_shapes.push_back(shape);
}

// Build a GAS given a subset of shape pointers
Expand All @@ -92,6 +118,9 @@ void build_gas(const OptixDeviceContext &context,
OptixAccelBuildOptions accel_options = {};
accel_options.buildFlags = OPTIX_BUILD_FLAG_ALLOW_COMPACTION |
OPTIX_BUILD_FLAG_PREFER_FAST_TRACE;
if (shape_subset.size() > 1 && shape_subset[0]->is_curve())
accel_options.buildFlags |= OPTIX_BUILD_FLAG_ALLOW_RANDOM_VERTEX_ACCESS;

accel_options.operation = OPTIX_BUILD_OPERATION_BUILD;
accel_options.motionOptions.numKeys = 0;
if (handle.buffer) {
Expand All @@ -102,7 +131,6 @@ void build_gas(const OptixDeviceContext &context,
}

size_t shapes_count = shape_subset.size();

if (shapes_count == 0)
return;

Expand Down Expand Up @@ -174,8 +202,10 @@ void build_gas(const OptixDeviceContext &context,

scoped_optix_context guard;

build_single_gas(shape_meshes, out_accel.meshes);
build_single_gas(shape_others, out_accel.others);
build_single_gas(meshes, out_accel.meshes);
build_single_gas(bspline_curves, out_accel.bspline_curves);
build_single_gas(linear_curves, out_accel.linear_curves);
build_single_gas(custom_shapes, out_accel.custom_shapes);
}

/// Prepares and fills the \ref OptixInstance array associated with a given list of shapes.
Expand Down Expand Up @@ -212,12 +242,34 @@ void prepare_ias(const OptixDeviceContext &context,
sbt_offset += (unsigned int) accel.meshes.count;
}

// Create an OptixInstance for the bspline curves if necessary
if (accel.bspline_curves.handle) {
OptixInstance bspline_curves_instance = {
{ T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10], T[11] },
instance_id, sbt_offset, /* visibilityMask = */ 255,
flags, accel.bspline_curves.handle, /* pads = */ { 0, 0 }
};
sbt_offset += (unsigned int) accel.bspline_curves.count;
out_instances.push_back(bspline_curves_instance);
}

// Create an OptixInstance for the linear curves if necessary
if (accel.linear_curves.handle) {
OptixInstance linear_curves_instance = {
{ T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10], T[11] },
instance_id, sbt_offset, /* visibilityMask = */ 255,
flags, accel.linear_curves.handle, /* pads = */ { 0, 0 }
};
sbt_offset += (unsigned int) accel.linear_curves.count;
out_instances.push_back(linear_curves_instance);
}

// Create an OptixInstance for the custom shapes if necessary
if (accel.others.handle) {
if (accel.custom_shapes.handle) {
OptixInstance others_instance = {
{ T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10], T[11] },
instance_id, sbt_offset, /* visibilityMask = */ 255,
flags, accel.others.handle, /* pads = */ { 0, 0 }
flags, accel.custom_shapes.handle, /* pads = */ { 0, 0 }
};
out_instances.push_back(others_instance);
}
Expand Down
50 changes: 45 additions & 5 deletions include/mitsuba/render/optix_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ using OptixIndicesFormat = int;
using OptixTransformFormat = int;
using OptixAccelPropertyType = int;
using OptixProgramGroupKind = int;
using OptixPrimitiveType = int;
using OptixDeviceContext = void*;
using OptixTask = void*;
using OptixDenoiserStructPtr = void*;
Expand All @@ -34,6 +35,7 @@ using OptixDenoiserStructPtr = void*;
#define OPTIX_BUILD_INPUT_TYPE_TRIANGLES 0x2141
#define OPTIX_BUILD_INPUT_TYPE_CUSTOM_PRIMITIVES 0x2142
#define OPTIX_BUILD_INPUT_TYPE_INSTANCES 0x2143
#define OPTIX_BUILD_INPUT_TYPE_CURVES 0x2145
#define OPTIX_BUILD_OPERATION_BUILD 0x2161

#define OPTIX_GEOMETRY_FLAG_NONE 0
Expand All @@ -52,9 +54,10 @@ using OptixDenoiserStructPtr = void*;
#define OPTIX_COMPILE_DEBUG_LEVEL_MODERATE 0x2353
#define OPTIX_COMPILE_DEBUG_LEVEL_FULL 0x2352

#define OPTIX_BUILD_FLAG_ALLOW_COMPACTION 2
#define OPTIX_BUILD_FLAG_PREFER_FAST_TRACE 4
#define OPTIX_PROPERTY_TYPE_COMPACTED_SIZE 0x2181
#define OPTIX_BUILD_FLAG_ALLOW_COMPACTION 2
#define OPTIX_BUILD_FLAG_PREFER_FAST_TRACE 4
#define OPTIX_BUILD_FLAG_ALLOW_RANDOM_VERTEX_ACCESS 16
#define OPTIX_PROPERTY_TYPE_COMPACTED_SIZE 0x2181

#define OPTIX_EXCEPTION_FLAG_NONE 0
#define OPTIX_EXCEPTION_FLAG_STACK_OVERFLOW 1
Expand All @@ -66,8 +69,16 @@ using OptixDenoiserStructPtr = void*;
#define OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_GAS 1
#define OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING (1u << 1)

#define OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM (1 << 0)
#define OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE (1 << 31)
#define OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE 0x2502
#define OPTIX_PRIMITIVE_TYPE_ROUND_LINEAR 0x2503

#define OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM (1 << 0)
#define OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_CUBIC_BSPLINE (1 << 2)
#define OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_LINEAR (1 << 3)
#define OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE (1 << 31)

#define OPTIX_CURVE_ENDCAP_DEFAULT 0
#define OPTIX_CURVE_ENDCAP_ON 1

#define OPTIX_PROGRAM_GROUP_KIND_MISS 0x2422
#define OPTIX_PROGRAM_GROUP_KIND_HITGROUP 0x2424
Expand All @@ -81,6 +92,7 @@ using OptixDenoiserStructPtr = void*;

#define OPTIX_MODULE_COMPILE_STATE_COMPLETED 0x2364


// =====================================================
// Commonly used OptiX data structures
// =====================================================
Expand Down Expand Up @@ -140,16 +152,41 @@ struct OptixBuildInputInstanceArray {
unsigned int numInstances;
};

struct OptixBuildInputCurveArray {
OptixPrimitiveType curveType;
unsigned int numPrimitives;
const CUdeviceptr* vertexBuffers;
unsigned int numVertices;
unsigned int vertexStrideInBytes;
const CUdeviceptr* widthBuffers;
unsigned int widthStrideInBytes;
const CUdeviceptr* normalBuffers;
unsigned int normalStrideInBytes;
CUdeviceptr indexBuffer;
unsigned int indexStrideInBytes;
unsigned int flag;
unsigned int primitiveIndexOffset;
unsigned int endcapFlags;
};

struct OptixBuildInput {
OptixBuildInputType type;
union {
OptixBuildInputTriangleArray triangleArray;
OptixBuildInputCustomPrimitiveArray customPrimitiveArray;
OptixBuildInputInstanceArray instanceArray;
OptixBuildInputCurveArray curveArray;
char pad[1024];
};
};

struct OptixBuiltinISOptions {
OptixPrimitiveType builtinISModuleType;
int usesMotionBlur;
unsigned int buildFlags;
unsigned int curveEndcapFlags;
};

struct OptixInstance {
float transform[12];
unsigned int instanceId;
Expand Down Expand Up @@ -305,6 +342,9 @@ D(optixAccelComputeMemoryUsage, OptixDeviceContext,
D(optixAccelBuild, OptixDeviceContext, CUstream, const OptixAccelBuildOptions *,
const OptixBuildInput *, unsigned int, CUdeviceptr, size_t, CUdeviceptr,
size_t, OptixTraversableHandle *, const OptixAccelEmitDesc *, unsigned int);
D(optixBuiltinISModuleGet, OptixDeviceContext,
const OptixModuleCompileOptions *, const OptixPipelineCompileOptions *,
const OptixBuiltinISOptions *, OptixModule *);
D(optixModuleCreateFromPTXWithTasks, OptixDeviceContext,
const OptixModuleCompileOptions *, const OptixPipelineCompileOptions *,
const char *, size_t, char *, size_t *, OptixModule *, OptixTask *);
Expand Down
11 changes: 10 additions & 1 deletion include/mitsuba/render/shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,15 @@ class MI_EXPORT_LIB Shape : public Object {
/// Is this shape a triangle mesh?
bool is_mesh() const;

/// Is this shape a curve ?
virtual bool is_curve() const;

/// Is this shape a curve ?
virtual bool is_bspline_curve() const;

/// Is this shape a curve ?
virtual bool is_linear_curve() const;

/// Is this shape a shapegroup?
bool is_shapegroup() const { return class_()->name() == "ShapeGroupPlugin"; };

Expand Down Expand Up @@ -641,14 +650,14 @@ DRJIT_VCALL_TEMPLATE_BEGIN(mitsuba::Shape)
DRJIT_VCALL_METHOD(eval_attribute)
DRJIT_VCALL_METHOD(eval_attribute_1)
DRJIT_VCALL_METHOD(eval_attribute_3)
DRJIT_VCALL_METHOD(eval_parameterization)
DRJIT_VCALL_METHOD(ray_intersect_preliminary)
DRJIT_VCALL_METHOD(ray_intersect)
DRJIT_VCALL_METHOD(ray_test)
DRJIT_VCALL_METHOD(sample_position)
DRJIT_VCALL_METHOD(pdf_position)
DRJIT_VCALL_METHOD(sample_direction)
DRJIT_VCALL_METHOD(pdf_direction)
DRJIT_VCALL_METHOD(eval_parameterization)
DRJIT_VCALL_METHOD(surface_area)
DRJIT_VCALL_GETTER(emitter, const typename Class::Emitter *)
DRJIT_VCALL_GETTER(sensor, const typename Class::Sensor *)
Expand Down
Loading

0 comments on commit e4c847f

Please sign in to comment.