16#include <optix_world.h>
17#include "RayTracing.cuh"
21RT_PROGRAM
void direct_raygen() {
23 uint Nrays = launch_dim.x * launch_dim.y;
24 uint ray_index = launch_dim.x * launch_index.y + launch_index.x;
27 prd.seed = tea<16>(ray_index + Nrays * launch_index.z, random_seed);
29 uint objID = launch_offset + launch_index.z;
31 uint pID = primitiveID[objID];
32 uint ptype = primitive_type[objID];
33 int puvID = uvID[objID];
41 for (
uint i = 0; i < 16; i++) {
42 m_trans[i] = transform_matrix[optix::make_uint2(i, objID)];
46 int NX = object_subdivisions[objID].x;
47 int NY = object_subdivisions[objID].y;
48 for (
int jj = 0; jj < NY; jj++) {
49 for (
int ii = 0; ii < NX; ii++) {
51 uint UUID = pID + jj * NX + ii;
54 float Rx = rnd(prd.seed);
55 float Ry = rnd(prd.seed);
57 if (ptype == 0 || ptype == 3) {
59 uint Nx = launch_dim.x;
60 uint Ny = launch_dim.y;
61 float dx = 1.f / float(NX);
62 float dy = 1.f / float(NY);
65 sp.x = -0.5f + ii * dx + float(launch_index.x) * dx / float(Nx) + Rx * dx / float(Nx);
66 sp.y = -0.5f + jj * dy + float(launch_index.y) * dy / float(Ny) + Ry * dy / float(Ny);
69 int ID = maskID[objID];
70 if (ID >= 0 && primitive_solid_fraction[UUID] > 0.f && primitive_solid_fraction[UUID] < 1.f) {
72 d_sampleTexture_patch(sp, optix::make_int2(ii, jj), optix::make_float2(dx, dy), prd, ID, puvID);
76 float3 v0 = make_float3(0, 0, 0);
77 d_transformPoint(m_trans, v0);
78 float3 v1 = make_float3(1, 0, 0);
79 d_transformPoint(m_trans, v1);
80 float3 v2 = make_float3(0, 1, 0);
81 d_transformPoint(m_trans, v2);
83 normal = normalize(
cross(v1 - v0, v2 - v0));
85 }
else if (ptype == 1) {
98 float3 v0 = make_float3(0, 0, 0);
99 d_transformPoint(m_trans, v0);
100 float3 v1 = make_float3(0, 1, 0);
101 d_transformPoint(m_trans, v1);
102 float3 v2 = make_float3(1, 1, 0);
103 d_transformPoint(m_trans, v2);
105 normal = normalize(
cross(v1 - v0, v2 - v1));
107 int ID = maskID[objID];
108 if (ID >= 0 && primitive_solid_fraction[UUID] > 0.f && primitive_solid_fraction[UUID] < 1.f) {
110 d_sampleTexture_triangle(sp, v0, v1, v2, prd, m_trans, ID, puvID);
113 }
else if (ptype == 2) {
115 d_sampleDisk(prd.seed, sp);
118 float3 v0 = make_float3(0, 0, 0);
119 d_transformPoint(m_trans, v0);
120 float3 v1 = make_float3(1, 0, 0);
121 d_transformPoint(m_trans, v1);
122 float3 v2 = make_float3(0, 1, 0);
123 d_transformPoint(m_trans, v2);
125 normal = normalize(
cross(v1 - v0, v2 - v0));
127 }
else if (ptype == 4) {
129 float Rz = rnd(prd.seed);
134 float3 ray_origin = sp;
135 d_transformPoint(m_trans, ray_origin);
138 for (
int rr = 0; rr < Nsources; rr++) {
141 float3 ray_direction;
143 if (source_types[rr] == 0) {
144 ray_direction = normalize(source_positions[rr]);
145 ray_magnitude = RT_DEFAULT_MAX;
146 prd.strength = 1. / double(launch_dim.x * launch_dim.y) * fabs(dot(normal, ray_direction));
147 }
else if (source_types[rr] == 1 || source_types[rr] == 2) {
150 float theta_s =
acos_safe(1.f - 2.f * rnd(prd.seed));
151 float phi_s = rnd(prd.seed) * 2.f *
M_PI;
152 float3 sphere_point = 0.5 * source_widths[rr].x * make_float3(sin(theta_s) * cos(phi_s), sin(theta_s) * sin(phi_s), cos(theta_s));
154 ray_direction = sphere_point + source_positions[rr] - ray_origin;
156 ray_magnitude = d_magnitude(ray_direction);
157 ray_direction = normalize(ray_direction);
160 for (
uint j = 0; j < N; j++) {
161 for (
uint i = 0; i < N; i++) {
162 float theta =
acos_safe(1.f - 2.f * (
float(i) + 0.5f) /
float(N));
163 float phi = (float(j) + 0.5f) * 2.f *
M_PI /
float(N);
164 float3 light_direction = make_float3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
165 if (dot(light_direction, ray_direction) < 0) {
167 1. / double(launch_dim.x * launch_dim.y) * fabs(dot(normal, ray_direction)) * fabs(dot(light_direction, ray_direction)) / (ray_magnitude * ray_magnitude) / (N * N) * source_widths[rr].x * source_widths[rr].x;
172 }
else if (source_types[rr] == 3) {
175 float light_transform[16];
176 d_makeTransformMatrix(source_rotations[rr], light_transform);
180 d_sampleSquare(prd.seed, square_point);
181 square_point = make_float3(source_widths[rr].x * square_point.x, source_widths[rr].y * square_point.y, square_point.z);
182 d_transformPoint(light_transform, square_point);
184 float3 light_direction = make_float3(0, 0, 1);
185 d_transformPoint(light_transform, light_direction);
187 ray_direction = square_point + source_positions[rr] - ray_origin;
189 if (dot(ray_direction, light_direction) > 0.f) {
193 ray_magnitude = d_magnitude(ray_direction);
194 ray_direction = normalize(ray_direction);
195 prd.strength = 1. / double(launch_dim.x * launch_dim.y) * fabs(dot(normal, ray_direction)) * fabs(dot(light_direction, ray_direction)) / (ray_magnitude * ray_magnitude) * source_widths[rr].x * source_widths[rr].y /
M_PI;
197 }
else if (source_types[rr] == 4) {
200 float light_transform[16];
201 d_makeTransformMatrix(source_rotations[rr], light_transform);
205 d_sampleDisk(prd.seed, disk_point);
206 d_transformPoint(light_transform, disk_point);
208 float3 light_direction = make_float3(0, 0, 1);
209 d_transformPoint(light_transform, light_direction);
211 ray_direction = source_widths[rr].x * disk_point + source_positions[rr] - ray_origin;
213 if (dot(ray_direction, light_direction) > 0.f) {
217 ray_magnitude = d_magnitude(ray_direction);
218 ray_direction = normalize(ray_direction);
219 prd.strength = 1. / double(launch_dim.x * launch_dim.y) * fabs(dot(normal, ray_direction)) * fabs(dot(light_direction, ray_direction)) / (ray_magnitude * ray_magnitude) * source_widths[rr].x * source_widths[rr].x;
222 optix::Ray ray = optix::make_Ray(ray_origin, ray_direction, direct_ray_type, 1e-4, ray_magnitude);
224 prd.origin_UUID = UUID;
226 prd.hit_periodic_boundary =
false;
228 if (dot(ray_direction, normal) > 0) {
234 if ((prd.face == 1 || twosided_flag[objID] == 1) && twosided_flag[objID] != 3) {
236 for (
int wrap = 0; wrap < 10; ++wrap) {
237 rtTrace(top_object, ray, prd);
239 if (!prd.hit_periodic_boundary)
242 ray.origin = prd.periodic_hit;
243 prd.hit_periodic_boundary =
false;
251RT_PROGRAM
void diffuse_raygen() {
253 uint dimx = launch_dim.x * launch_dim.y;
254 uint indx = launch_dim.x * launch_index.y + launch_index.x;
257 prd.seed = tea<16>(indx + dimx * launch_index.z, random_seed);
259 uint objID = launch_offset + launch_index.z;
261 if (launch_face == 0 && twosided_flag[objID] == 0) {
265 uint pID = primitiveID[objID];
266 uint ptype = primitive_type[objID];
267 int puvID = uvID[objID];
271 for (
uint i = 0; i < 16; i++) {
272 m_trans[i] = transform_matrix[optix::make_uint2(i, objID)];
278 int NX = object_subdivisions[objID].x;
279 int NY = object_subdivisions[objID].y;
280 for (
int jj = 0; jj < NY; jj++) {
281 for (
int ii = 0; ii < NX; ii++) {
283 uint UUID = pID + jj * NX + ii;
286 float Rx = rnd(prd.seed);
287 float Ry = rnd(prd.seed);
290 printf(
"objID = %d\n", objID);
291 printf(
"Invalid primitive type in diffuse ray launch.\n");
294 if (ptype == 0 || ptype == 3) {
297 float3 s0 = make_float3(0, 0, 0);
298 float3 s1 = make_float3(1, 0, 0);
299 float3 s2 = make_float3(0, 1, 0);
300 d_transformPoint(m_trans, s0);
301 d_transformPoint(m_trans, s1);
302 d_transformPoint(m_trans, s2);
304 normal = normalize(
cross(s1 - s0, s2 - s0));
306 float dx = 1.f / float(NX);
307 float dy = 1.f / float(NY);
310 sp.x = -0.5f + (ii + Rx) * dx;
311 sp.y = -0.5f + (jj + Ry) * dy;
314 int ID = maskID[objID];
317 d_sampleTexture_patch(sp, optix::make_int2(ii, jj), optix::make_float2(dx, dy), prd, ID, puvID);
320 }
else if (ptype == 1) {
333 float3 v0 = make_float3(0, 0, 0);
334 d_transformPoint(m_trans, v0);
335 float3 v1 = make_float3(0, 1, 0);
336 d_transformPoint(m_trans, v1);
337 float3 v2 = make_float3(1, 1, 0);
338 d_transformPoint(m_trans, v2);
340 normal = normalize(
cross(v1 - v0, v2 - v1));
342 int ID = maskID[objID];
345 d_sampleTexture_triangle(sp, v0, v1, v2, prd, m_trans, ID, puvID);
348 }
else if (ptype == 2) {
353 sp.x = -1.f + 2.f * Rx;
354 sp.y = -1.f + 2.f * Ry;
363 p = 2.f - sp.x / sp.y;
368 p = 4.f + sp.y / sp.x;
372 p = 6.f - sp.x / sp.y;
386 float3 v0 = make_float3(0, 0, 0);
387 d_transformPoint(m_trans, v0);
388 float3 v1 = make_float3(1, 0, 0);
389 d_transformPoint(m_trans, v1);
390 float3 v2 = make_float3(0, 1, 0);
391 d_transformPoint(m_trans, v2);
392 normal = normalize(
cross(v1 - v0, v2 - v0));
394 }
else if (ptype == 4) {
399 sp.z = -0.5f + rnd(prd.seed);
407 Rt = (launch_index.x + rnd(prd.seed)) /
float(launch_dim.x);
408 Rp = (launch_index.y + rnd(prd.seed)) /
float(launch_dim.y);
416 float p = 2.f *
M_PI * Rp;
418 float3 ray_direction;
419 ray_direction.x = sin(t) * cos(p);
420 ray_direction.y = sin(t) * sin(p);
421 ray_direction.z = cos(t);
428 prd.strength = 0.5f / float(dimx);
429 prd.origin_UUID = UUID;
432 prd.hit_periodic_boundary =
false;
435 d_transformPoint(m_trans, ray_origin);
437 ray = optix::make_Ray(ray_origin, ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
438 rtTrace(top_object, ray, prd);
440 ray = optix::make_Ray(ray_origin, -ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
441 rtTrace(top_object, ray, prd);
445 ray_direction = d_rotatePoint(ray_direction,
acos_safe(normal.z), atan2(normal.y, normal.x));
447 prd.strength = 1.f / float(dimx);
449 prd.origin_UUID = UUID;
451 prd.hit_periodic_boundary =
false;
455 d_transformPoint(m_trans, ray_origin);
457 if (launch_face == 1 && twosided_flag[objID] != 3) {
459 ray = optix::make_Ray(ray_origin, ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
463 for (
int wrap = 0; wrap < 10; ++wrap) {
464 rtTrace(top_object, ray, prd);
466 if (!prd.hit_periodic_boundary)
469 ray.origin = prd.periodic_hit;
470 prd.hit_periodic_boundary =
false;
474 }
else if (launch_face == 0 && twosided_flag[objID] == 1) {
475 ray_direction = -ray_direction;
476 ray = optix::make_Ray(ray_origin, ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
480 for (
int wrap = 0; wrap < 10; ++wrap) {
481 rtTrace(top_object, ray, prd);
483 if (!prd.hit_periodic_boundary)
486 ray.origin = prd.periodic_hit;
487 prd.hit_periodic_boundary =
false;
495RT_PROGRAM
void camera_raygen() {
497 uint dimx = launch_dim.x * launch_dim.y;
498 uint indx = launch_dim.x * launch_index.y + launch_index.x;
500 optix::int2 camera_resolution = optix::make_int2(launch_dim.y, launch_dim.z);
503 prd.seed = tea<16>(indx + dimx * launch_index.z, random_seed);
507 uint ii = launch_index.y;
508 uint jj = launch_index.z;
509 size_t origin_ID = jj * launch_dim.y + ii;
528 float PPointsRatiox = 1.f;
529 float PPointsRatioy = 1.f;
530 float Rx = rnd(prd.seed);
531 float Ry = rnd(prd.seed);
537 float multiplier = 1.0f / FOV_aspect_ratio;
538 sp.y = (-0.5f * PPointsRatioy + (ii + Rx) /
float(camera_resolution.x));
539 sp.z = (0.5f * PPointsRatiox - (jj + Ry) /
float(camera_resolution.y)) * multiplier;
540 sp.x = camera_viewplane_length;
544 float3 p = make_float3(camera_focal_length, sp.y / camera_viewplane_length * camera_focal_length, sp.z / camera_viewplane_length * camera_focal_length);
548 float3 ray_origin = make_float3(0, 0, 0);
549 if (camera_lens_diameter > 0) {
551 d_sampleDisk(prd.seed, disk_sample);
552 ray_origin = make_float3(0.f, 0.5f * disk_sample.x * camera_lens_diameter, 0.5f * disk_sample.y * camera_lens_diameter);
557 float3 ray_direction = p - ray_origin;
561 ray_origin = d_rotatePoint(ray_origin, -0.5 *
M_PI + camera_direction.x, 0.5f *
M_PI - camera_direction.y) + camera_position;
563 ray_direction = d_rotatePoint(ray_direction, -0.5 *
M_PI + camera_direction.x, 0.5f *
M_PI - camera_direction.y);
564 ray_direction /= d_magnitude(ray_direction);
568 prd.strength = 1.f / float(launch_dim.x);
570 prd.origin_UUID = origin_ID;
573 prd.hit_periodic_boundary =
false;
575 ray = optix::make_Ray(ray_origin, ray_direction, camera_ray_type, 1e-5, RT_DEFAULT_MAX);
577 for (
int wrap = 0; wrap < 10; ++wrap) {
578 rtTrace(top_object, ray, prd);
580 if (!prd.hit_periodic_boundary)
583 ray.origin = prd.periodic_hit;
584 prd.hit_periodic_boundary =
false;
588RT_PROGRAM
void pixel_label_raygen() {
590 uint indx = launch_dim.y * launch_index.z + launch_index.y;
592 optix::int2 camera_resolution = optix::make_int2(launch_dim.y, launch_dim.z);
595 prd.seed = tea<16>(indx, random_seed);
599 uint ii = launch_index.y;
601 uint jj = launch_index.z;
603 size_t origin_ID = jj * launch_dim.y + ii;
609 float multiplier = 1.0f / FOV_aspect_ratio;
610 sp.y = (-0.5f + (ii + 0.5f) /
float(camera_resolution.x));
611 sp.z = (0.5f - (jj + 0.5f) /
float(camera_resolution.y)) * multiplier;
612 sp.x = camera_viewplane_length;
617 float3 p = make_float3(camera_focal_length, sp.y / camera_viewplane_length * camera_focal_length, sp.z / camera_viewplane_length * camera_focal_length);
621 float3 ray_origin = make_float3(0, 0, 0);
625 float3 ray_direction = p;
629 ray_origin = d_rotatePoint(ray_origin, -0.5 *
M_PI + camera_direction.x, 0.5f *
M_PI - camera_direction.y) + camera_position;
631 ray_direction = d_rotatePoint(ray_direction, -0.5 *
M_PI + camera_direction.x, 0.5f *
M_PI - camera_direction.y);
632 ray_direction /= d_magnitude(ray_direction);
638 prd.origin_UUID = origin_ID;
641 prd.hit_periodic_boundary =
false;
643 ray = optix::make_Ray(ray_origin, ray_direction, pixel_label_ray_type, 1e-5, RT_DEFAULT_MAX);
645 for (
int wrap = 0; wrap < 10; ++wrap) {
646 rtTrace(top_object, ray, prd);
648 if (!prd.hit_periodic_boundary)
651 ray.origin = prd.periodic_hit;
652 prd.hit_periodic_boundary =
false;