depth ordering volumetrics
This commit is contained in:
parent
fa6495e4cc
commit
68cd58f038
3 changed files with 415 additions and 292 deletions
shaders
Binary file not shown.
|
@ -36,7 +36,8 @@ float pos_infinity = uintBitsToFloat(0x7F800000);
|
|||
// set limit for maximal iterations
|
||||
uint max_iterations = max_num_lights * max_iterations_per_light * raster_points;
|
||||
uint iteration_num = 0;
|
||||
uint max_num_compounds = scene_info.infos[6];
|
||||
const uint absolute_max_compounds = 10;
|
||||
uint max_num_compounds = min(scene_info.infos[6], absolute_max_compounds);
|
||||
|
||||
uvec4 unpack_color(uint val) {
|
||||
// left most 8 bits first
|
||||
|
@ -311,20 +312,39 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
vec3 color_mul_transparent;
|
||||
|
||||
uint next_volumetric_index = 0;
|
||||
uint[5] done_volumetrics;
|
||||
for (int i=0; i < 5; i++) {
|
||||
uint[absolute_max_compounds] done_volumetrics;
|
||||
for (int i=0; i < max_num_compounds; i++) {
|
||||
done_volumetrics[i] = 0;
|
||||
}
|
||||
|
||||
uint[absolute_max_compounds] compound_starts;
|
||||
float[absolute_max_compounds] hit_factors;
|
||||
bool[absolute_max_compounds] is_x_hits;
|
||||
bool[absolute_max_compounds] is_y_hits;
|
||||
bool[absolute_max_compounds] is_z_hits;
|
||||
bool[absolute_max_compounds] hits_inside;
|
||||
|
||||
while (iteration_num < max_iterations) {
|
||||
iteration_num ++;
|
||||
|
||||
for (int i=0; i < max_num_compounds; i++) {
|
||||
compound_starts[i] = 0;
|
||||
hit_factors[i] = 0.0;
|
||||
is_x_hits[i] = false;
|
||||
is_y_hits[i] = false;
|
||||
is_z_hits[i] = false;
|
||||
hits_inside[i] = false;
|
||||
}
|
||||
|
||||
uint compound_num = 0;
|
||||
// go over the borders by this amount
|
||||
float overstep = 0.00001 / length(direction);
|
||||
uint hits = 0;
|
||||
while (scene_info.infos[volume_index + 6 + max_num_lights + compound_num] != 0 && compound_num < max_num_compounds && iteration_num < max_iterations && !result.has_hit) {
|
||||
uint compound_start = scene_info.infos[volume_index + 6 + max_num_lights + compound_num];
|
||||
|
||||
bool already_checked = false;
|
||||
for (int i=0; i < 5; i++) {
|
||||
for (int i=0; i < max_num_compounds; i++) {
|
||||
if (compound_start == done_volumetrics[i]) {
|
||||
already_checked = true;
|
||||
break;
|
||||
|
@ -334,8 +354,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
compound_num += 1;
|
||||
continue;
|
||||
}
|
||||
done_volumetrics[next_volumetric_index] = compound_start;
|
||||
next_volumetric_index = (next_volumetric_index + 1) % 5;
|
||||
|
||||
//iteration_num ++;
|
||||
uint oct_tree_index = compounds[compound_start + 8];
|
||||
|
@ -347,9 +365,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
float y_border = compound_pos.y + float((compound_grid_size) * uint(!y_pos)) * compound_scale;
|
||||
float z_border = compound_pos.z + float((compound_grid_size) * uint(!z_pos)) * compound_scale;
|
||||
|
||||
// go over the borders by this amount
|
||||
float overstep = 0.00001 / length(direction);
|
||||
|
||||
if (!x_null) {
|
||||
x_factor = (x_border - pos.x) / direction.x;
|
||||
} else {
|
||||
|
@ -369,15 +384,18 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
y_factor += overstep;
|
||||
z_factor += overstep;
|
||||
|
||||
vec3 intersection_pos = pos;
|
||||
vec3 intersection_pos = pos + 10.0 * overstep * direction;
|
||||
bool is_x_hit = false;
|
||||
bool is_y_hit = false;
|
||||
bool is_z_hit = false;
|
||||
bool hit_inside = false;
|
||||
float hit_factor;
|
||||
// check that either the hit is in range or we are inside of the compound from the start
|
||||
if ((compound_pos.x <= intersection_pos.x && intersection_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) &&
|
||||
(compound_pos.y <= intersection_pos.y && intersection_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) &&
|
||||
(compound_pos.z <= intersection_pos.z && intersection_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale)){
|
||||
//hit_inside = true;
|
||||
hit_inside = true;
|
||||
hit_factor = 10.0 * overstep;
|
||||
} else {
|
||||
vec3 intersection_pos_x = pos + x_factor * direction;
|
||||
vec3 intersection_pos_y = pos + y_factor * direction;
|
||||
|
@ -388,6 +406,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
hit_inside = true;
|
||||
is_x_hit = true;
|
||||
intersection_pos = intersection_pos_x;
|
||||
hit_factor = x_factor;
|
||||
}
|
||||
|
||||
if ((compound_pos.x <= intersection_pos_y.x && intersection_pos_y.x <= compound_pos.x + float(compound_grid_size) * compound_scale) &&
|
||||
|
@ -396,6 +415,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
hit_inside = true;
|
||||
is_y_hit = true;
|
||||
intersection_pos = intersection_pos_y;
|
||||
hit_factor = y_factor;
|
||||
}
|
||||
|
||||
if ((compound_pos.x <= intersection_pos_z.x && intersection_pos_z.x <= compound_pos.x + float(compound_grid_size) * compound_scale) &&
|
||||
|
@ -404,149 +424,185 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
hit_inside = true;
|
||||
is_z_hit = true;
|
||||
intersection_pos = intersection_pos_z;
|
||||
hit_factor = z_factor;
|
||||
}
|
||||
}
|
||||
|
||||
// check that either the hit is in range or we are inside of the compound from the start
|
||||
if (hit_inside) {
|
||||
vec3 oct_tree_pos = vec3(compound_pos);
|
||||
uint current_size = compound_grid_size;
|
||||
vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale);
|
||||
bool children_open[8] = {true, true, true, true, true, true, true, true};
|
||||
uint oct_tree_address = oct_tree_index;
|
||||
// iterate through the oct_tree
|
||||
uint check_it = 0;
|
||||
uint max_check_it = 60;
|
||||
uint prev_child = 0;
|
||||
uint prev_prev_child = 0;
|
||||
compound_starts[hits] = compound_start;
|
||||
hit_factors[hits] = hit_factor;
|
||||
is_x_hits[hits] = is_x_hit;
|
||||
is_y_hits[hits] = is_y_hit;
|
||||
is_z_hits[hits] = is_z_hit;
|
||||
hits_inside[hits] = hit_inside;
|
||||
hits += 1 * uint(hit_inside);
|
||||
|
||||
uvec3 grid_pos = uvec3(0, 0, 0);
|
||||
uvec3 parent_pos = uvec3(0, 0, 0);
|
||||
|
||||
bool has_moved = false;
|
||||
while (!result.has_hit && check_it < max_check_it) {
|
||||
// failsafe to get out in case has_moved runs into an accuracy issue
|
||||
check_it ++;
|
||||
oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos;
|
||||
mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale));
|
||||
|
||||
uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open);
|
||||
if (child_index == 0) {
|
||||
// go up to parent
|
||||
// if parent is 0 abort, as we have reached the root node again and try to exit it
|
||||
if (oct_tree_mem[oct_tree_address] == 0) {
|
||||
break;
|
||||
}
|
||||
for (int i=0; i < 8; i++) {
|
||||
children_open[i] = true;
|
||||
}
|
||||
uint parent_index = oct_tree_mem[oct_tree_address];
|
||||
// check which child we came from
|
||||
child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]);
|
||||
// mark as done to avoid reinvestigating, since intersection_pos is on its edge
|
||||
children_open[child_index - 1] = false;
|
||||
prev_prev_child = prev_child;
|
||||
prev_child = oct_tree_address;
|
||||
|
||||
uvec3 back_vec = parent_child_vec(current_size, child_index);
|
||||
grid_pos -= parent_child_vec(current_size, child_index);
|
||||
current_size *= 2;
|
||||
oct_tree_address = parent_index;
|
||||
} else {
|
||||
// go down into child
|
||||
if (current_size == 2) {
|
||||
// check block if hit break
|
||||
if (oct_tree_mem[oct_tree_address + child_index] != 0) {
|
||||
result.has_hit = true;
|
||||
result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// check if the child has content, else skip to next child of current parent
|
||||
uint x = oct_tree_mem[oct_tree_address + child_index];
|
||||
if (oct_tree_mem[x] != 0) {
|
||||
// change base address and position to child
|
||||
current_size /= 2;
|
||||
oct_tree_address = x;
|
||||
grid_pos += parent_child_vec(current_size, child_index);
|
||||
for (int i=0; i < 8; i++) {
|
||||
children_open[i] = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
children_open[child_index - 1] = false;
|
||||
|
||||
// we did not go deeper or had a hit, so intersection pos needs to be updated
|
||||
// new intersection pos calc
|
||||
vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale;
|
||||
vec3 low = oct_tree_pos + offset;
|
||||
float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos));
|
||||
float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos));
|
||||
float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos));
|
||||
|
||||
if (!x_null) {
|
||||
x_factor = (x_border - pos.x) / direction.x;
|
||||
if (x_factor <= 0.0) {
|
||||
x_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
x_factor = max_factor;
|
||||
}
|
||||
if (!y_null) {
|
||||
y_factor = (y_border - pos.y) / direction.y;
|
||||
if (y_factor <= 0.0) {
|
||||
y_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
y_factor = max_factor;
|
||||
}
|
||||
if (!z_null) {
|
||||
z_factor = (z_border - pos.z) / direction.z;
|
||||
if (z_factor <= 0.0) {
|
||||
z_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
z_factor = max_factor;
|
||||
}
|
||||
float smallest_factor = min(min(x_factor, y_factor), z_factor);
|
||||
|
||||
if (x_factor == smallest_factor) {
|
||||
is_x_hit = true;
|
||||
is_y_hit = false;
|
||||
is_z_hit = false;
|
||||
}
|
||||
if (y_factor == smallest_factor) {
|
||||
is_x_hit = false;
|
||||
is_y_hit = true;
|
||||
is_z_hit = false;
|
||||
}
|
||||
if (z_factor == smallest_factor) {
|
||||
is_x_hit = false;
|
||||
is_y_hit = false;
|
||||
is_z_hit = true;
|
||||
}
|
||||
|
||||
// move a bit further to fully enter the next quadrant
|
||||
smallest_factor += overstep;
|
||||
|
||||
//has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001;
|
||||
has_moved = intersection_pos != (pos + smallest_factor * direction);
|
||||
intersection_pos = pos + smallest_factor * direction;
|
||||
}
|
||||
}
|
||||
|
||||
uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos);
|
||||
//result.has_hit = true;
|
||||
result.end_pos = intersection_pos;
|
||||
result.end_facing = hit_facing;
|
||||
result.end_volume = volume_index;
|
||||
result.end_direction = direction;
|
||||
}
|
||||
done_volumetrics[next_volumetric_index] = compound_start;
|
||||
next_volumetric_index = (next_volumetric_index + 1) % max_num_compounds;
|
||||
|
||||
compound_num += 1;
|
||||
}
|
||||
|
||||
for (int i =0; i < hits; i++) {
|
||||
if (result.has_hit) {
|
||||
break;
|
||||
}
|
||||
// find encounters in order
|
||||
float min_factor = max_factor;
|
||||
uint min_index = 0;
|
||||
for (int j = 0; j < hits; j++) {
|
||||
if (hit_factors[j] < min_factor) {
|
||||
min_factor = hit_factors[j];
|
||||
min_index = j;
|
||||
}
|
||||
}
|
||||
// set up the compound
|
||||
uint compound_start = compound_starts[min_index];
|
||||
bool is_x_hit = is_x_hits[min_index];
|
||||
bool is_y_hit = is_y_hits[min_index];
|
||||
bool is_z_hit = is_z_hits[min_index];
|
||||
uint oct_tree_index = compounds[compound_start + 8];
|
||||
uint compound_grid_size = compounds[compound_start];
|
||||
float compound_scale = uintBitsToFloat(compounds[compound_start + 1]);
|
||||
vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7]));
|
||||
vec3 intersection_pos = pos + hit_factors[min_index] * direction;
|
||||
// invalidate the min found
|
||||
hit_factors[min_index] = max_factor;
|
||||
|
||||
vec3 oct_tree_pos = vec3(compound_pos);
|
||||
uint current_size = compound_grid_size;
|
||||
vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale);
|
||||
bool children_open[8] = {true, true, true, true, true, true, true, true};
|
||||
uint oct_tree_address = oct_tree_index;
|
||||
// iterate through the oct_tree
|
||||
uint check_it = 0;
|
||||
uint max_check_it = 60;
|
||||
uint prev_child = 0;
|
||||
uint prev_prev_child = 0;
|
||||
|
||||
uvec3 grid_pos = uvec3(0, 0, 0);
|
||||
uvec3 parent_pos = uvec3(0, 0, 0);
|
||||
|
||||
bool has_moved = false;
|
||||
while (!result.has_hit && check_it < max_check_it) {
|
||||
// failsafe to get out in case has_moved runs into an accuracy issue
|
||||
check_it ++;
|
||||
oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos;
|
||||
mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale));
|
||||
|
||||
uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open);
|
||||
if (child_index == 0) {
|
||||
// go up to parent
|
||||
// if parent is 0 abort, as we have reached the root node again and try to exit it
|
||||
if (oct_tree_mem[oct_tree_address] == 0) {
|
||||
break;
|
||||
}
|
||||
for (int i=0; i < 8; i++) {
|
||||
children_open[i] = true;
|
||||
}
|
||||
uint parent_index = oct_tree_mem[oct_tree_address];
|
||||
// check which child we came from
|
||||
child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]);
|
||||
// mark as done to avoid reinvestigating, since intersection_pos is on its edge
|
||||
children_open[child_index - 1] = false;
|
||||
prev_prev_child = prev_child;
|
||||
prev_child = oct_tree_address;
|
||||
|
||||
uvec3 back_vec = parent_child_vec(current_size, child_index);
|
||||
grid_pos -= parent_child_vec(current_size, child_index);
|
||||
current_size *= 2;
|
||||
oct_tree_address = parent_index;
|
||||
} else {
|
||||
// go down into child
|
||||
if (current_size == 2) {
|
||||
// check block if hit break
|
||||
if (oct_tree_mem[oct_tree_address + child_index] != 0) {
|
||||
result.has_hit = true;
|
||||
result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// check if the child has content, else skip to next child of current parent
|
||||
uint x = oct_tree_mem[oct_tree_address + child_index];
|
||||
if (oct_tree_mem[x] != 0) {
|
||||
// change base address and position to child
|
||||
current_size /= 2;
|
||||
oct_tree_address = x;
|
||||
grid_pos += parent_child_vec(current_size, child_index);
|
||||
for (int i=0; i < 8; i++) {
|
||||
children_open[i] = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
children_open[child_index - 1] = false;
|
||||
|
||||
// we did not go deeper or had a hit, so intersection pos needs to be updated
|
||||
// new intersection pos calc
|
||||
vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale;
|
||||
vec3 low = oct_tree_pos + offset;
|
||||
float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos));
|
||||
float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos));
|
||||
float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos));
|
||||
|
||||
if (!x_null) {
|
||||
x_factor = (x_border - pos.x) / direction.x;
|
||||
if (x_factor <= 0.0) {
|
||||
x_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
x_factor = max_factor;
|
||||
}
|
||||
if (!y_null) {
|
||||
y_factor = (y_border - pos.y) / direction.y;
|
||||
if (y_factor <= 0.0) {
|
||||
y_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
y_factor = max_factor;
|
||||
}
|
||||
if (!z_null) {
|
||||
z_factor = (z_border - pos.z) / direction.z;
|
||||
if (z_factor <= 0.0) {
|
||||
z_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
z_factor = max_factor;
|
||||
}
|
||||
float smallest_factor = min(min(x_factor, y_factor), z_factor);
|
||||
|
||||
if (x_factor == smallest_factor) {
|
||||
is_x_hit = true;
|
||||
is_y_hit = false;
|
||||
is_z_hit = false;
|
||||
}
|
||||
if (y_factor == smallest_factor) {
|
||||
is_x_hit = false;
|
||||
is_y_hit = true;
|
||||
is_z_hit = false;
|
||||
}
|
||||
if (z_factor == smallest_factor) {
|
||||
is_x_hit = false;
|
||||
is_y_hit = false;
|
||||
is_z_hit = true;
|
||||
}
|
||||
|
||||
// move a bit further to fully enter the next quadrant
|
||||
smallest_factor += overstep;
|
||||
|
||||
//has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001;
|
||||
has_moved = intersection_pos != (pos + smallest_factor * direction);
|
||||
intersection_pos = pos + smallest_factor * direction;
|
||||
}
|
||||
}
|
||||
|
||||
uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos);
|
||||
//result.has_hit = true;
|
||||
result.end_pos = intersection_pos;
|
||||
result.end_facing = hit_facing;
|
||||
result.end_volume = volume_index;
|
||||
result.end_direction = direction;
|
||||
}
|
||||
|
||||
if (result.has_hit) {
|
||||
break;
|
||||
}
|
||||
|
@ -667,6 +723,11 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
|
||||
z_pos = direction.z > 0.0;
|
||||
z_null = (direction.z == 0.0);
|
||||
|
||||
// clear volumetrics for reevaluation
|
||||
for (int i=0; i < max_num_compounds; i++) {
|
||||
done_volumetrics[i] = 0;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,8 @@ float pos_infinity = uintBitsToFloat(0x7F800000);
|
|||
// set limit for maximal iterations
|
||||
uint max_iterations = max_num_lights * max_iterations_per_light * raster_points;
|
||||
uint iteration_num = 0;
|
||||
uint max_num_compounds = scene_info.infos[6];
|
||||
const uint absolute_max_compounds = 10;
|
||||
uint max_num_compounds = min(scene_info.infos[6], absolute_max_compounds);
|
||||
|
||||
uvec4 unpack_color(uint val) {
|
||||
// left most 8 bits first
|
||||
|
@ -322,20 +323,40 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
vec3 color_mul_transparent;
|
||||
|
||||
uint next_volumetric_index = 0;
|
||||
uint[5] done_volumetrics;
|
||||
for (int i=0; i < 5; i++) {
|
||||
uint[absolute_max_compounds] done_volumetrics;
|
||||
for (int i=0; i < max_num_compounds; i++) {
|
||||
done_volumetrics[i] = 0;
|
||||
}
|
||||
|
||||
uint[absolute_max_compounds] compound_starts;
|
||||
float[absolute_max_compounds] hit_factors;
|
||||
bool[absolute_max_compounds] is_x_hits;
|
||||
bool[absolute_max_compounds] is_y_hits;
|
||||
bool[absolute_max_compounds] is_z_hits;
|
||||
bool[absolute_max_compounds] hits_inside;
|
||||
|
||||
while (iteration_num < max_iterations) {
|
||||
iteration_num ++;
|
||||
|
||||
for (int i=0; i < max_num_compounds; i++) {
|
||||
compound_starts[i] = 0;
|
||||
hit_factors[i] = 0.0;
|
||||
is_x_hits[i] = false;
|
||||
is_y_hits[i] = false;
|
||||
is_z_hits[i] = false;
|
||||
hits_inside[i] = false;
|
||||
}
|
||||
|
||||
uint compound_num = 0;
|
||||
// go over the borders by this amount
|
||||
float overstep = 0.00001 / length(direction);
|
||||
uint hits = 0;
|
||||
// todo needs depth ordering of volumetrics inside of the volume
|
||||
while (scene_info.infos[volume_index + 6 + max_num_lights + compound_num] != 0 && compound_num < max_num_compounds && iteration_num < max_iterations && !result.has_hit) {
|
||||
uint compound_start = scene_info.infos[volume_index + 6 + max_num_lights + compound_num];
|
||||
|
||||
bool already_checked = false;
|
||||
for (int i=0; i < 5; i++) {
|
||||
for (int i=0; i < max_num_compounds; i++) {
|
||||
if (compound_start == done_volumetrics[i]) {
|
||||
already_checked = true;
|
||||
break;
|
||||
|
@ -345,8 +366,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
compound_num += 1;
|
||||
continue;
|
||||
}
|
||||
done_volumetrics[next_volumetric_index] = compound_start;
|
||||
next_volumetric_index = (next_volumetric_index + 1) % 5;
|
||||
|
||||
//iteration_num ++;
|
||||
uint oct_tree_index = compounds[compound_start + 8];
|
||||
|
@ -358,9 +377,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
float y_border = compound_pos.y + float((compound_grid_size) * uint(!y_pos)) * compound_scale;
|
||||
float z_border = compound_pos.z + float((compound_grid_size) * uint(!z_pos)) * compound_scale;
|
||||
|
||||
// go over the borders by this amount
|
||||
float overstep = 0.00001 / length(direction);
|
||||
|
||||
if (!x_null) {
|
||||
x_factor = (x_border - pos.x) / direction.x;
|
||||
} else {
|
||||
|
@ -380,15 +396,18 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
y_factor += overstep;
|
||||
z_factor += overstep;
|
||||
|
||||
vec3 intersection_pos = pos;
|
||||
vec3 intersection_pos = pos + 10.0 * overstep * direction;
|
||||
bool is_x_hit = false;
|
||||
bool is_y_hit = false;
|
||||
bool is_z_hit = false;
|
||||
bool hit_inside = false;
|
||||
float hit_factor;
|
||||
// check that either the hit is in range or we are inside of the compound from the start
|
||||
if ((compound_pos.x <= intersection_pos.x && intersection_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) &&
|
||||
(compound_pos.y <= intersection_pos.y && intersection_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) &&
|
||||
(compound_pos.z <= intersection_pos.z && intersection_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale)){
|
||||
//hit_inside = true;
|
||||
hit_inside = true;
|
||||
hit_factor = 10.0 * overstep;
|
||||
} else {
|
||||
vec3 intersection_pos_x = pos + x_factor * direction;
|
||||
vec3 intersection_pos_y = pos + y_factor * direction;
|
||||
|
@ -399,6 +418,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
hit_inside = true;
|
||||
is_x_hit = true;
|
||||
intersection_pos = intersection_pos_x;
|
||||
hit_factor = x_factor;
|
||||
}
|
||||
|
||||
if ((compound_pos.x <= intersection_pos_y.x && intersection_pos_y.x <= compound_pos.x + float(compound_grid_size) * compound_scale) &&
|
||||
|
@ -407,6 +427,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
hit_inside = true;
|
||||
is_y_hit = true;
|
||||
intersection_pos = intersection_pos_y;
|
||||
hit_factor = y_factor;
|
||||
}
|
||||
|
||||
if ((compound_pos.x <= intersection_pos_z.x && intersection_pos_z.x <= compound_pos.x + float(compound_grid_size) * compound_scale) &&
|
||||
|
@ -415,149 +436,185 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
hit_inside = true;
|
||||
is_z_hit = true;
|
||||
intersection_pos = intersection_pos_z;
|
||||
hit_factor = z_factor;
|
||||
}
|
||||
}
|
||||
|
||||
// check that either the hit is in range or we are inside of the compound from the start
|
||||
if (hit_inside) {
|
||||
vec3 oct_tree_pos = vec3(compound_pos);
|
||||
uint current_size = compound_grid_size;
|
||||
vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale);
|
||||
bool children_open[8] = {true, true, true, true, true, true, true, true};
|
||||
uint oct_tree_address = oct_tree_index;
|
||||
// iterate through the oct_tree
|
||||
uint check_it = 0;
|
||||
uint max_check_it = 60;
|
||||
uint prev_child = 0;
|
||||
uint prev_prev_child = 0;
|
||||
compound_starts[hits] = compound_start;
|
||||
hit_factors[hits] = hit_factor;
|
||||
is_x_hits[hits] = is_x_hit;
|
||||
is_y_hits[hits] = is_y_hit;
|
||||
is_z_hits[hits] = is_z_hit;
|
||||
hits_inside[hits] = hit_inside;
|
||||
hits += 1 * uint(hit_inside);
|
||||
|
||||
uvec3 grid_pos = uvec3(0, 0, 0);
|
||||
uvec3 parent_pos = uvec3(0, 0, 0);
|
||||
|
||||
bool has_moved = false;
|
||||
while (!result.has_hit && check_it < max_check_it) {
|
||||
// failsafe to get out in case has_moved runs into an accuracy issue
|
||||
check_it ++;
|
||||
oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos;
|
||||
mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale));
|
||||
|
||||
uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open);
|
||||
if (child_index == 0) {
|
||||
// go up to parent
|
||||
// if parent is 0 abort, as we have reached the root node again and try to exit it
|
||||
if (oct_tree_mem[oct_tree_address] == 0) {
|
||||
break;
|
||||
}
|
||||
for (int i=0; i < 8; i++) {
|
||||
children_open[i] = true;
|
||||
}
|
||||
uint parent_index = oct_tree_mem[oct_tree_address];
|
||||
// check which child we came from
|
||||
child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]);
|
||||
// mark as done to avoid reinvestigating, since intersection_pos is on its edge
|
||||
children_open[child_index - 1] = false;
|
||||
prev_prev_child = prev_child;
|
||||
prev_child = oct_tree_address;
|
||||
|
||||
uvec3 back_vec = parent_child_vec(current_size, child_index);
|
||||
grid_pos -= parent_child_vec(current_size, child_index);
|
||||
current_size *= 2;
|
||||
oct_tree_address = parent_index;
|
||||
} else {
|
||||
// go down into child
|
||||
if (current_size == 2) {
|
||||
// check block if hit break
|
||||
if (oct_tree_mem[oct_tree_address + child_index] != 0) {
|
||||
result.has_hit = true;
|
||||
result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// check if the child has content, else skip to next child of current parent
|
||||
uint x = oct_tree_mem[oct_tree_address + child_index];
|
||||
if (oct_tree_mem[x] != 0) {
|
||||
// change base address and position to child
|
||||
current_size /= 2;
|
||||
oct_tree_address = x;
|
||||
grid_pos += parent_child_vec(current_size, child_index);
|
||||
for (int i=0; i < 8; i++) {
|
||||
children_open[i] = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
children_open[child_index - 1] = false;
|
||||
|
||||
// we did not go deeper or had a hit, so intersection pos needs to be updated
|
||||
// new intersection pos calc
|
||||
vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale;
|
||||
vec3 low = oct_tree_pos + offset;
|
||||
float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos));
|
||||
float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos));
|
||||
float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos));
|
||||
|
||||
if (!x_null) {
|
||||
x_factor = (x_border - pos.x) / direction.x;
|
||||
if (x_factor <= 0.0) {
|
||||
x_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
x_factor = max_factor;
|
||||
}
|
||||
if (!y_null) {
|
||||
y_factor = (y_border - pos.y) / direction.y;
|
||||
if (y_factor <= 0.0) {
|
||||
y_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
y_factor = max_factor;
|
||||
}
|
||||
if (!z_null) {
|
||||
z_factor = (z_border - pos.z) / direction.z;
|
||||
if (z_factor <= 0.0) {
|
||||
z_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
z_factor = max_factor;
|
||||
}
|
||||
float smallest_factor = min(min(x_factor, y_factor), z_factor);
|
||||
|
||||
if (x_factor == smallest_factor) {
|
||||
is_x_hit = true;
|
||||
is_y_hit = false;
|
||||
is_z_hit = false;
|
||||
}
|
||||
if (y_factor == smallest_factor) {
|
||||
is_x_hit = false;
|
||||
is_y_hit = true;
|
||||
is_z_hit = false;
|
||||
}
|
||||
if (z_factor == smallest_factor) {
|
||||
is_x_hit = false;
|
||||
is_y_hit = false;
|
||||
is_z_hit = true;
|
||||
}
|
||||
|
||||
// move a bit further to fully enter the next quadrant
|
||||
smallest_factor += overstep;
|
||||
|
||||
//has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001;
|
||||
has_moved = intersection_pos != (pos + smallest_factor * direction);
|
||||
intersection_pos = pos + smallest_factor * direction;
|
||||
}
|
||||
}
|
||||
|
||||
uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos);
|
||||
//result.has_hit = true;
|
||||
result.end_pos = intersection_pos;
|
||||
result.end_facing = hit_facing;
|
||||
result.end_volume = volume_index;
|
||||
result.end_direction = direction;
|
||||
}
|
||||
done_volumetrics[next_volumetric_index] = compound_start;
|
||||
next_volumetric_index = (next_volumetric_index + 1) % max_num_compounds;
|
||||
|
||||
compound_num += 1;
|
||||
}
|
||||
|
||||
for (int i =0; i < hits; i++) {
|
||||
if (result.has_hit) {
|
||||
break;
|
||||
}
|
||||
// find encounters in order
|
||||
float min_factor = max_factor;
|
||||
uint min_index = 0;
|
||||
for (int j = 0; j < hits; j++) {
|
||||
if (hit_factors[j] < min_factor) {
|
||||
min_factor = hit_factors[j];
|
||||
min_index = j;
|
||||
}
|
||||
}
|
||||
// set up the compound
|
||||
uint compound_start = compound_starts[min_index];
|
||||
bool is_x_hit = is_x_hits[min_index];
|
||||
bool is_y_hit = is_y_hits[min_index];
|
||||
bool is_z_hit = is_z_hits[min_index];
|
||||
uint oct_tree_index = compounds[compound_start + 8];
|
||||
uint compound_grid_size = compounds[compound_start];
|
||||
float compound_scale = uintBitsToFloat(compounds[compound_start + 1]);
|
||||
vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7]));
|
||||
vec3 intersection_pos = pos + hit_factors[min_index] * direction;
|
||||
// invalidate the min found
|
||||
hit_factors[min_index] = max_factor;
|
||||
|
||||
vec3 oct_tree_pos = vec3(compound_pos);
|
||||
uint current_size = compound_grid_size;
|
||||
vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale);
|
||||
bool children_open[8] = {true, true, true, true, true, true, true, true};
|
||||
uint oct_tree_address = oct_tree_index;
|
||||
// iterate through the oct_tree
|
||||
uint check_it = 0;
|
||||
uint max_check_it = 60;
|
||||
uint prev_child = 0;
|
||||
uint prev_prev_child = 0;
|
||||
|
||||
uvec3 grid_pos = uvec3(0, 0, 0);
|
||||
uvec3 parent_pos = uvec3(0, 0, 0);
|
||||
|
||||
bool has_moved = false;
|
||||
while (!result.has_hit && check_it < max_check_it) {
|
||||
// failsafe to get out in case has_moved runs into an accuracy issue
|
||||
check_it ++;
|
||||
oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos;
|
||||
mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale));
|
||||
|
||||
uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open);
|
||||
if (child_index == 0) {
|
||||
// go up to parent
|
||||
// if parent is 0 abort, as we have reached the root node again and try to exit it
|
||||
if (oct_tree_mem[oct_tree_address] == 0) {
|
||||
break;
|
||||
}
|
||||
for (int i=0; i < 8; i++) {
|
||||
children_open[i] = true;
|
||||
}
|
||||
uint parent_index = oct_tree_mem[oct_tree_address];
|
||||
// check which child we came from
|
||||
child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]);
|
||||
// mark as done to avoid reinvestigating, since intersection_pos is on its edge
|
||||
children_open[child_index - 1] = false;
|
||||
prev_prev_child = prev_child;
|
||||
prev_child = oct_tree_address;
|
||||
|
||||
uvec3 back_vec = parent_child_vec(current_size, child_index);
|
||||
grid_pos -= parent_child_vec(current_size, child_index);
|
||||
current_size *= 2;
|
||||
oct_tree_address = parent_index;
|
||||
} else {
|
||||
// go down into child
|
||||
if (current_size == 2) {
|
||||
// check block if hit break
|
||||
if (oct_tree_mem[oct_tree_address + child_index] != 0) {
|
||||
result.has_hit = true;
|
||||
result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// check if the child has content, else skip to next child of current parent
|
||||
uint x = oct_tree_mem[oct_tree_address + child_index];
|
||||
if (oct_tree_mem[x] != 0) {
|
||||
// change base address and position to child
|
||||
current_size /= 2;
|
||||
oct_tree_address = x;
|
||||
grid_pos += parent_child_vec(current_size, child_index);
|
||||
for (int i=0; i < 8; i++) {
|
||||
children_open[i] = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
children_open[child_index - 1] = false;
|
||||
|
||||
// we did not go deeper or had a hit, so intersection pos needs to be updated
|
||||
// new intersection pos calc
|
||||
vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale;
|
||||
vec3 low = oct_tree_pos + offset;
|
||||
float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos));
|
||||
float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos));
|
||||
float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos));
|
||||
|
||||
if (!x_null) {
|
||||
x_factor = (x_border - pos.x) / direction.x;
|
||||
if (x_factor <= 0.0) {
|
||||
x_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
x_factor = max_factor;
|
||||
}
|
||||
if (!y_null) {
|
||||
y_factor = (y_border - pos.y) / direction.y;
|
||||
if (y_factor <= 0.0) {
|
||||
y_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
y_factor = max_factor;
|
||||
}
|
||||
if (!z_null) {
|
||||
z_factor = (z_border - pos.z) / direction.z;
|
||||
if (z_factor <= 0.0) {
|
||||
z_factor = max_factor;
|
||||
}
|
||||
} else {
|
||||
z_factor = max_factor;
|
||||
}
|
||||
float smallest_factor = min(min(x_factor, y_factor), z_factor);
|
||||
|
||||
if (x_factor == smallest_factor) {
|
||||
is_x_hit = true;
|
||||
is_y_hit = false;
|
||||
is_z_hit = false;
|
||||
}
|
||||
if (y_factor == smallest_factor) {
|
||||
is_x_hit = false;
|
||||
is_y_hit = true;
|
||||
is_z_hit = false;
|
||||
}
|
||||
if (z_factor == smallest_factor) {
|
||||
is_x_hit = false;
|
||||
is_y_hit = false;
|
||||
is_z_hit = true;
|
||||
}
|
||||
|
||||
// move a bit further to fully enter the next quadrant
|
||||
smallest_factor += overstep;
|
||||
|
||||
//has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001;
|
||||
has_moved = intersection_pos != (pos + smallest_factor * direction);
|
||||
intersection_pos = pos + smallest_factor * direction;
|
||||
}
|
||||
}
|
||||
|
||||
uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos);
|
||||
//result.has_hit = true;
|
||||
result.end_pos = intersection_pos;
|
||||
result.end_facing = hit_facing;
|
||||
result.end_volume = volume_index;
|
||||
result.end_direction = direction;
|
||||
}
|
||||
|
||||
if (result.has_hit) {
|
||||
break;
|
||||
}
|
||||
|
@ -678,6 +735,11 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
|
|||
|
||||
z_pos = direction.z > 0.0;
|
||||
z_null = (direction.z == 0.0);
|
||||
|
||||
// clear volumetrics for reevaluation
|
||||
for (int i=0; i < max_num_compounds; i++) {
|
||||
done_volumetrics[i] = 0;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue