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];
71 if (ID >= 0 && primitive_solid_fraction[objID] > 0.f && primitive_solid_fraction[objID] < 1.f) {
73 d_sampleTexture_patch(sp, optix::make_int2(ii, jj), optix::make_float2(dx, dy), prd, ID, puvID);
77 float3 v0 = make_float3(0, 0, 0);
78 d_transformPoint(m_trans, v0);
79 float3 v1 = make_float3(1, 0, 0);
80 d_transformPoint(m_trans, v1);
81 float3 v2 = make_float3(0, 1, 0);
82 d_transformPoint(m_trans, v2);
84 normal = normalize(
cross(v1 - v0, v2 - v0));
86 }
else if (ptype == 1) {
99 float3 v0 = make_float3(0, 0, 0);
100 d_transformPoint(m_trans, v0);
101 float3 v1 = make_float3(0, 1, 0);
102 d_transformPoint(m_trans, v1);
103 float3 v2 = make_float3(1, 1, 0);
104 d_transformPoint(m_trans, v2);
106 normal = normalize(
cross(v1 - v0, v2 - v0));
108 int ID = maskID[objID];
110 if (ID >= 0 && primitive_solid_fraction[objID] > 0.f && primitive_solid_fraction[objID] < 1.f) {
112 d_sampleTexture_triangle(sp, v0, v1, v2, prd, m_trans, ID, puvID);
115 }
else if (ptype == 2) {
117 d_sampleDisk(prd.seed, sp);
120 float3 v0 = make_float3(0, 0, 0);
121 d_transformPoint(m_trans, v0);
122 float3 v1 = make_float3(1, 0, 0);
123 d_transformPoint(m_trans, v1);
124 float3 v2 = make_float3(0, 1, 0);
125 d_transformPoint(m_trans, v2);
127 normal = normalize(
cross(v1 - v0, v2 - v0));
129 }
else if (ptype == 4) {
131 float Rz = rnd(prd.seed);
136 float3 ray_origin = sp;
137 d_transformPoint(m_trans, ray_origin);
140 for (
int rr = 0; rr < Nsources; rr++) {
143 float3 ray_direction;
145 if (source_types[rr] == 0) {
146 ray_direction = normalize(source_positions[rr]);
147 ray_magnitude = RT_DEFAULT_MAX;
148 prd.strength = 1. / double(launch_dim.x * launch_dim.y) * fabs(dot(normal, ray_direction));
149 }
else if (source_types[rr] == 1 || source_types[rr] == 2) {
152 float theta_s =
acos_safe(1.f - 2.f * rnd(prd.seed));
153 float phi_s = rnd(prd.seed) * 2.f *
M_PI;
154 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));
156 ray_direction = sphere_point + source_positions[rr] - ray_origin;
158 ray_magnitude = d_magnitude(ray_direction);
159 ray_direction = normalize(ray_direction);
162 for (
uint j = 0; j < N; j++) {
163 for (
uint i = 0; i < N; i++) {
164 float theta =
acos_safe(1.f - 2.f * (
float(i) + 0.5f) /
float(N));
165 float phi = (float(j) + 0.5f) * 2.f *
M_PI /
float(N);
166 float3 light_direction = make_float3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
167 if (dot(light_direction, ray_direction) < 0) {
169 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;
174 }
else if (source_types[rr] == 3) {
177 float light_transform[16];
178 d_makeTransformMatrix(source_rotations[rr], light_transform);
182 d_sampleSquare(prd.seed, square_point);
183 square_point = make_float3(source_widths[rr].x * square_point.x, source_widths[rr].y * square_point.y, square_point.z);
184 d_transformPoint(light_transform, square_point);
186 float3 light_direction = make_float3(0, 0, 1);
187 d_transformPoint(light_transform, light_direction);
189 ray_direction = square_point + source_positions[rr] - ray_origin;
191 if (dot(ray_direction, light_direction) > 0.f) {
195 ray_magnitude = d_magnitude(ray_direction);
196 ray_direction = normalize(ray_direction);
197 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;
199 }
else if (source_types[rr] == 4) {
202 float light_transform[16];
203 d_makeTransformMatrix(source_rotations[rr], light_transform);
207 d_sampleDisk(prd.seed, disk_point);
208 d_transformPoint(light_transform, disk_point);
210 float3 light_direction = make_float3(0, 0, 1);
211 d_transformPoint(light_transform, light_direction);
213 ray_direction = source_widths[rr].x * disk_point + source_positions[rr] - ray_origin;
215 if (dot(ray_direction, light_direction) > 0.f) {
219 ray_magnitude = d_magnitude(ray_direction);
220 ray_direction = normalize(ray_direction);
221 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;
224 optix::Ray ray = optix::make_Ray(ray_origin, ray_direction, direct_ray_type, 1e-4, ray_magnitude);
226 prd.origin_UUID = UUID;
228 prd.hit_periodic_boundary =
false;
230 if (dot(ray_direction, normal) > 0) {
236 if ((prd.face == 1 || twosided_flag[objID] == 1) && twosided_flag[objID] != 3) {
238 for (
int wrap = 0; wrap < 10; ++wrap) {
239 rtTrace(top_object, ray, prd);
241 if (!prd.hit_periodic_boundary)
244 ray.origin = prd.periodic_hit;
245 prd.hit_periodic_boundary =
false;
253RT_PROGRAM
void diffuse_raygen() {
255 uint dimx = launch_dim.x * launch_dim.y;
256 uint indx = launch_dim.x * launch_index.y + launch_index.x;
259 prd.seed = tea<16>(indx + dimx * launch_index.z, random_seed);
261 uint objID = launch_offset + launch_index.z;
263 if (launch_face == 0 && twosided_flag[objID] == 0) {
267 uint pID = primitiveID[objID];
268 uint ptype = primitive_type[objID];
269 int puvID = uvID[objID];
273 for (
uint i = 0; i < 16; i++) {
274 m_trans[i] = transform_matrix[optix::make_uint2(i, objID)];
280 int NX = object_subdivisions[objID].x;
281 int NY = object_subdivisions[objID].y;
282 for (
int jj = 0; jj < NY; jj++) {
283 for (
int ii = 0; ii < NX; ii++) {
285 uint UUID = pID + jj * NX + ii;
288 float Rx = rnd(prd.seed);
289 float Ry = rnd(prd.seed);
291 if (ptype == 0 || ptype == 3) {
294 float3 s0 = make_float3(0, 0, 0);
295 float3 s1 = make_float3(1, 0, 0);
296 float3 s2 = make_float3(0, 1, 0);
297 d_transformPoint(m_trans, s0);
298 d_transformPoint(m_trans, s1);
299 d_transformPoint(m_trans, s2);
301 normal = normalize(
cross(s1 - s0, s2 - s0));
303 float dx = 1.f / float(NX);
304 float dy = 1.f / float(NY);
307 sp.x = -0.5f + (ii + Rx) * dx;
308 sp.y = -0.5f + (jj + Ry) * dy;
311 int ID = maskID[objID];
314 d_sampleTexture_patch(sp, optix::make_int2(ii, jj), optix::make_float2(dx, dy), prd, ID, puvID);
317 }
else if (ptype == 1) {
330 float3 v0 = make_float3(0, 0, 0);
331 d_transformPoint(m_trans, v0);
332 float3 v1 = make_float3(0, 1, 0);
333 d_transformPoint(m_trans, v1);
334 float3 v2 = make_float3(1, 1, 0);
335 d_transformPoint(m_trans, v2);
337 normal = normalize(
cross(v1 - v0, v2 - v0));
339 int ID = maskID[objID];
342 d_sampleTexture_triangle(sp, v0, v1, v2, prd, m_trans, ID, puvID);
345 }
else if (ptype == 2) {
350 sp.x = -1.f + 2.f * Rx;
351 sp.y = -1.f + 2.f * Ry;
360 p = 2.f - sp.x / sp.y;
365 p = 4.f + sp.y / sp.x;
369 p = 6.f - sp.x / sp.y;
383 float3 v0 = make_float3(0, 0, 0);
384 d_transformPoint(m_trans, v0);
385 float3 v1 = make_float3(1, 0, 0);
386 d_transformPoint(m_trans, v1);
387 float3 v2 = make_float3(0, 1, 0);
388 d_transformPoint(m_trans, v2);
389 normal = normalize(
cross(v1 - v0, v2 - v0));
391 }
else if (ptype == 4) {
396 sp.z = -0.5f + rnd(prd.seed);
404 Rt = (launch_index.x + rnd(prd.seed)) /
float(launch_dim.x);
405 Rp = (launch_index.y + rnd(prd.seed)) /
float(launch_dim.y);
413 float p = 2.f *
M_PI * Rp;
415 float3 ray_direction;
416 ray_direction.x = sin(t) * cos(p);
417 ray_direction.y = sin(t) * sin(p);
418 ray_direction.z = cos(t);
425 prd.strength = 0.5f / float(dimx);
426 prd.origin_UUID = UUID;
429 prd.hit_periodic_boundary =
false;
432 d_transformPoint(m_trans, ray_origin);
434 ray = optix::make_Ray(ray_origin, ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
435 rtTrace(top_object, ray, prd);
437 ray = optix::make_Ray(ray_origin, -ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
438 rtTrace(top_object, ray, prd);
442 ray_direction = d_rotatePoint(ray_direction,
acos_safe(normal.z), atan2(normal.y, normal.x));
444 prd.strength = 1.f / float(dimx);
446 prd.origin_UUID = UUID;
448 prd.hit_periodic_boundary =
false;
452 d_transformPoint(m_trans, ray_origin);
454 if (launch_face == 1 && twosided_flag[objID] != 3) {
456 ray = optix::make_Ray(ray_origin, ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
460 for (
int wrap = 0; wrap < 10; ++wrap) {
461 rtTrace(top_object, ray, prd);
463 if (!prd.hit_periodic_boundary)
466 ray.origin = prd.periodic_hit;
467 prd.hit_periodic_boundary =
false;
471 }
else if (launch_face == 0 && twosided_flag[objID] == 1) {
473 ray_direction = -ray_direction;
474 ray = optix::make_Ray(ray_origin, ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
478 for (
int wrap = 0; wrap < 10; ++wrap) {
479 rtTrace(top_object, ray, prd);
481 if (!prd.hit_periodic_boundary)
484 ray.origin = prd.periodic_hit;
485 prd.hit_periodic_boundary =
false;
494RT_PROGRAM
void camera_raygen() {
496 uint dimx = launch_dim.x * launch_dim.y;
497 uint indx = launch_dim.x * launch_index.y + launch_index.x;
500 optix::int2 camera_resolution = camera_resolution_full;
503 prd.seed = tea<16>(indx + dimx * launch_index.z, random_seed);
508 uint ii = camera_pixel_offset_x + launch_index.y;
509 uint jj = camera_pixel_offset_y + launch_index.z;
510 size_t origin_ID = jj * camera_resolution_full.x + ii;
529 float PPointsRatiox = 1.f;
530 float PPointsRatioy = 1.f;
531 float Rx = rnd(prd.seed);
532 float Ry = rnd(prd.seed);
538 float multiplier = 1.0f / FOV_aspect_ratio;
539 sp.y = (-0.5f * PPointsRatioy + (ii + Rx) /
float(camera_resolution.x));
540 sp.z = (0.5f * PPointsRatiox - (jj + Ry) /
float(camera_resolution.y)) * multiplier;
541 sp.x = camera_viewplane_length;
546 float3 p = make_float3(camera_focal_length, sp.y / camera_viewplane_length * camera_focal_length, sp.z / camera_viewplane_length * camera_focal_length);
550 float3 ray_origin = make_float3(0, 0, 0);
551 if (camera_lens_diameter > 0) {
553 d_sampleDisk(prd.seed, disk_sample);
554 ray_origin = make_float3(0.f, 0.5f * disk_sample.x * camera_lens_diameter, 0.5f * disk_sample.y * camera_lens_diameter);
559 float3 ray_direction = p - ray_origin;
563 ray_origin = d_rotatePoint(ray_origin, -0.5 *
M_PI + camera_direction.x, 0.5f *
M_PI - camera_direction.y) + camera_position;
565 ray_direction = d_rotatePoint(ray_direction, -0.5 *
M_PI + camera_direction.x, 0.5f *
M_PI - camera_direction.y);
566 ray_direction /= d_magnitude(ray_direction);
570 prd.strength = 1.f / float(launch_dim.x);
572 prd.origin_UUID = origin_ID;
575 prd.hit_periodic_boundary =
false;
577 ray = optix::make_Ray(ray_origin, ray_direction, camera_ray_type, 1e-5, RT_DEFAULT_MAX);
579 for (
int wrap = 0; wrap < 10; ++wrap) {
580 rtTrace(top_object, ray, prd);
582 if (!prd.hit_periodic_boundary)
585 ray.origin = prd.periodic_hit;
586 prd.hit_periodic_boundary =
false;
590RT_PROGRAM
void pixel_label_raygen() {
592 uint indx = launch_dim.y * launch_index.z + launch_index.y;
595 optix::int2 camera_resolution = camera_resolution_full;
598 prd.seed = tea<16>(indx, random_seed);
603 uint ii = camera_pixel_offset_x + launch_index.y;
605 uint jj = camera_pixel_offset_y + launch_index.z;
607 size_t origin_ID = jj * camera_resolution_full.x + ii;
613 float multiplier = 1.0f / FOV_aspect_ratio;
614 sp.y = (-0.5f + (ii + 0.5f) /
float(camera_resolution.x));
615 sp.z = (0.5f - (jj + 0.5f) /
float(camera_resolution.y)) * multiplier;
616 sp.x = camera_viewplane_length;
622 float3 p = make_float3(camera_focal_length, sp.y / camera_viewplane_length * camera_focal_length, sp.z / camera_viewplane_length * camera_focal_length);
626 float3 ray_origin = make_float3(0, 0, 0);
630 float3 ray_direction = p;
634 ray_origin = d_rotatePoint(ray_origin, -0.5 *
M_PI + camera_direction.x, 0.5f *
M_PI - camera_direction.y) + camera_position;
636 ray_direction = d_rotatePoint(ray_direction, -0.5 *
M_PI + camera_direction.x, 0.5f *
M_PI - camera_direction.y);
637 ray_direction /= d_magnitude(ray_direction);
643 prd.origin_UUID = origin_ID;
646 prd.hit_periodic_boundary =
false;
648 ray = optix::make_Ray(ray_origin, ray_direction, pixel_label_ray_type, 1e-5, RT_DEFAULT_MAX);
650 for (
int wrap = 0; wrap < 10; ++wrap) {
651 rtTrace(top_object, ray, prd);
653 if (!prd.hit_periodic_boundary)
656 ray.origin = prd.periodic_hit;
657 prd.hit_periodic_boundary =
false;