mesh_datastructure.glsl 3.73 KB
Newer Older
1
2
#ifndef INCLUDE_PATHTRACER_DATASTRUCTURE_GLSL
#define INCLUDE_PATHTRACER_DATASTRUCTURE_GLSL
unknown's avatar
unknown committed
3

4
5
6
#include <pathtracer/buffers.glsl>
#include <util/scene/mesh.glsl>
#include <util/tracing/bvh_node.glsl>
unknown's avatar
unknown committed
7

8
9
#include <pathtracer/data/mesh_bvh.glsl>
#include <pathtracer/data/mesh_linespace.glsl>
unknown's avatar
unknown committed
10

unknown's avatar
unknown committed
11

12
bool traverseObjects(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false);
unknown's avatar
unknown committed
13

unknown's avatar
unknown committed
14
15
bool nearestIntersection(const in Ray ray, inout Hit hit, bool force_bvh = false)
{
16
17
	float t_min = FLT_MAX;
	return traverseObjects(ray, false, FLT_MAX, hit, t_min, force_bvh);
unknown's avatar
unknown committed
18
19
20
21
}

bool intersectsAny(const in Ray ray, const in float max_distance, bool force_bvh = false)
{
22
23
24
	float t_min = max_distance;
	Hit unused_hit;
	return traverseObjects(ray, true, max_distance, unused_hit, t_min, force_bvh);
unknown's avatar
unknown committed
25
26
}

27
bool traverseObjects(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false)
unknown's avatar
unknown committed
28
29
30
31
{
	float t = t_min;
	float max_dist = max_distance;
	// Check once the AABB for the whole scene
32
	bool hit_scene = global_bvh_nodes_data.length() != 0 && ray.intersectsBounds(global_bvh_nodes_data[0].bounds, max_distance);
unknown's avatar
unknown committed
33
34
35
36
	bool hit_triangle = false;

	int current_node = 0;
	int bitstack = 0;
37

38
	Hit unused;
unknown's avatar
unknown committed
39
40
41

	while (hit_scene)
	{
42
		if (global_bvh_nodes_data[current_node].type == 0) //Inner node.
unknown's avatar
unknown committed
43
		{
44
45
			int id_left = int(global_bvh_nodes_data[current_node].left_idx);
			bool hit_left = ray.intersectsBounds(global_bvh_nodes_data[id_left].bounds, max_distance);
unknown's avatar
unknown committed
46

47
48
			int id_right = int(global_bvh_nodes_data[current_node].right_idx);
			bool hit_right = ray.intersectsBounds(global_bvh_nodes_data[id_right].bounds, max_distance);
unknown's avatar
unknown committed
49
50
51
52

			//both hit
			if (hit_left && hit_right)
			{
53
				// shift bitstack and mark as branched, so we can use the marker
unknown's avatar
unknown committed
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
				// when backtracking to stop here and use the right child.
				bitstack = bitstack << 1;
				current_node = id_left;
				bitstack = bitstack | 1;
				continue;
			}
			// only left hit
			else if (hit_left && !hit_right)
			{
				// Not branching here, the other sibling-check won't be needed here.
				bitstack = bitstack << 1;
				current_node = id_left;
				continue;
			}
			// only right hit
			else if (!hit_left && hit_right)
			{
				// Not branching here, the other sibling-check won't be needed here.
				bitstack = bitstack << 1;
				current_node = id_right;
				continue;
			}
		}
		else
		{
			//Is leaf
			// intersect ray with primitives.
			//shorten ray if closer intersection found.
			//intersect triangles

84
85
			int start = int(global_bvh_nodes_data[current_node].left_idx);
			int end = int(global_bvh_nodes_data[current_node].right_idx);
86

unknown's avatar
unknown committed
87
88
			for (int i = start; i <= end; i++)
			{
89
				float current_t = t_min;
90
				const Mesh mesh = meshes_data[i];
unknown's avatar
unknown committed
91
92
				if(force_bvh)
				{
93
					if(mesh.traverseBVH(ray.makeRelative(mesh), use_first, current_t, false, hit, unused, t_min)){
unknown's avatar
unknown committed
94
95
96
97
98
99
100
101
102
						hit_triangle = true;
						if (use_first)
						{
							return true;
						}
					}
				}
				else
				{
103
					if(mesh.traverseLineSpace(ray.makeRelative(mesh), use_first, current_t, hit, t_min)){
unknown's avatar
unknown committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
						hit_triangle = true;
						if (use_first)
						{
							return true;
						}
					}
				}
			}

		}

		//Backtrace on bitstack until we find a branching point (where bit value is 1)
		while ((bitstack & 1) == 0)
		{
			//Empty bitstack
			if (bitstack == 0)
			{
				return hit_triangle;
			}

124
			current_node = int(global_bvh_nodes_data[current_node].parent);
unknown's avatar
unknown committed
125
126
127
128
			bitstack = bitstack >> 1;
		}

		//Use other (right) sibling from the left child of the branched tree node.
129
		current_node = int(global_bvh_nodes_data[global_bvh_nodes_data[current_node].parent].right_idx);
unknown's avatar
unknown committed
130
131
132
133
		bitstack = bitstack ^ 1;
	}

	return hit_triangle;
unknown's avatar
unknown committed
134
135
}

136
#endif //INCLUDE_PATHTRACER_DATASTRUCTURE_GLSL