Hello,
I am trying to render particle data with ambient occlusion using Optix progressive launches. As starting point my code is based on the optixProgressiveVCA example, removing the remote features and adding more spheres.
Instead of creating a geometry for just one sphere, I am creating a vertex buffer containing the position and radius of each particle:
m_posBuffer = m_context->createBuffer( RT_BUFFER_INPUT, RT_FORMAT_FLOAT4, NUM_PARTICLES );
float4* positions = reinterpret_cast<float4*>(m_posBuffer->map());
for( unsigned int i = 0; i < NUM_PARTICLES; i+=4 )
{
positions->x = rand ()/(RAND_MAX*1.0f) * NUM_PARTICLES / 10.0f - NUM_PARTICLES / 10.0f;;
positions->y = rand ()/(RAND_MAX*1.0f) * NUM_PARTICLES / 10.0f - NUM_PARTICLES / 10.0f;;
positions->z = rand ()/(RAND_MAX*1.0f) * NUM_PARTICLES / 10.0f - NUM_PARTICLES / 10.0f;;
positions->w = 1.0f;
}
m_posBuffer->unmap();
Then I create the geometry holding that buffer, the geometry instance and the root group:
Geometry particles = m_context->createGeometry();
particles->setPrimitiveCount(NUM_PARTICLES);
particles->setBoundingBoxProgram( m_context->createProgramFromPTXFile( "shaders/spheres.ptx", "bounds" ) );
particles->setIntersectionProgram( m_context->createProgramFromPTXFile( "shaders/spheres.ptx", "intersect" ) );
particles["vertex_buffer"]->setBuffer ( m_posBuffer );
GeometryInstance gi = m_context->createGeometryInstance();
gi->setGeometry( particles );
gi->setMaterialCount( 1 );
gi->setMaterial( 0, m_material );
GeometryGroup geometrygroup = m_context->createGeometryGroup();
geometrygroup->setChildCount( 1 );
geometrygroup->setChild( 0, gi );
Acceleration accel = m_context->createAcceleration("Trbvh");
accel->setProperty("vertex_buffer_name", "vertex_buffer");
geometrygroup->setAcceleration( accel);
m_context["top_object"]->set( geometrygroup );
the material is from the optixProgressiveVCA’s ambient occlusion shader.
Finally I’ve modified the sphere shader from the optixProgressiveVCA example by adding the vertex buffer and receive the primitive idx in the corresponding methods:
...
rtBuffer<float4> vertex_buffer;
...
template<bool use_robust_method>
static __device__
void intersect_sphere(int primIdx)
{
const float4 lookUp = vertex_buffer[primIdx];
const float3 center = make_float3 (lookUp);
const float radius = lookUp.w;
...
}
RT_PROGRAM void intersect(int primIdx)
{
//rtPrintf( "primIdx %d", primIdx);
intersect_sphere<false>( primIdx );
}
RT_PROGRAM void robust_intersect(int primIdx)
{
intersect_sphere<true>( primIdx );
}
RT_PROGRAM void bounds (int primIdx, float result[6])
{
//rtPrintf( "primIdx %d", primIdx);
// const int idx = index_buffer[primIdx];
const float4 lookUp = vertex_buffer[primIdx];
const float3 center = make_float3 (lookUp);
const float radius = lookUp.w;
...
}
Validating the context shows no error, but when running the application is I got:
Invalid value (Details: Function “RTresult _rtContextLaunchProgressive2D(RTcontext, unsigned int, RTsize, RTsize, unsigned int)” caught exception: Invalid vertex buffer size. Possible reasons: stride too large with no index buffer.)
I guess I am missing something in the set-up, I checked the swimmingShark example in Optix 3.8 that renders a set of bubbles but can’t find what. Any leads would be very useful.
Thanks!
Benjamin
Using:
Titan-Z GPU (Kepler)
Driver Version: 367.57
CUDA 8.0
Optix 4.0.2
Ubuntu 16