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) {
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);
228 prd.hit_periodic_boundary =
false;
229 initCoverTransmittance(prd);
231 if (dot(ray_direction, normal) > 0) {
237 if ((prd.
face == 1 || twosided_flag[objID] == 1) && twosided_flag[objID] != 3) {
239 for (
int wrap = 0; wrap < 10; ++wrap) {
240 rtTrace(top_object, ray, prd);
242 if (!prd.hit_periodic_boundary)
246 prd.hit_periodic_boundary =
false;
254RT_PROGRAM
void diffuse_raygen() {
256 uint dimx = launch_dim.x * launch_dim.y;
257 uint indx = launch_dim.x * launch_index.y + launch_index.x;
260 prd.
seed = tea<16>(indx + dimx * launch_index.z, random_seed);
262 uint objID = launch_offset + launch_index.z;
264 if (launch_face == 0 && twosided_flag[objID] == 0) {
268 uint pID = primitiveID[objID];
269 uint ptype = primitive_type[objID];
270 int puvID = uvID[objID];
274 for (
uint i = 0; i < 16; i++) {
275 m_trans[i] = transform_matrix[optix::make_uint2(i, objID)];
281 int NX = object_subdivisions[objID].x;
282 int NY = object_subdivisions[objID].y;
283 for (
int jj = 0; jj < NY; jj++) {
284 for (
int ii = 0; ii < NX; ii++) {
286 uint UUID = pID + jj * NX + ii;
289 float Rx = rnd(prd.
seed);
290 float Ry = rnd(prd.
seed);
292 if (ptype == 0 || ptype == 3) {
295 float3 s0 = make_float3(0, 0, 0);
296 float3 s1 = make_float3(1, 0, 0);
297 float3 s2 = make_float3(0, 1, 0);
298 d_transformPoint(m_trans, s0);
299 d_transformPoint(m_trans, s1);
300 d_transformPoint(m_trans, s2);
302 normal = normalize(
cross(s1 - s0, s2 - s0));
304 float dx = 1.f / float(NX);
305 float dy = 1.f / float(NY);
308 sp.x = -0.5f + (ii + Rx) * dx;
309 sp.y = -0.5f + (jj + Ry) * dy;
312 int ID = maskID[objID];
315 d_sampleTexture_patch(sp, optix::make_int2(ii, jj), optix::make_float2(dx, dy), prd, ID, puvID);
318 }
else if (ptype == 1) {
331 float3 v0 = make_float3(0, 0, 0);
332 d_transformPoint(m_trans, v0);
333 float3 v1 = make_float3(0, 1, 0);
334 d_transformPoint(m_trans, v1);
335 float3 v2 = make_float3(1, 1, 0);
336 d_transformPoint(m_trans, v2);
338 normal = normalize(
cross(v1 - v0, v2 - v0));
340 int ID = maskID[objID];
343 d_sampleTexture_triangle(sp, v0, v1, v2, prd, m_trans, ID, puvID);
346 }
else if (ptype == 2) {
351 sp.x = -1.f + 2.f * Rx;
352 sp.y = -1.f + 2.f * Ry;
361 p = 2.f - sp.x / sp.y;
366 p = 4.f + sp.y / sp.x;
370 p = 6.f - sp.x / sp.y;
384 float3 v0 = make_float3(0, 0, 0);
385 d_transformPoint(m_trans, v0);
386 float3 v1 = make_float3(1, 0, 0);
387 d_transformPoint(m_trans, v1);
388 float3 v2 = make_float3(0, 1, 0);
389 d_transformPoint(m_trans, v2);
390 normal = normalize(
cross(v1 - v0, v2 - v0));
392 }
else if (ptype == 4) {
397 sp.z = -0.5f + rnd(prd.
seed);
405 Rt = (launch_index.x + rnd(prd.
seed)) /
float(launch_dim.x);
406 Rp = (launch_index.y + rnd(prd.
seed)) /
float(launch_dim.y);
414 float p = 2.f *
M_PI * Rp;
416 float3 ray_direction;
417 ray_direction.x = sin(t) * cos(p);
418 ray_direction.y = sin(t) * sin(p);
419 ray_direction.z = cos(t);
430 prd.hit_periodic_boundary =
false;
433 d_transformPoint(m_trans, ray_origin);
435 ray = optix::make_Ray(ray_origin, ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
436 initCoverTransmittance(prd);
437 rtTrace(top_object, ray, prd);
439 ray = optix::make_Ray(ray_origin, -ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
440 initCoverTransmittance(prd);
441 rtTrace(top_object, ray, prd);
445 ray_direction = d_rotatePoint(ray_direction,
acos_safe(normal.z), atan2(normal.y, normal.x));
451 prd.hit_periodic_boundary =
false;
452 initCoverTransmittance(prd);
456 d_transformPoint(m_trans, ray_origin);
458 if (launch_face == 1 && twosided_flag[objID] != 3) {
460 ray = optix::make_Ray(ray_origin, ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
464 for (
int wrap = 0; wrap < 10; ++wrap) {
465 rtTrace(top_object, ray, prd);
467 if (!prd.hit_periodic_boundary)
471 prd.hit_periodic_boundary =
false;
475 }
else if (launch_face == 0 && twosided_flag[objID] == 1) {
477 ray_direction = -ray_direction;
478 ray = optix::make_Ray(ray_origin, ray_direction, diffuse_ray_type, 1e-5, RT_DEFAULT_MAX);
482 for (
int wrap = 0; wrap < 10; ++wrap) {
483 rtTrace(top_object, ray, prd);
485 if (!prd.hit_periodic_boundary)
489 prd.hit_periodic_boundary =
false;
498RT_PROGRAM
void camera_raygen() {
500 uint dimx = launch_dim.x * launch_dim.y;
501 uint indx = launch_dim.x * launch_index.y + launch_index.x;
504 optix::int2 camera_resolution = camera_resolution_full;
507 prd.
seed = tea<16>(indx + dimx * launch_index.z, random_seed);
512 uint ii = camera_pixel_offset_x + launch_index.y;
513 uint jj = camera_pixel_offset_y + launch_index.z;
514 size_t origin_ID = jj * camera_resolution_full.x + ii;
533 float PPointsRatiox = 1.f;
534 float PPointsRatioy = 1.f;
535 float Rx = rnd(prd.
seed);
536 float Ry = rnd(prd.
seed);
542 float multiplier = 1.0f / FOV_aspect_ratio;
543 sp.y = (-0.5f * PPointsRatioy + (ii + Rx) /
float(camera_resolution.x));
544 sp.z = (0.5f * PPointsRatiox - (jj + Ry) /
float(camera_resolution.y)) * multiplier;
545 sp.x = camera_viewplane_length;
550 float3 p = make_float3(camera_focal_length, sp.y / camera_viewplane_length * camera_focal_length, sp.z / camera_viewplane_length * camera_focal_length);
554 float3 ray_origin = make_float3(0, 0, 0);
555 if (camera_lens_diameter > 0) {
557 d_sampleDisk(prd.
seed, disk_sample);
558 ray_origin = make_float3(0.f, 0.5f * disk_sample.x * camera_lens_diameter, 0.5f * disk_sample.y * camera_lens_diameter);
563 float3 ray_direction = p - ray_origin;
567 ray_origin = d_rotatePoint(ray_origin, -0.5 * M_PI + camera_direction.x, 0.5f * M_PI - camera_direction.y) + camera_position;
569 ray_direction = d_rotatePoint(ray_direction, -0.5 * M_PI + camera_direction.x, 0.5f * M_PI - camera_direction.y);
570 ray_direction /= d_magnitude(ray_direction);
574 prd.
strength = 1.f / float(launch_dim.x);
579 prd.hit_periodic_boundary =
false;
581 ray = optix::make_Ray(ray_origin, ray_direction, camera_ray_type, 1e-5, RT_DEFAULT_MAX);
583 for (
int wrap = 0; wrap < 10; ++wrap) {
584 rtTrace(top_object, ray, prd);
586 if (!prd.hit_periodic_boundary)
590 prd.hit_periodic_boundary =
false;
594RT_PROGRAM
void pixel_label_raygen() {
596 uint indx = launch_dim.y * launch_index.z + launch_index.y;
599 optix::int2 camera_resolution = camera_resolution_full;
602 prd.
seed = tea<16>(indx, random_seed);
607 uint ii = camera_pixel_offset_x + launch_index.y;
609 uint jj = camera_pixel_offset_y + launch_index.z;
611 size_t origin_ID = jj * camera_resolution_full.x + ii;
617 float multiplier = 1.0f / FOV_aspect_ratio;
618 sp.y = (-0.5f + (ii + 0.5f) /
float(camera_resolution.x));
619 sp.z = (0.5f - (jj + 0.5f) /
float(camera_resolution.y)) * multiplier;
620 sp.x = camera_viewplane_length;
626 float3 p = make_float3(camera_focal_length, sp.y / camera_viewplane_length * camera_focal_length, sp.z / camera_viewplane_length * camera_focal_length);
630 float3 ray_origin = make_float3(0, 0, 0);
634 float3 ray_direction = p;
638 ray_origin = d_rotatePoint(ray_origin, -0.5 * M_PI + camera_direction.x, 0.5f * M_PI - camera_direction.y) + camera_position;
640 ray_direction = d_rotatePoint(ray_direction, -0.5 * M_PI + camera_direction.x, 0.5f * M_PI - camera_direction.y);
641 ray_direction /= d_magnitude(ray_direction);
650 prd.hit_periodic_boundary =
false;
652 ray = optix::make_Ray(ray_origin, ray_direction, pixel_label_ray_type, 1e-5, RT_DEFAULT_MAX);
654 for (
int wrap = 0; wrap < 10; ++wrap) {
655 rtTrace(top_object, ray, prd);
657 if (!prd.hit_periodic_boundary)
661 prd.hit_periodic_boundary =
false;