shader refactoring and float pos for lights
This commit is contained in:
parent
86135cb2ce
commit
9b618b0e3f
3 changed files with 92 additions and 70 deletions
Binary file not shown.
|
@ -127,68 +127,71 @@ uvec4 sample_color_from_scene_info(uint volume_start, uvec2 raster_pos, uint f)
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 get_light_position(uint light_index) {
|
vec3 get_light_position(uint light_index) {
|
||||||
return vec3(float(scene_info.infos[light_index]), float(scene_info.infos[light_index + 1]), float(scene_info.infos[light_index + 2]));
|
return vec3(uintBitsToFloat(scene_info.infos[light_index]), uintBitsToFloat(scene_info.infos[light_index + 1]), uintBitsToFloat(scene_info.infos[light_index + 2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 get_light_color(uint light_index) {
|
vec3 get_light_color(uint light_index) {
|
||||||
return vec3(float(scene_info.infos[light_index + 3]) / 255.0, float(scene_info.infos[light_index + 4]) / 255.0, float(scene_info.infos[light_index + 5]) / 255.0);
|
return vec3(float(scene_info.infos[light_index + 3]) / 255.0, float(scene_info.infos[light_index + 4]) / 255.0, float(scene_info.infos[light_index + 5]) / 255.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sample) {
|
struct Tracing {
|
||||||
uint max_light_num = scene_info.infos[0];
|
vec3 end_pos;
|
||||||
uint light_num = 0;
|
uvec4 end_color;
|
||||||
|
uint end_volume;
|
||||||
|
uint end_facing;
|
||||||
|
float end_factor;
|
||||||
|
uint end_cycle;
|
||||||
|
bool has_hit;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 direction, float max_factor, uint start_cycle, uint max_cycle) {
|
||||||
|
uint cycle = start_cycle;
|
||||||
// setup volume info
|
// setup volume info
|
||||||
uint volume_index = volume_start;
|
uint volume_index = volume_start;
|
||||||
uint volume_pos_x = scene_info.infos[volume_index + 0];
|
uint volume_pos_x = scene_info.infos[volume_index + 0];
|
||||||
uint volume_pos_y = scene_info.infos[volume_index + 1];
|
uint volume_pos_y = scene_info.infos[volume_index + 1];
|
||||||
uint volume_pos_z = scene_info.infos[volume_index + 2];
|
uint volume_pos_z = scene_info.infos[volume_index + 2];
|
||||||
|
|
||||||
// setup light info
|
bool x_pos = direction.x > 0.0;
|
||||||
uint light_index = scene_info.infos[volume_start + 6 + light_num];
|
bool x_null = (direction.x == 0.0);
|
||||||
vec3 light_direction = get_light_position(light_index) - starting_pos;
|
|
||||||
vec3 light_color = get_light_color(light_index);
|
|
||||||
|
|
||||||
bool x_pos = light_direction.x > 0.0;
|
bool y_pos = direction.y > 0.0;
|
||||||
bool x_null = (light_direction.x == 0.0);
|
bool y_null = (direction.y == 0.0);
|
||||||
|
|
||||||
bool y_pos = light_direction.y > 0.0;
|
bool z_pos = direction.z > 0.0;
|
||||||
bool y_null = (light_direction.y == 0.0);
|
bool z_null = (direction.z == 0.0);
|
||||||
|
|
||||||
bool z_pos = light_direction.z > 0.0;
|
// default is max factor, that way we avoid collision when going parallel to an axis. The other directions will score a hit
|
||||||
bool z_null = (light_direction.z == 0.0);
|
float x_factor = max_factor;
|
||||||
|
float y_factor = max_factor;
|
||||||
|
float z_factor = max_factor;
|
||||||
|
|
||||||
// initialize color
|
Tracing result;
|
||||||
vec3 color_sum = vec3(0.0, 0.0, 0.0) + (orig_color_sample.xyz * 0.01);
|
|
||||||
|
|
||||||
uint max_iterations = max_light_num * scene_info.infos[1];
|
while (cycle < max_cycle) {
|
||||||
for (int i = 0; i < max_iterations; i++) {
|
cycle ++;
|
||||||
float x_border = float(volume_pos_x + (scene_info.infos[volume_index + 3]) * uint(x_pos)) - 0.5;
|
float x_border = float(volume_pos_x + (scene_info.infos[volume_index + 3]) * uint(x_pos)) - 0.5;
|
||||||
float y_border = float(volume_pos_y + (scene_info.infos[volume_index + 4]) * uint(y_pos)) - 0.5;
|
float y_border = float(volume_pos_y + (scene_info.infos[volume_index + 4]) * uint(y_pos)) - 0.5;
|
||||||
float z_border = float(volume_pos_z + (scene_info.infos[volume_index + 5]) * uint(z_pos)) - 0.5;
|
float z_border = float(volume_pos_z + (scene_info.infos[volume_index + 5]) * uint(z_pos)) - 0.5;
|
||||||
|
|
||||||
bool needs_next_light = false;
|
bool needs_next_light = false;
|
||||||
|
|
||||||
// 2 is way behind the light position and should result in no collision being detected
|
|
||||||
float x_factor = 2.0;
|
|
||||||
float y_factor = 2.0;
|
|
||||||
float z_factor = 2.0;
|
|
||||||
if (!x_null) {
|
if (!x_null) {
|
||||||
x_factor = (x_border - starting_pos.x) / light_direction.x;
|
x_factor = (x_border - starting_pos.x) / direction.x;
|
||||||
}
|
}
|
||||||
if (!y_null) {
|
if (!y_null) {
|
||||||
y_factor = (y_border - starting_pos.y) / light_direction.y;
|
y_factor = (y_border - starting_pos.y) / direction.y;
|
||||||
}
|
}
|
||||||
if (!z_null) {
|
if (!z_null) {
|
||||||
z_factor = (z_border - starting_pos.z) / light_direction.z;
|
z_factor = (z_border - starting_pos.z) / direction.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((x_factor >= 1.0) && (y_factor >= 1.0) && (z_factor >= 1.0)) {
|
if ((x_factor >= max_factor) && (y_factor >= max_factor) && (z_factor >= max_factor)) {
|
||||||
// no hit, add light color result
|
// no hit, finish tracking
|
||||||
color_sum += (orig_color_sample.xyz * light_color) / ((0.01 * length(light_direction) * length(light_direction)) + 1.0);
|
result.has_hit = false;
|
||||||
needs_next_light = true;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// if there is a border hit before reaching the light
|
// if there is a border hit before reaching the end
|
||||||
// change to the relevant next volume
|
// change to the relevant next volume
|
||||||
// Todo: look into removing ifs from this
|
// Todo: look into removing ifs from this
|
||||||
uint hit_facing = 0;
|
uint hit_facing = 0;
|
||||||
|
@ -200,9 +203,11 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa
|
||||||
} else {
|
} else {
|
||||||
hit_facing = 2;
|
hit_facing = 2;
|
||||||
}
|
}
|
||||||
vec3 intersection_pos = starting_pos + x_factor * light_direction;
|
vec3 intersection_pos = starting_pos + x_factor * direction;
|
||||||
u = uint(round(intersection_pos.y)) - volume_pos_y;
|
u = uint(round(intersection_pos.y)) - volume_pos_y;
|
||||||
v = uint(round(intersection_pos.z)) - volume_pos_z;
|
v = uint(round(intersection_pos.z)) - volume_pos_z;
|
||||||
|
result.end_pos = intersection_pos;
|
||||||
|
result.end_facing = hit_facing;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y_factor <= x_factor && y_factor <= z_factor) {
|
if (y_factor <= x_factor && y_factor <= z_factor) {
|
||||||
|
@ -211,9 +216,11 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa
|
||||||
} else {
|
} else {
|
||||||
hit_facing = 4;
|
hit_facing = 4;
|
||||||
}
|
}
|
||||||
vec3 intersection_pos = starting_pos + y_factor * light_direction;
|
vec3 intersection_pos = starting_pos + y_factor * direction;
|
||||||
u = uint(round(intersection_pos.x)) - volume_pos_x;
|
u = uint(round(intersection_pos.x)) - volume_pos_x;
|
||||||
v = uint(round(intersection_pos.z)) - volume_pos_z;
|
v = uint(round(intersection_pos.z)) - volume_pos_z;
|
||||||
|
result.end_pos = intersection_pos;
|
||||||
|
result.end_facing = hit_facing;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (z_factor <= x_factor && z_factor <= y_factor) {
|
if (z_factor <= x_factor && z_factor <= y_factor) {
|
||||||
|
@ -222,9 +229,11 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa
|
||||||
} else {
|
} else {
|
||||||
hit_facing = 1;
|
hit_facing = 1;
|
||||||
}
|
}
|
||||||
vec3 intersection_pos = starting_pos + z_factor * light_direction;
|
vec3 intersection_pos = starting_pos + z_factor * direction;
|
||||||
u = uint(round(intersection_pos.x)) - volume_pos_x;
|
u = uint(round(intersection_pos.x)) - volume_pos_x;
|
||||||
v = uint(round(intersection_pos.y)) - volume_pos_y;
|
v = uint(round(intersection_pos.y)) - volume_pos_y;
|
||||||
|
result.end_pos = intersection_pos;
|
||||||
|
result.end_facing = hit_facing;
|
||||||
}
|
}
|
||||||
uint next_neighbor = sample_neighbor_from_scene_info(volume_index, uvec2(u, v), hit_facing);
|
uint next_neighbor = sample_neighbor_from_scene_info(volume_index, uvec2(u, v), hit_facing);
|
||||||
uvec4 color_sample = sample_color_from_scene_info(volume_index, uvec2(u, v), hit_facing);
|
uvec4 color_sample = sample_color_from_scene_info(volume_index, uvec2(u, v), hit_facing);
|
||||||
|
@ -237,43 +246,56 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa
|
||||||
volume_pos_y = scene_info.infos[volume_index + 1];
|
volume_pos_y = scene_info.infos[volume_index + 1];
|
||||||
volume_pos_z = scene_info.infos[volume_index + 2];
|
volume_pos_z = scene_info.infos[volume_index + 2];
|
||||||
} else {
|
} else {
|
||||||
// neightbor miss, shouldn't happen with a light inside of a volume. Might happen with ambient light. For now move on to next light.
|
// neightbor miss
|
||||||
needs_next_light = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// color hit, move on to next light (may change once transparents are implemnted)
|
|
||||||
needs_next_light = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (needs_next_light) {
|
|
||||||
light_num += 1;
|
|
||||||
if (light_num >= max_light_num) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// set up the new light
|
} else {
|
||||||
light_index = scene_info.infos[volume_start + 6 + light_num];
|
// color hit, move on
|
||||||
|
result.end_color = color_sample;
|
||||||
|
result.has_hit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.end_volume = volume_index;
|
||||||
|
result.end_factor = min(min(x_factor, y_factor), z_factor);
|
||||||
|
result.end_cycle = cycle;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sample) {
|
||||||
|
uint max_light_num = scene_info.infos[0];
|
||||||
|
uint light_num = 0;
|
||||||
|
|
||||||
|
// initialize color
|
||||||
|
vec3 color_sum = vec3(0.0, 0.0, 0.0) + (orig_color_sample.xyz * 0.01);
|
||||||
|
|
||||||
|
uint max_iterations = max_light_num * scene_info.infos[1];
|
||||||
|
uint iteration = 0;
|
||||||
|
while (iteration < max_iterations) {
|
||||||
|
// setup light info
|
||||||
|
uint light_index = scene_info.infos[volume_start + 6 + light_num];
|
||||||
if (light_index == 0) {
|
if (light_index == 0) {
|
||||||
// abort if there is no new light
|
// abort if there is no new light
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
light_direction = get_light_position(light_index) - starting_pos;
|
vec3 light_direction = get_light_position(light_index) - starting_pos;
|
||||||
light_color = get_light_color(light_index);
|
vec3 light_color = get_light_color(light_index);
|
||||||
|
|
||||||
x_pos = light_direction.x > 0.0;
|
Tracing result = trace_ray(volume_start, starting_pos, light_direction, 1.0, iteration, max_iterations);
|
||||||
x_null = (light_direction.x == 0.0);
|
if (!result.has_hit) {
|
||||||
|
// no hit, add light color result
|
||||||
|
color_sum += (orig_color_sample.xyz * light_color) / ((0.01 * length(light_direction) * length(light_direction)) + 1.0);
|
||||||
|
}
|
||||||
|
iteration = result.end_cycle;
|
||||||
|
|
||||||
y_pos = light_direction.y > 0.0;
|
light_num += 1;
|
||||||
y_null = (light_direction.y == 0.0);
|
if (light_num >= max_light_num) {
|
||||||
|
break;
|
||||||
z_pos = light_direction.z > 0.0;
|
|
||||||
z_null = (light_direction.z == 0.0);
|
|
||||||
// reset volume info
|
|
||||||
volume_index = volume_start;
|
|
||||||
volume_pos_x = scene_info.infos[volume_index + 0];
|
|
||||||
volume_pos_y = scene_info.infos[volume_index + 1];
|
|
||||||
volume_pos_z = scene_info.infos[volume_index + 2];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return color_sum;
|
return color_sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ impl PointLight {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_into_memory(&self, mut v: Vec<u32>) -> Vec<u32> {
|
pub fn insert_into_memory(&self, mut v: Vec<u32>) -> Vec<u32> {
|
||||||
v[self.memory_start] = self.pos.x as u32;
|
v[self.memory_start] = u32::from_ne_bytes(self.pos.x.to_ne_bytes());
|
||||||
v[self.memory_start + 1] = self.pos.y as u32;
|
v[self.memory_start + 1] = u32::from_ne_bytes(self.pos.y.to_ne_bytes());
|
||||||
v[self.memory_start + 2] = self.pos.z as u32;
|
v[self.memory_start + 2] = u32::from_ne_bytes(self.pos.z.to_ne_bytes());
|
||||||
|
|
||||||
v[self.memory_start + 3] = (self.color.x * 255.0) as u32;
|
v[self.memory_start + 3] = (self.color.x * 255.0) as u32;
|
||||||
v[self.memory_start + 4] = (self.color.y * 255.0) as u32;
|
v[self.memory_start + 4] = (self.color.y * 255.0) as u32;
|
||||||
|
|
Loading…
Add table
Reference in a new issue