depth ordering volumetrics

This commit is contained in:
zomseffen 2025-06-05 13:45:46 +02:00
parent fa6495e4cc
commit 68cd58f038
3 changed files with 415 additions and 292 deletions

Binary file not shown.

View file

@ -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,11 +424,50 @@ 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) {
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);
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);
@ -544,9 +603,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
result.end_direction = direction;
}
compound_num += 1;
}
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;
}

View file

@ -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,11 +436,50 @@ 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) {
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);
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);
@ -555,9 +615,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
result.end_direction = direction;
}
compound_num += 1;
}
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;
}