different ray types in ray generation program?

Hi.

I am trying to make a bidirectional path tracer, but I have some trouble with tracing different types of rays in the ray generation program.

I specifically having trouble with my shadow rays, which is attached to a simple any_hit program, which is inspired by the path tracing example. When the program run, it’ll cast the error: 700 illegal address.

If i do shadow tracing in a closest_hit program, it’s working perfectly, so I’m quite confused.

The shadow tracing part of the program.

// Test if in shadow
shadow_ray_data shadow_data;
shadow_data.inShadow = 0.0f;
Ray shadow_ray = make_Ray(current_vertex.position, dir, shadow_ray_type, scene_epsilon, dist - scene_epsilon);
rtTrace(top_object, shadow_ray, shadow_data);

If i comment out the line where the tracing is happening, the code works fine. and if I merge the two ray data structs to one, the program is working fine as well. but I’m not really happy with dragging the data for the other programs along when tracing for shadows.

My ray data:

struct shadow_ray_data
{
	float inShadow;
};

struct eye_path_vertex
{
	float3 position;
	float3 shading_normal;
	float3 geometric_normal;
	float2 uv;
	float3 wi;
	float3 attenuation;
	float3 radiance;
	unsigned int material_id;
	bool done;
	//float inShadow;
};

Can it really be true that it’s not possible to trace different types of rays in the ray generation program.

As a more basic test, try shooting a shadow ray from the eye in pathtrace_camera() in the optixPathTracer sample in the SDK. Something like this:

...
prd.seed = seed;
prd.depth = 0;

// INSERTED NEW CODE: shoot a shadow ray from the eye
PerRayData_pathtrace_shadow shadow_prd;
shadow_prd.inShadow = false;
Ray shadow_ray = make_Ray( ray_origin, ray_direction, pathtrace_shadow_ray_type, scene_epsilon, RT_DEFAULT_MAX );
rtTrace(top_object, shadow_ray, shadow_prd);
if ( launch_index.x == 0 && launch_index.y == 0 ) {
  printf("shot shadow ray at launch index %d %d, inShadow = %d\n", 
    launch_index.x, launch_index.y, shadow_prd.inShadow);
}

// Each iteration is a segment of the ray path.  The closest hit will
// return new segments to be traced here.
for(;;)
{
  ...
}

You should get values of ‘0’ or ‘1’ for the inShadow result depending on whether launch index (0,0), which is the lower left corner of the image, has geometry under it. I’m just using a specific launch index to reduce the amount of output and make it easier to debug.

Example output on my machine:

shot shadow ray at launch index 0 0, inShadow = 0
...

Try to move the float2 uv onto an 8 byte aligned offset in your per ray data structure.
That is currently on a 4 byte aligned offset which might be a reason for an illegal address error.
Putting it as first element would do.

Check the CUDA manual for other alignment requirements.
See Table 3. Alignment Requirements in Device Code here:
http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#built-in-vector-types

Any updates on this? Were you able to confirm that my mods to optixPathTracer above work ok, proving that you can shoot different types of rays from a ray-gen program?

So I may or may not have found a solution to this problem. It had nothing to do with the amount of ray_types used. Or at least it is now working with multiple types.

First I tried the solution from Detlef Roettger, but without any result. I’m also not really sure if I did it correctly, but I kept the changes for the later solution, so it may have some effect I’m not aware of.

From here I tried going back to the basics, greatly inspired by dlacewell, and the code ran without any problems, with a simple implementation using all 3 ray_types.

I then remembered from somewhere that passing ray_data as pointers to the rtTrace can give some problems. Therefore I tried making a new implementation without an array of ray_data, for each vertex in the path. Instead I now have a single ray_data, which is reused for every trace, then I have an array of vertex data, from where the data is copied into the ray_data. I am not exactly sure if this was the problem, but now I have a working implementation.