Nvidia OptiX GeometryGroup

1.4k views Asked by At

Hello I'm using Nvidia OptiX to create a RayTracer. I used the example Programs "sample0" and "tutorial" to set up a simple tracer.

In my C++ Code i set up Everything with:

this->buffer_height  = 512u;
this->buffer_width = 512u;
char path_to_ptx[512];
_context = _context->create();
_context->setRayTypeCount( 1 );
_context->setEntryPointCount( 1 );
_context->setStackSize( 4640 );
_context["radiance_ray_type"]->setUint( 0 );
_context["scene_epsilon"]->setFloat( 1.e-3f );
_context["result_buffer"]->set( _context->createBuffer( RT_BUFFER_OUTPUT, RT_FORMAT_FLOAT4, this->buffer_width, this->buffer_height) );

sprintf( path_to_ptx, "%s/%s", projectPath, "RayTracer_generated_draw_color.cu.ptx" );
_context->setRayGenerationProgram( 0, _context->createProgramFromPTXFile( path_to_ptx, "draw_solid_color" ) );
_context["draw_color"]->setFloat( 0.462f, 0.725f, 0.0f, 1.0f );
_context["eye"]->setFloat( 0.0f, 0.0f, 5.0f );

_context->setMissProgram( 0,  _context->createProgramFromPTXFile( path_to_ptx, "miss" ) );
_context["bg_color"]->setFloat( 1.0f, 0.0f, 0.0f, 1.0f );

sprintf( path_to_ptx, "%s/%s", projectPath, "RayTracer_generated_box.cu.ptx" );
Program box_bounds = _context->createProgramFromPTXFile( path_to_ptx, "box_bounds" );
Program box_intersect = _context->createProgramFromPTXFile( path_to_ptx, "box_intersect" );

sprintf( path_to_ptx, "%s/%s", projectPath, "RayTracer_generated_draw_color.cu.ptx" );

// This block must be full there. It is not possible just to create a geometry and not attach a program to it this would lead the program to crash when _context->compile();
Geometry gbox = _context->createGeometry();
gbox->setPrimitiveCount( 1u );
gbox->setBoundingBoxProgram( box_bounds );
gbox->setIntersectionProgram( box_intersect );
gbox["boxmin"]->setFloat( -2.0f, 0.0f, -2.0f );
gbox["boxmax"]->setFloat(  2.0f, 7.0f,  2.0f );

Material box_matl = _context->createMaterial();
Program box_ch = _context->createProgramFromPTXFile( path_to_ptx, "closest_hit_radiance0" );
box_matl->setClosestHitProgram( 0, box_ch );

GeometryInstance geomIns = _context->createGeometryInstance( /* gbox, &box_matl, &box_matl+1 */ );
geomIns->setGeometry( gbox );
geomIns->setMaterialCount( 1u );
geomIns->setMaterial( 0, box_matl );

GeometryGroup geomGrp = _context->createGeometryGroup();
geomGrp->setChildCount( 1u );
geomGrp->setChild( 0, geomIns );
geomGrp->setAcceleration( _context->createAcceleration("NoAccel","NoAccel") );
//_context["target"]->set( geomGrp );

_context->validate();
_context->compile();
_context->launch( 0, buffer_width, buffer_height );

this->imageData = _context["result_buffer"]->getBuffer()->map();
this->vboId = 0;
rtBufferGetGLBOId( _context["result_buffer"]->getBuffer()->get() , &this->vboId );

RTsize buffer_width_tmp, buffer_height_tmp;

rtBufferGetSize2D( _context["result_buffer"]->getBuffer()->get() , &buffer_width_tmp , &buffer_height_tmp );
this->width  = static_cast<GLsizei>(buffer_width_tmp);
this->height = static_cast<GLsizei>(buffer_height_tmp);

My .cu program looks like this:

#include <optix.h>
#include <optixu/optixu_math_namespace.h>
#include "commonStructs.h"

using namespace optix;


// Variables of Context

rtDeclareVariable( unsigned int, radiance_ray_type, , );
rtDeclareVariable( float, scene_epsilon, , );
rtDeclareVariable( rtObject, target, , );

rtBuffer<float4, 2> result_buffer;

// Variables of RayGenerationProgram
rtDeclareVariable( float3, eye, , );
rtDeclareVariable( float4, draw_color, , );

// Globals
rtDeclareVariable( PerRayData_radiance, prd_radiance, rtPayload, );
rtDeclareVariable( uint2, launch_index, rtLaunchIndex, );
rtDeclareVariable( uint2, launch_dim,   rtLaunchDim, );
rtDeclareVariable( float3, shading_normal,   attribute shading_normal, ); 


RT_PROGRAM void draw_solid_color()
{
    float2 d = make_float2(launch_index) / make_float2(launch_dim) * 2.f - 1.f;

float3 U,V,W;
U.x = 1.0; U.y = 0.0; U.z = 0.0;
V.x = 0.0; V.y = 1.0; V.z = 0.0;
W.x = 0.0; W.y = 0.0; W.z = -1.0;

// Calc the ray Direction
float3 ray_origin = eye;
float3 ray_direction = normalize( d.x*U + d.y*V + W );

// shoot the ray
optix::Ray ray(ray_origin, ray_direction, radiance_ray_type, scene_epsilon );

// Add ray Data
PerRayData_radiance prd;
prd.importance = 1.f;
prd.depth = 0;

//rtTrace(target, ray, prd);

//result_buffer[launch_index] = make_float4(prd.result.x, prd.result.y, prd.result.z, prd.result.w);

result_buffer[launch_index] = make_float4( abs(d.x), abs(d.y), 0.0f, 1.0f );


}

//
// Returns solid color for miss rays
//
rtDeclareVariable(float4, bg_color, , );
RT_PROGRAM void miss()
{
  prd_radiance.result = bg_color;
}


//
// Returns shading normal as the surface shading result
// 
RT_PROGRAM void closest_hit_radiance0()
{
    float3 res = normalize(rtTransformNormal(RT_OBJECT_TO_WORLD, shading_normal))*0.5f + 0.5f;
    float4 result;
    result.x = res.x;
    result.y = res.y;
    result.z = res.z;
    result.w = 1.0f;
    prd_radiance.result = result;
}

Like I posted it it works fine and a colored picture is visible, but you may have noticed that //_context["target"]->set( geomGrp ); in the c++ code. If I uncomment that the Program gets an exception in _context->compile();

The Box Program is the same as in all the examples.

Does anyone have an idea about what goes wrong when i want to set the target to the _context.

_context is of type Context like in #include .

Best Regards

Edit: found out more about the exception:

_context->compile();

is a shortcut for

checkError( rtContextCompile( m_context ) );

in optixx_namespace.h the returned result that is checked in checkError is a RT_ERROR_INVALID_VALUE .

1

There are 1 answers

0
rcpfuchs On BEST ANSWER

Fortunately I could fix the issue by myself. My Problem was I had an old install of CUDA 3.2 and CUDA 5.0 running side by side.