#ifndef __ALPHA_H__ #define __ALPHA_H__ #include "linalg.h" #include "intersect.h" #include "mesh.h" #include "sorting.h" #include "stdio.h" #define ALPHA_DEPTH 10 __device__ int get_color_alpha(const float3 &origin, const float3& direction, bool &hit, float &distance) { if (!intersect_node(origin, direction, g_start_node, -1.0f)) return 0; unsigned int stack[STACK_SIZE]; unsigned int *head = &stack[0]; unsigned int *node = &stack[1]; unsigned int *tail = &stack[STACK_SIZE-1]; *node = g_start_node; unsigned int i; float distances[ALPHA_DEPTH]; unsigned int indices[ALPHA_DEPTH]; unsigned int n=0; do { unsigned int first_child = tex1Dfetch(node_map, *node); unsigned int stop = tex1Dfetch(node_map_end, *node); while (*node >= g_first_node && stop == first_child+1) { *node = first_child; first_child = tex1Dfetch(node_map, *node); stop = tex1Dfetch(node_map_end, *node); } if (*node >= g_first_node) { for (i=first_child; i < stop; i++) { if (intersect_node(origin, direction, i, -1.0f)) { *node = i; node++; } } node--; } else // node is a leaf { for (i=first_child; i < stop; i++) { uint4 triangle_data = g_triangles[i]; float3 v0 = g_vertices[triangle_data.x]; float3 v1 = g_vertices[triangle_data.y]; float3 v2 = g_vertices[triangle_data.z]; if (intersect_triangle(origin, direction, v0, v1, v2, distance)) { if (n < 1) { distances[0] = distance; indices[0] = i; } else { unsigned long j = searchsorted(n, distances, distance); if (j <= ALPHA_DEPTH-1) { insert(ALPHA_DEPTH, distances, j, distance); insert(ALPHA_DEPTH, indices, j, i); } } if (n < ALPHA_DEPTH) n++; } } // triangle loop node--; } // node is a leaf } // while loop while (node != head); if (n < 1) { hit = false; return 0; } hit = true; distance = distances[0]; float scale = 1.0f; float fr = 0.0f; float fg = 0.0f; float fb = 0.0f; unsigned int index; for (i=0; i < n; i++) { index = indices[i]; uint4 triangle_data = g_triangles[index]; float3 v0 = g_vertices[triangle_data.x]; float3 v1 = g_vertices[triangle_data.y]; float3 v2 = g_vertices[triangle_data.z]; float cos_theta = dot(normalize(cross(v1-v0,v2-v1)),-direction); if (cos_theta < 0.0f) cos_theta = dot(-normalize(cross(v1-v0,v2-v1)),-direction); unsigned int r0 = 0xff & (g_colors[index] >> 16); unsigned int g0 = 0xff & (g_colors[index] >> 8); unsigned int b0 = 0xff & g_colors[index]; float alpha = (255 - (0xff & (g_colors[index] >> 24)))/255.0f; fr += r0*scale*cos_theta*alpha; fg += g0*scale*cos_theta*alpha; fb += b0*scale*cos_theta*alpha; scale *= (1.0f-alpha); } unsigned int r = floorf(fr); unsigned int g = floorf(fg); unsigned int b = floorf(fb); return r << 16 | g << 8 | b; } #endif