17#include <optix_world.h>
18#include <optixu/optixu_math_namespace.h>
19#include <optixu/optixu_matrix_namespace.h>
21#include "RayTracing.cuh"
25rtDeclareVariable(optix::Ray, ray, rtCurrentRay, );
26rtDeclareVariable(
float, t_hit, rtIntersectionDistance, );
27rtDeclareVariable(PerRayData, prd, rtPayload, );
29rtDeclareVariable(
unsigned int, UUID, attribute UUID, );
31RT_PROGRAM
void closest_hit_direct() {
33 uint objID = objectID[UUID];
35 if ((periodic_flag.x == 1 || periodic_flag.y == 1) && primitive_type[objID] == 5) {
37 prd.hit_periodic_boundary =
true;
39 float3 ray_origin = ray.origin + t_hit * ray.direction;
43 float2 xbounds = make_float2(bbox_vertices[
make_uint2(0, 0)].x, bbox_vertices[
make_uint2(1, 1)].x);
44 float2 ybounds = make_float2(bbox_vertices[
make_uint2(0, 0)].y, bbox_vertices[
make_uint2(1, 1)].y);
46 float width_x = xbounds.y - xbounds.x;
47 float width_y = ybounds.y - ybounds.x;
49 prd.periodic_hit = ray_origin;
50 if (periodic_flag.x == 1 && fabs(ray_origin.x - xbounds.x) <= eps) {
51 prd.periodic_hit.x += +width_x - eps;
52 }
else if (periodic_flag.x == 1 && fabs(ray_origin.x - xbounds.y) <= eps) {
53 prd.periodic_hit.x += -width_x + eps;
54 }
else if (periodic_flag.y == 1 && fabs(ray_origin.y - ybounds.x) <= eps) {
55 prd.periodic_hit.y += +width_y - eps;
56 }
else if (periodic_flag.y == 1 && fabs(ray_origin.y - ybounds.y) <= eps) {
57 prd.periodic_hit.y += -width_y + eps;
62RT_PROGRAM
void closest_hit_diffuse() {
64 uint origin_UUID = prd.origin_UUID;
66 uint objID = objectID[UUID];
68 if ((periodic_flag.x == 1 || periodic_flag.y == 1) && primitive_type[objID] == 5) {
70 prd.hit_periodic_boundary =
true;
72 float3 ray_origin = ray.origin + t_hit * ray.direction;
76 float2 xbounds = make_float2(bbox_vertices[
make_uint2(0, 0)].x, bbox_vertices[
make_uint2(1, 1)].x);
77 float2 ybounds = make_float2(bbox_vertices[
make_uint2(0, 0)].y, bbox_vertices[
make_uint2(1, 1)].y);
79 float width_x = xbounds.y - xbounds.x;
80 float width_y = ybounds.y - ybounds.x;
82 prd.periodic_hit = ray_origin;
83 if (periodic_flag.x == 1 && fabs(ray_origin.x - xbounds.x) <= eps) {
84 prd.periodic_hit.x += +width_x - eps;
85 }
else if (periodic_flag.x == 1 && fabs(ray_origin.x - xbounds.y) <= eps) {
86 prd.periodic_hit.x += -width_x + eps;
87 }
else if (periodic_flag.y == 1 && fabs(ray_origin.y - ybounds.x) <= eps) {
88 prd.periodic_hit.y += +width_y - eps;
89 }
else if (periodic_flag.y == 1 && fabs(ray_origin.y - ybounds.y) <= eps) {
90 prd.periodic_hit.y += -width_y + eps;
101 for (
uint i = 0; i < 16; i++) {
102 m[i] = transform_matrix[optix::make_uint2(i, objID)];
105 if (primitive_type[objID] == 0 || primitive_type[objID] == 3) {
106 float3 s0 = make_float3(0, 0, 0);
107 float3 s1 = make_float3(1, 0, 0);
108 float3 s2 = make_float3(0, 1, 0);
109 d_transformPoint(m, s0);
110 d_transformPoint(m, s1);
111 d_transformPoint(m, s2);
112 normal =
cross(s1 - s0, s2 - s0);
113 }
else if (primitive_type[UUID] == 1) {
114 float3 v0 = make_float3(0, 0, 0);
115 d_transformPoint(m, v0);
116 float3 v1 = make_float3(0, 1, 0);
117 d_transformPoint(m, v1);
118 float3 v2 = make_float3(1, 1, 0);
119 d_transformPoint(m, v2);
120 normal =
cross(v1 - v0, v2 - v1);
121 }
else if (primitive_type[UUID] == 2) {
122 float3 v0 = make_float3(0, 0, 0);
123 d_transformPoint(m, v0);
124 float3 v1 = make_float3(1, 0, 0);
125 d_transformPoint(m, v1);
126 float3 v2 = make_float3(0, 1, 0);
127 d_transformPoint(m, v2);
128 normal =
cross(v1 - v0, v2 - v0);
129 }
else if (primitive_type[UUID] == 4) {
130 float3 vmin = make_float3(-0.5, -0.5, -0.5);
131 d_transformPoint(m, vmin);
132 float3 vmax = make_float3(0.5, 0.5, 0.5);
133 d_transformPoint(m, vmax);
135 normal = normalize(normal);
137 bool face = dot(normal, ray.direction) < 0;
140 for (
int b_global = 0; b_global < Nbands_global; b_global++) {
142 if (band_launch_flag[b_global] == 0) {
147 size_t ind_origin = Nbands_launch * origin_UUID + b;
148 size_t ind_hit = Nbands_launch * UUID + b;
151 if (face || primitive_type[objID] == 4) {
152 strength = radiation_out_top[ind_hit] * prd.strength;
154 strength = radiation_out_bottom[ind_hit] * prd.strength;
161 size_t radprop_ind_global = Nprimitives * Nbands_global * prd.source_ID + Nbands_global * origin_UUID + b_global;
162 float t_rho = rho[radprop_ind_global];
163 float t_tau = tau[radprop_ind_global];
165 if (primitive_type[objectID[origin_UUID]] == 4) {
180 atomicAdd(&radiation_in[ind_origin], strength * (1.f - t_rho - t_tau));
182 if ((t_rho > 0 || t_tau > 0) && strength > 0) {
184 atomicFloatAdd(&scatter_buff_top[ind_origin], strength * t_rho);
185 atomicFloatAdd(&scatter_buff_bottom[ind_origin], strength * t_tau);
187 atomicFloatAdd(&scatter_buff_bottom[ind_origin], strength * t_rho);
188 atomicFloatAdd(&scatter_buff_top[ind_origin], strength * t_tau);
192 size_t indc = prd.source_ID * Nprimitives * Nbands_global * Ncameras + origin_UUID * Nbands_global * Ncameras + b_global * Ncameras + camera_ID;
193 float t_rho_cam = rho_cam[indc];
194 float t_tau_cam = tau_cam[indc];
195 if ((t_rho_cam > 0 || t_tau_cam > 0) && strength > 0) {
197 atomicFloatAdd(&scatter_buff_top_cam[ind_origin], strength * t_rho_cam);
198 atomicFloatAdd(&scatter_buff_bottom_cam[ind_origin], strength * t_tau_cam);
200 atomicFloatAdd(&scatter_buff_bottom_cam[ind_origin], strength * t_rho_cam);
201 atomicFloatAdd(&scatter_buff_top_cam[ind_origin], strength * t_tau_cam);
218RT_PROGRAM
void closest_hit_camera() {
220 uint objID = objectID[UUID];
222 if ((periodic_flag.x == 1 || periodic_flag.y == 1) && primitive_type[objID] == 5) {
224 prd.hit_periodic_boundary =
true;
226 float3 ray_origin = ray.origin + t_hit * ray.direction;
230 float2 xbounds = make_float2(bbox_vertices[
make_uint2(0, 0)].x, bbox_vertices[
make_uint2(1, 1)].x);
231 float2 ybounds = make_float2(bbox_vertices[
make_uint2(0, 0)].y, bbox_vertices[
make_uint2(1, 1)].y);
233 float width_x = xbounds.y - xbounds.x;
234 float width_y = ybounds.y - ybounds.x;
236 prd.periodic_hit = ray_origin;
237 if (periodic_flag.x == 1 && fabs(ray_origin.x - xbounds.x) <= eps) {
238 prd.periodic_hit.x += +width_x - eps;
239 }
else if (periodic_flag.x == 1 && fabs(ray_origin.x - xbounds.y) <= eps) {
240 prd.periodic_hit.x += -width_x + eps;
241 }
else if (periodic_flag.y == 1 && fabs(ray_origin.y - ybounds.x) <= eps) {
242 prd.periodic_hit.y += +width_y - eps;
243 }
else if (periodic_flag.y == 1 && fabs(ray_origin.y - ybounds.y) <= eps) {
244 prd.periodic_hit.y += -width_y + eps;
255 for (
uint i = 0; i < 16; i++) {
256 m[i] = transform_matrix[optix::make_uint2(i, objID)];
259 if (primitive_type[objID] == 0 || primitive_type[objID] == 3) {
260 float3 s0 = make_float3(0, 0, 0);
261 float3 s1 = make_float3(1, 0, 0);
262 float3 s2 = make_float3(0, 1, 0);
263 d_transformPoint(m, s0);
264 d_transformPoint(m, s1);
265 d_transformPoint(m, s2);
266 normal =
cross(s1 - s0, s2 - s0);
267 }
else if (primitive_type[UUID] == 1) {
268 float3 v0 = make_float3(0, 0, 0);
269 d_transformPoint(m, v0);
270 float3 v1 = make_float3(0, 1, 0);
271 d_transformPoint(m, v1);
272 float3 v2 = make_float3(1, 1, 0);
273 d_transformPoint(m, v2);
274 normal =
cross(v1 - v0, v2 - v1);
275 }
else if (primitive_type[UUID] == 2) {
276 float3 v0 = make_float3(0, 0, 0);
277 d_transformPoint(m, v0);
278 float3 v1 = make_float3(1, 0, 0);
279 d_transformPoint(m, v1);
280 float3 v2 = make_float3(0, 1, 0);
281 d_transformPoint(m, v2);
282 normal =
cross(v1 - v0, v2 - v0);
283 }
else if (primitive_type[UUID] == 4) {
284 float3 vmin = make_float3(-0.5, -0.5, -0.5);
285 d_transformPoint(m, vmin);
286 float3 vmax = make_float3(0.5, 0.5, 0.5);
287 d_transformPoint(m, vmax);
289 normal = normalize(normal);
291 bool face = dot(normal, ray.direction) < 0;
294 float3 camera_normal = d_rotatePoint(make_float3(0, 0, 1), -0.5 *
M_PI + camera_direction.x, 0.5f *
M_PI - camera_direction.y);
297 for (
size_t b = 0; b < Nbands_launch; b++) {
299 if (face || primitive_type[objID] == 4) {
300 strength = radiation_out_top[Nbands_launch * UUID + b] * prd.strength;
302 strength = radiation_out_bottom[Nbands_launch * UUID + b] * prd.strength;
307 double strength_spec = 0;
308 if (specular_reflection_enabled > 0 && specular_exponent[objID] > 0.f) {
309 for (
int rr = 0; rr < Nsources; rr++) {
312 float3 light_direction;
314 if (source_types[rr] == 0 || source_types[rr] == 2) {
316 light_direction = normalize(source_positions[rr]);
318 spec = radiation_out_top[Nbands_launch * UUID + b];
320 spec = radiation_out_bottom[Nbands_launch * UUID + b];
328 float3 specular_direction = normalize(light_direction - ray.direction);
331 float exponent = specular_exponent[objID];
332 double scale_coefficient = 1.0;
333 if (specular_reflection_enabled == 2) {
334 scale_coefficient = specular_scale[objID];
336 strength_spec += spec * scale_coefficient * pow(
max(0.f, dot(specular_direction, normal)), exponent) * (exponent + 2.f) /
337 (
double(launch_dim.x) * 2.f *
M_PI);
343 atomicAdd(&radiation_in_camera[Nbands_launch * prd.origin_UUID + b], strength + strength_spec);
348RT_PROGRAM
void closest_hit_pixel_label() {
350 uint origin_UUID = prd.origin_UUID;
352 uint objID = objectID[UUID];
354 if ((periodic_flag.x == 1 || periodic_flag.y == 1) && primitive_type[objID] == 5) {
356 prd.hit_periodic_boundary =
true;
358 float3 ray_origin = ray.origin + t_hit * ray.direction;
362 float2 xbounds = make_float2(bbox_vertices[
make_uint2(0, 0)].x, bbox_vertices[
make_uint2(1, 1)].x);
363 float2 ybounds = make_float2(bbox_vertices[
make_uint2(0, 0)].y, bbox_vertices[
make_uint2(1, 1)].y);
365 float width_x = xbounds.y - xbounds.x;
366 float width_y = ybounds.y - ybounds.x;
368 prd.periodic_hit = ray_origin;
369 if (periodic_flag.x == 1 && fabs(ray_origin.x - xbounds.x) <= eps) {
370 prd.periodic_hit.x += +width_x - eps;
371 }
else if (periodic_flag.x == 1 && fabs(ray_origin.x - xbounds.y) <= eps) {
372 prd.periodic_hit.x += -width_x + eps;
373 }
else if (periodic_flag.y == 1 && fabs(ray_origin.y - ybounds.x) <= eps) {
374 prd.periodic_hit.y += +width_y - eps;
375 }
else if (periodic_flag.y == 1 && fabs(ray_origin.y - ybounds.y) <= eps) {
376 prd.periodic_hit.y += -width_y + eps;
383 camera_pixel_label[origin_UUID] = UUID + 1;
385 float depth = prd.strength + t_hit;
386 float3 camera_direction3 = d_rotatePoint(make_float3(1, 0, 0), -0.5 *
M_PI + camera_direction.x, 0.5f *
M_PI - camera_direction.y);
387 camera_pixel_depth[origin_UUID] = abs(dot(camera_direction3, ray.direction)) * depth;
391RT_PROGRAM
void miss_direct() {
393 uint objID = objectID[prd.origin_UUID];
396 for (
int b_global = 0; b_global < Nbands_global; b_global++) {
398 if (band_launch_flag[b_global] == 0) {
403 size_t ind_origin = Nbands_launch * prd.origin_UUID + b;
405 size_t radprop_ind_global = Nprimitives * Nbands_global * prd.source_ID + Nbands_global * prd.origin_UUID + b_global;
406 float t_rho = rho[radprop_ind_global];
407 float t_tau = tau[radprop_ind_global];
409 double strength = prd.strength * source_fluxes[prd.source_ID * Nbands_launch + b];
412 atomicAdd(&radiation_in[ind_origin], strength * (1.f - t_rho - t_tau));
414 if (t_rho > 0 || t_tau > 0) {
416 atomicFloatAdd(&scatter_buff_top[ind_origin], strength * t_rho);
417 atomicFloatAdd(&scatter_buff_bottom[ind_origin], strength * t_tau);
419 atomicFloatAdd(&scatter_buff_bottom[ind_origin], strength * t_rho);
420 atomicFloatAdd(&scatter_buff_top[ind_origin], strength * t_tau);
424 size_t indc = prd.source_ID * Nprimitives * Nbands_global * Ncameras + prd.origin_UUID * Nbands_global * Ncameras + b_global * Ncameras + camera_ID;
425 float t_rho_cam = rho_cam[indc];
426 float t_tau_cam = tau_cam[indc];
427 if ((t_rho_cam > 0 || t_tau_cam > 0) && strength > 0) {
429 atomicFloatAdd(&scatter_buff_top_cam[ind_origin], strength * t_rho_cam);
430 atomicFloatAdd(&scatter_buff_bottom_cam[ind_origin], strength * t_tau_cam);
432 atomicFloatAdd(&scatter_buff_bottom_cam[ind_origin], strength * t_rho_cam);
433 atomicFloatAdd(&scatter_buff_top_cam[ind_origin], strength * t_tau_cam);
440RT_PROGRAM
void miss_diffuse() {
452 for (
size_t b_global = 0; b_global < Nbands_global; b_global++) {
454 if (band_launch_flag[b_global] == 0) {
459 if (diffuse_flux[b] > 0.f) {
461 size_t ind_origin = Nbands_launch * prd.origin_UUID + b;
463 size_t radprop_ind_global = Nprimitives * Nbands_global * prd.source_ID + Nbands_global * prd.origin_UUID + b_global;
464 float t_rho = rho[radprop_ind_global];
465 float t_tau = tau[radprop_ind_global];
467 if (primitive_type[objectID[prd.origin_UUID]] == 4) {
470 float sigma_s = t_tau;
471 float beta = kappa + sigma_s;
474 atomicAdd(&radiation_in[ind_origin], diffuse_flux[b] * prd.strength * kappa / beta);
477 atomicAdd(&scatter_buff_top[ind_origin], diffuse_flux[b] * prd.strength * sigma_s / beta);
482 if (diffuse_extinction[b] > 0.f) {
483 float psi =
acos_safe(dot(diffuse_peak_dir[b], ray.direction));
484 if (psi <
M_PI / 180.f) {
485 fd = powf(
M_PI / 180.f, -diffuse_extinction[b]) * diffuse_dist_norm[b];
487 fd = powf(psi, -diffuse_extinction[b]) * diffuse_dist_norm[b];
491 float strength = fd * diffuse_flux[b] * prd.strength;
494 atomicAdd(&radiation_in[ind_origin], strength * (1.f - t_rho - t_tau));
496 if (t_rho > 0 || t_tau > 0) {
498 atomicFloatAdd(&scatter_buff_top[ind_origin], strength * t_rho);
499 atomicFloatAdd(&scatter_buff_bottom[ind_origin], strength * t_tau);
501 atomicFloatAdd(&scatter_buff_bottom[ind_origin], strength * t_rho);
502 atomicFloatAdd(&scatter_buff_top[ind_origin], strength * t_tau);
506 size_t indc = prd.source_ID * Nprimitives * Nbands_global * Ncameras + prd.origin_UUID * Nbands_global * Ncameras + b_global * Ncameras + camera_ID;
507 float t_rho_cam = rho_cam[indc];
508 float t_tau_cam = tau_cam[indc];
509 if ((t_rho_cam > 0 || t_tau_cam > 0) && prd.strength > 0) {
511 atomicFloatAdd(&scatter_buff_top_cam[ind_origin], strength * t_rho_cam);
512 atomicFloatAdd(&scatter_buff_bottom_cam[ind_origin], strength * t_tau_cam);
514 atomicFloatAdd(&scatter_buff_bottom_cam[ind_origin], strength * t_rho_cam);
515 atomicFloatAdd(&scatter_buff_top_cam[ind_origin], strength * t_tau_cam);
524RT_PROGRAM
void miss_camera() {
526 for (
size_t b = 0; b < Nbands_launch; b++) {
528 if (diffuse_flux[b] > 0.f) {
531 if (diffuse_extinction[b] > 0.f) {
532 float psi =
acos_safe(dot(diffuse_peak_dir[b], ray.direction));
533 if (psi <
M_PI / 180.f) {
534 fd = powf(
float(
M_PI) / 180.f, -diffuse_extinction[b]) * diffuse_dist_norm[b];
536 fd = powf(psi, -diffuse_extinction[b]) * diffuse_dist_norm[b];
541 atomicAdd(&radiation_in_camera[Nbands_launch * prd.origin_UUID + b], fd * diffuse_flux[b] * prd.strength);
546RT_PROGRAM
void miss_pixel_label() {
548 camera_pixel_depth[prd.origin_UUID] = -1;