diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv index c161614..8a2654c 100644 Binary files a/shaders/compiled/frag_rt_quad.spv and b/shaders/compiled/frag_rt_quad.spv differ diff --git a/shaders/compiled/vert_cube.spv b/shaders/compiled/vert_cube.spv index 7c214fa..668eeae 100644 Binary files a/shaders/compiled/vert_cube.spv and b/shaders/compiled/vert_cube.spv differ diff --git a/shaders/compiled/vert_cuboid.spv b/shaders/compiled/vert_cuboid.spv index e4f3503..239c7fb 100644 Binary files a/shaders/compiled/vert_cuboid.spv and b/shaders/compiled/vert_cuboid.spv differ diff --git a/shaders/compiled/vert_rt_quad.spv b/shaders/compiled/vert_rt_quad.spv index 87bf2ac..f89ceba 100644 Binary files a/shaders/compiled/vert_rt_quad.spv and b/shaders/compiled/vert_rt_quad.spv differ diff --git a/shaders/cube.vert b/shaders/cube.vert index 9e5c24b..7e1bf91 100644 --- a/shaders/cube.vert +++ b/shaders/cube.vert @@ -5,6 +5,7 @@ layout(binding = 0) uniform UniformBufferObject { mat4 geom_rot; mat4 view; mat4 proj; + vec3 camera_pos; bool[16] use_geom_shader; } ubo; diff --git a/shaders/cuboid.vert b/shaders/cuboid.vert index 99c6ccf..882c0b2 100644 --- a/shaders/cuboid.vert +++ b/shaders/cuboid.vert @@ -5,6 +5,7 @@ layout(binding = 0) uniform UniformBufferObject { mat4 geom_rot; mat4 view; mat4 proj; + vec3 camera_pos; bool[16] use_geom_shader; } ubo; diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag index bac8002..93b04be 100644 --- a/shaders/rt_quad.frag +++ b/shaders/rt_quad.frag @@ -7,6 +7,15 @@ layout(location = 3) flat in uint facing; layout(location = 0) out vec4 outColor; +layout(binding = 0) uniform UniformBufferObject { + mat4 model; + mat4 geom_rot; + mat4 view; + mat4 proj; + vec3 camera_pos; + bool[16] use_geom_shader; +} ubo; + layout(binding = 2) buffer SceneInfoBuffer{ uint infos[]; } scene_info; @@ -122,7 +131,7 @@ uvec4 sample_color_from_scene_info(uint volume_start, uvec2 raster_pos, uint f) uint vs[6] = {top_color_size_v, bottom_color_size_v, left_color_size_v, right_color_size_v, front_color_size_v, back_color_size_v}; uint u_size = us[f]; uint v_size = vs[f]; - uint value = scene_info.infos[array_start + raster_pos.x * v_size * uint(u_size > 1) + raster_pos.y * uint(v_size > 1)]; + uint value = scene_info.infos[array_start + clamp(raster_pos.x, 0, u_size) * v_size * uint(u_size > 1) + clamp(raster_pos.y, 0, v_size) * uint(v_size > 1)]; return unpack_color(value); } @@ -142,6 +151,8 @@ struct Tracing { float end_factor; uint end_cycle; bool has_hit; + vec3 color_mul; + uvec2 end_raster; }; Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 direction, float max_factor, uint start_cycle, uint max_cycle) { @@ -167,6 +178,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 direction, float ma float z_factor = max_factor; Tracing result; + result.color_mul = vec3(1.0, 1.0, 1.0); while (cycle < max_cycle) { cycle ++; @@ -250,10 +262,20 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 direction, float ma break; } } else { - // color hit, move on - result.end_color = color_sample; - result.has_hit = true; - break; + if (next_neighbor != 0) { + // transparent hit, move on but change the color + volume_index = next_neighbor; + 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]; + result.color_mul = result.color_mul * vec3(float(color_sample.x) / 255.0, float(color_sample.y) / 255.0, float(color_sample.z) / 255.0); + } else { + // color hit, move on + result.end_color = color_sample; + result.end_raster = uvec2(u, v); + result.has_hit = true; + break; + } } } } @@ -264,7 +286,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 direction, float ma return result; } -vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sample) { +vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sample, vec3 normal) { uint max_light_num = scene_info.infos[0]; uint light_num = 0; @@ -286,7 +308,7 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa Tracing result = trace_ray(volume_start, starting_pos, light_direction, 1.0, iteration, max_iterations); 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); + color_sum += result.color_mul * max(dot(normal, normalize(light_direction)), 0.0) * (orig_color_sample.xyz * light_color) / (length(light_direction) * length(light_direction)); } iteration = result.end_cycle; @@ -299,15 +321,33 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa return color_sum; } -void main() { - uint max_length = scene_info.infos[0]; - uint last = scene_info.infos[max_length]; - - uvec4 color_roughness = sample_color_from_scene_info(fragVolumeStart, fragRasterPos, facing); - vec4 orig_color_sample = vec4(float(color_roughness.x) / 255.0, float(color_roughness.y) / 255.0, float(color_roughness.z) / 255.0, 1); +vec3 normal_for_facing(uint facing) { + if (facing == 0) { + return vec3(0.0, 0.0, -1.0); + } + if (facing == 1) { + return vec3(0.0, 0.0, 1.0); + } + if (facing == 2) { + return vec3(0.0, 1.0, 0.0); + } + if (facing == 3) { + return vec3(0.0, -1.0, 0.0); + } + if (facing == 4) { + return vec3(1.0, 0.0, 0.0); + } + if (facing == 5) { + return vec3(-1.0, 0.0, 0.0); + } - // singular raytracing - //vec3 color_sum = get_lighting_color(fragVolumeStart, origPosition, orig_color_sample); + return vec3(0.0, 0.0, 0.0); +} + +vec3 diffuse_tracing(uint volume_start, uvec2 raster_pos, vec3 pos, uint f) { + uvec4 color_roughness = sample_color_from_scene_info(volume_start, raster_pos, f); + vec4 orig_color_sample = vec4(float(color_roughness.x) / 255.0, float(color_roughness.y) / 255.0, float(color_roughness.z) / 255.0, 1); + vec3 normal = normal_for_facing(f); // diffuse raytracing using a quadratic raster of rays int raster_half_steps = 0; @@ -317,16 +357,54 @@ void main() { vec3 color_sum = vec3(0.0, 0.0, 0.0); for (int u_offset = -raster_half_steps; u_offset <= raster_half_steps; u_offset++) { for (int v_offset = -raster_half_steps; v_offset <= raster_half_steps; v_offset++) { - float x_offset = raster_distance * float(u_offset) * float(facing == 0 || facing == 1 || facing == 4 || facing == 5); - float y_offset = raster_distance * float(u_offset) * float(facing == 2 || facing == 3); - y_offset += raster_distance * float(v_offset) * float(facing == 0 || facing == 1); - float z_offset = raster_distance * float(v_offset) * float(facing == 4 || facing == 5 || facing == 2 || facing == 3); + float x_offset = raster_distance * float(u_offset) * float(f == 0 || f == 1 || f == 4 || f == 5); + float y_offset = raster_distance * float(u_offset) * float(f == 2 || f == 3); + y_offset += raster_distance * float(v_offset) * float(f == 0 || f == 1); + float z_offset = raster_distance * float(v_offset) * float(f == 4 || f == 5 || f == 2 || f == 3); vec3 offset = vec3(x_offset, y_offset, z_offset); - color_sum += get_lighting_color(fragVolumeStart, origPosition + offset, orig_color_sample) / float(raster_points); + color_sum += get_lighting_color(volume_start, origPosition + offset, orig_color_sample, normal) / float(raster_points); } } + return color_sum; +} + +vec3 clamp_to_volume(uint volume_start, vec3 position) { + uint volume_pos_x = scene_info.infos[volume_start + 0]; + uint volume_pos_y = scene_info.infos[volume_start + 1]; + uint volume_pos_z = scene_info.infos[volume_start + 2]; + + float high_x_border = float(volume_pos_x + (scene_info.infos[volume_start + 3])) - 0.5; + float high_y_border = float(volume_pos_y + (scene_info.infos[volume_start + 4])) - 0.5; + float high_z_border = float(volume_pos_z + (scene_info.infos[volume_start + 5])) - 0.5; + + float low_x_border = float(volume_pos_x) - 0.5; + float low_y_border = float(volume_pos_y) - 0.5; + float low_z_border = float(volume_pos_z) - 0.5; + + return vec3(min(max(position.x, low_x_border), high_x_border), min(max(position.y, low_y_border), high_y_border), min(max(position.z, low_z_border), high_z_border)); +} + +void main() { + vec3 clamped_pos = clamp_to_volume(fragVolumeStart, origPosition); + vec3 color_sum = diffuse_tracing(fragVolumeStart, fragRasterPos, clamped_pos, facing); + + uint orig_neighbor = sample_neighbor_from_scene_info(fragVolumeStart, fragRasterPos, facing); + if (orig_neighbor != 0) { + float pos_infinity = uintBitsToFloat(0x7F800000); + Tracing t = trace_ray(fragVolumeStart, ubo.camera_pos, clamped_pos - ubo.camera_pos, 100.0, 0, 20); + if (t.has_hit) { + color_sum += diffuse_tracing(t.end_volume, t.end_raster, t.end_pos, t.end_facing); + } + else { + // Todo: hit sky box + color_sum += vec3(0.0, 0.0, 0.0); + } + + } + + outColor = vec4(color_sum, 1.0); } \ No newline at end of file diff --git a/shaders/rt_quad.vert b/shaders/rt_quad.vert index b027c8d..47b98b0 100644 --- a/shaders/rt_quad.vert +++ b/shaders/rt_quad.vert @@ -5,6 +5,7 @@ layout(binding = 0) uniform UniformBufferObject { mat4 geom_rot; mat4 view; mat4 proj; + vec3 camera_pos; bool[16] use_geom_shader; } ubo; diff --git a/src/buffer.rs b/src/buffer.rs index 15e96d5..13b0159 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -1,5 +1,6 @@ use anyhow::{anyhow, Result}; +use cgmath::Point3; use vulkanalia::prelude::v1_0::*; use std::mem::size_of; @@ -10,6 +11,7 @@ pub type Mat4 = cgmath::Matrix4<f32>; use crate::app_data; use crate::command_buffer; use crate::vertex::VertexContainer; +use crate::scene; pub unsafe fn create_buffer( instance: &Instance, @@ -163,9 +165,6 @@ pub unsafe fn create_index_buffer( vk::MemoryPropertyFlags::DEVICE_LOCAL, )?; - let index_buffer = index_buffer; - let index_buffer_memory = index_buffer_memory; - copy_buffer(device, data, staging_buffer, index_buffer, size)?; device.destroy_buffer(staging_buffer, None); @@ -181,6 +180,7 @@ pub struct UniformBufferObject { pub geom_rot: Mat4, pub view: Mat4, pub proj: Mat4, + pub camera_pos: Point3<f32>, pub use_geom_shader: [bool; 16], } @@ -192,7 +192,7 @@ pub unsafe fn create_descriptor_set_layout( .binding(0) .descriptor_type(vk::DescriptorType::UNIFORM_BUFFER) .descriptor_count(1) - .stage_flags(vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY); + .stage_flags(vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY | vk::ShaderStageFlags::FRAGMENT); let sampler_binding = vk::DescriptorSetLayoutBinding::builder() .binding(1) @@ -254,8 +254,8 @@ pub unsafe fn create_storage_buffers( device, data, data.scene_rt_memory_size, - vk::BufferUsageFlags::STORAGE_BUFFER, - vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, + vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::STORAGE_BUFFER, + vk::MemoryPropertyFlags::DEVICE_LOCAL, )?; data.storage_buffers.push(storage_buffer); @@ -265,6 +265,41 @@ pub unsafe fn create_storage_buffers( Ok(()) } +pub unsafe fn update_storage_buffer( + instance: &Instance, + device: &Device, + data: &app_data::AppData, + image_index: usize, + scene_handler: &scene::Scene, +) -> Result<()> { + let (staging_buffer, staging_buffer_memory) = create_buffer( + instance, + device, + data, + data.scene_rt_memory_size, + vk::BufferUsageFlags::TRANSFER_SRC, + vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, + )?; + + let memory = device.map_memory( + staging_buffer_memory, + 0, + data.scene_rt_memory_size, + vk::MemoryMapFlags::empty(), + )?; + + memcpy(scene_handler.rt_memory.as_ptr(), memory.cast(), scene_handler.rt_memory.len()); + + device.unmap_memory(staging_buffer_memory); + + copy_buffer(device, data, staging_buffer, data.storage_buffers[image_index], data.scene_rt_memory_size)?; + + device.destroy_buffer(staging_buffer, None); + device.free_memory(staging_buffer_memory, None); + + Ok(()) +} + pub unsafe fn create_descriptor_pool(device: &Device, data: &mut app_data::AppData) -> Result<()> { let ubo_size = vk::DescriptorPoolSize::builder() .type_(vk::DescriptorType::UNIFORM_BUFFER) diff --git a/src/main.rs b/src/main.rs index bda1050..2e8d209 100644 --- a/src/main.rs +++ b/src/main.rs @@ -257,7 +257,7 @@ impl App { self.update_uniform_buffer(image_index)?; if self.synchronized < MAX_FRAMES_IN_FLIGHT { - self.update_storage_buffer(image_index)?; + buffer::update_storage_buffer(&self.instance, &self.device, &self.data, image_index, &self.scene_handler)?; self.synchronized += 1 } @@ -434,7 +434,8 @@ impl App { ); let ubo = buffer::UniformBufferObject { model, geom_rot: rot_mat4, view, proj, - use_geom_shader: [self.data.use_geometry_shader, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]}; + use_geom_shader: [self.data.use_geometry_shader, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false], + camera_pos: self.cur_pos.clone()}; let memory = self.device.map_memory( self.data.uniform_buffers_memory[image_index], @@ -449,25 +450,10 @@ impl App { Ok(()) } - - unsafe fn update_storage_buffer(&mut self, image_index: usize) -> Result<()> { - let memory = self.device.map_memory( - self.data.storage_buffers_memory[image_index], - 0, - self.data.scene_rt_memory_size, - vk::MemoryMapFlags::empty(), - )?; - - memcpy(self.scene_handler.rt_memory.as_ptr(), memory.cast(), self.scene_handler.rt_memory.len()); - - self.device.unmap_memory(self.data.storage_buffers_memory[image_index]); - - Ok(()) - } } //================================================ -// Instance +// MARK: Instance //================================================ unsafe fn create_instance(window: &Window, entry: &Entry, data: &mut app_data::AppData) -> Result<Instance> { diff --git a/src/primitives/cube.rs b/src/primitives/cube.rs index 38d5f8f..31a760e 100644 --- a/src/primitives/cube.rs +++ b/src/primitives/cube.rs @@ -12,57 +12,57 @@ pub struct Cube{ pub transparent: bool, } -const cube_size: f32 = 0.48; +const CUBE_SIZE: f32 = 0.5; impl Drawable for Cube { fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene) { if *topology == vk::PrimitiveTopology::TRIANGLE_LIST { // 0 top left far scene.vertices.push(vertex::Vertex::new( - vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 + cube_size), + vec3(self.pos.x as f32 - CUBE_SIZE, self.pos.y as f32 + CUBE_SIZE, self.pos.z as f32 + CUBE_SIZE), self.color, self.tex_coord )); // 1 top right far scene.vertices.push(vertex::Vertex::new( - vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 + cube_size), + vec3(self.pos.x as f32 + CUBE_SIZE, self.pos.y as f32 + CUBE_SIZE, self.pos.z as f32 + CUBE_SIZE), self.color, self.tex_coord )); // 2 top left near scene.vertices.push(vertex::Vertex::new( - vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 + cube_size), + vec3(self.pos.x as f32 - CUBE_SIZE, self.pos.y as f32 - CUBE_SIZE, self.pos.z as f32 + CUBE_SIZE), self.color, self.tex_coord )); // 3 top right near scene.vertices.push(vertex::Vertex::new( - vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 + cube_size), + vec3(self.pos.x as f32 + CUBE_SIZE, self.pos.y as f32 - CUBE_SIZE, self.pos.z as f32 + CUBE_SIZE), self.color, self.tex_coord )); // 4 bottom left far scene.vertices.push(vertex::Vertex::new( - vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 - cube_size), + vec3(self.pos.x as f32 - CUBE_SIZE, self.pos.y as f32 + CUBE_SIZE, self.pos.z as f32 - CUBE_SIZE), self.color, self.tex_coord )); // 5 bottom right far scene.vertices.push(vertex::Vertex::new( - vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 - cube_size), + vec3(self.pos.x as f32 + CUBE_SIZE, self.pos.y as f32 + CUBE_SIZE, self.pos.z as f32 - CUBE_SIZE), self.color, self.tex_coord )); // 6 bottom left near scene.vertices.push(vertex::Vertex::new( - vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 - cube_size), + vec3(self.pos.x as f32 - CUBE_SIZE, self.pos.y as f32 - CUBE_SIZE, self.pos.z as f32 - CUBE_SIZE), self.color, self.tex_coord )); // 7 bottom right near scene.vertices.push(vertex::Vertex::new( - vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 - cube_size), + vec3(self.pos.x as f32 + CUBE_SIZE, self.pos.y as f32 - CUBE_SIZE, self.pos.z as f32 - CUBE_SIZE), self.color, self.tex_coord )); diff --git a/src/scene/empty_volume.rs b/src/scene/empty_volume.rs index 50961dc..7581195 100644 --- a/src/scene/empty_volume.rs +++ b/src/scene/empty_volume.rs @@ -1,7 +1,6 @@ use cgmath::Vector3; use std::cell::RefCell; -use std::collections::HashSet; use std::rc::Rc; use std::time::Instant; @@ -50,6 +49,14 @@ impl EmptyVolume { self.position[1] + self.size_y > pos[1] && pos[1] >= self.position[1] && self.position[2] + self.size_z > pos[2] && pos[2] >= self.position[2] } + + fn check_transparent(cube_result: Option<Cube>, transparent_color: &Vector3<f32>) -> bool { + if let Some(c) = cube_result { + return c.transparent && &c.color == transparent_color + } + false + } + // MARK: From Oct Tree pub fn from_oct_tree(tree: &OctTree<Cube>) -> (Vec<Rc<RefCell<EmptyVolume>>>, OctTree<Rc<RefCell<EmptyVolume>>>) { // todo: ppotentially use a child exist check while going through the oct tree to find some obvios starting empty volumes. Will still need to check for possible expansions though @@ -64,8 +71,14 @@ impl EmptyVolume { for z_index in 0..tree.size { // check if there is a block at that position let query_result = tree.test_element(x_index, y_index, z_index); - - if !query_result.0 { + let mut transparent = false; + let mut transparent_color = Vector3 {x: 0.0, y: 0.0, z: 0.0}; + if let Some(c) = query_result.3 { + transparent = c.transparent; + transparent_color = c.color; + } + if !query_result.0 || transparent { + //if not check that it is not already inside of a volume let mut contained = false; for volume in &volumes { @@ -99,7 +112,7 @@ impl EmptyVolume { while z < z_size.max(1) && y < y_size.max(1) { let query_result = tree.test_element(x_index + x_size + 1, y_index + y, z_index + z); check_its += 1; - grow &= !query_result.0 && + grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color))) && neighbors.get_element(x_index + x_size + 1, y_index + y, z_index + z).is_none(); if query_result.1 > 1 { @@ -146,7 +159,7 @@ impl EmptyVolume { while z < z_size.max(1) && x < x_size.max(1) { let query_result = tree.test_element(x_index + x, y_index + y_size + 1, z_index + z); check_its += 1; - grow &= !query_result.0 && + grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color))) && neighbors.get_element(x_index + x, y_index + y_size + 1, z_index + z).is_none(); if query_result.1 > 1 { @@ -194,7 +207,7 @@ impl EmptyVolume { while y < y_size.max(1) && x < x_size.max(1) { let query_result = tree.test_element(x_index + x, y_index + y, z_index + z_size + 1); check_its += 1; - grow &= !query_result.0 && + grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color))) && neighbors.get_element(x_index + x, y_index + y, z_index + z_size + 1).is_none(); if query_result.1 > 1 { @@ -683,12 +696,14 @@ impl EmptyVolume { for x in 0..self.size_x { for y in 0..self.size_y { let index = x * self.size_y + y; - if self.color_bottom.len() == 0 { + if self.color_bottom.len() <= index { continue; } if self.neighbor_bottom.len() > index { if let Some(_) = self.neighbor_bottom[index] { - continue; + if self.color_bottom[index] == (Vector3 {x: 0, y: 0, z: 0}) { + continue; + } } } let quad = Quad { @@ -707,12 +722,14 @@ impl EmptyVolume { for x in 0..self.size_x { for y in 0..self.size_y { let index = x * self.size_y + y; - if self.color_top.len() == 0 { + if self.color_top.len() <= 0 { continue; } if self.neighbor_top.len() > index { if let Some(_) = self.neighbor_top[index] { - continue; + if self.color_top[index] == (Vector3 {x: 0, y: 0, z: 0}) { + continue; + } } } let quad = Quad { @@ -732,12 +749,14 @@ impl EmptyVolume { for x in 0..self.size_x { for z in 0..self.size_z { let index = x * self.size_z + z; - if self.color_front.len() == 0 { + if self.color_front.len() <= 0 { continue; } if self.neighbor_front.len() > index { if let Some(_) = self.neighbor_front[index] { - continue; + if self.color_front[index] == (Vector3 {x: 0, y: 0, z: 0}) { + continue; + } } } let quad = Quad { @@ -757,12 +776,14 @@ impl EmptyVolume { for x in 0..self.size_x { for z in 0..self.size_z { let index = x * self.size_z + z; - if self.color_back.len() == 0 { + if self.color_back.len() <= 0 { continue; } if self.neighbor_back.len() > index { if let Some(_) = self.neighbor_back[index] { - continue; + if self.color_back[index] == (Vector3 {x: 0, y: 0, z: 0}) { + continue; + } } } let quad = Quad { @@ -782,12 +803,14 @@ impl EmptyVolume { for y in 0..self.size_y { for z in 0..self.size_z { let index = y * self.size_z + z; - if self.color_left.len() == 0 { + if self.color_left.len() <= 0 { continue; } if self.neighbor_left.len() > index { if let Some(_) = self.neighbor_left[index] { - continue; + if self.color_left[index] == (Vector3 {x: 0, y: 0, z: 0}) { + continue; + } } } let quad = Quad { @@ -807,12 +830,14 @@ impl EmptyVolume { for y in 0..self.size_y { for z in 0..self.size_z { let index = y * self.size_z + z; - if self.color_right.len() == 0 { + if self.color_right.len() <= 0 { continue; } if self.neighbor_right.len() > index { if let Some(_) = self.neighbor_right[index] { - continue; + if self.color_right[index] == (Vector3 {x: 0, y: 0, z: 0}) { + continue; + } } } let quad = Quad { diff --git a/src/scene/mod.rs b/src/scene/mod.rs index a91b1a8..c5703a7 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -11,7 +11,6 @@ use cgmath::{vec2, vec3, Vector3}; use std::cell::RefCell; use std::rc::Rc; -use crate::app_data; use crate::app_data::AppData; use crate::buffer; use crate::primitives::rec_cuboid::Cuboid; @@ -68,7 +67,7 @@ impl Scene { for x_index in 0..grid_size { for y_index in 0..grid_size { - let shade = (rng.gen_range(0..25) as f32) / 100.0; + let shade = (rng.gen_range(0..50) as f32) / 100.0; let cube = Cube { pos: vec3(x_index as f32, y_index as f32, 5.0), color: vec3(shade, 1.0, shade), @@ -83,17 +82,24 @@ impl Scene { let shade = (rng.gen_range(0..25) as f32) / 100.0; let cube = Cube { pos: vec3(10.0, 10.0, 10.0), - color: vec3(1.0, 1.0, 0.0), + color: vec3(1.0, 0.0, 0.0), tex_coord: vec2(0.0, 0.0), transparent: true, }; + oct_tree.set_cube(cube.clone()); + let cube = Cube { + pos: vec3(10.0, 10.0, 9.0), + color: vec3(1.0, 0.0, 0.0), + tex_coord: vec2(0.0, 0.0), + transparent: true, + }; oct_tree.set_cube(cube.clone()); self.point_lights.push(PointLight { pos: vec3(11.0, 11.0, 11.0), color: vec3(0.5, 0.5, 0.5), memory_start: 0 }); self.point_lights.push(PointLight { pos: vec3(9.0, 9.0, 11.0), color: vec3(0.5, 0.5, 0.5), memory_start: 0 }); - let mut empty_volumes: Vec<Rc<RefCell<EmptyVolume>>>; + let empty_volumes: Vec<Rc<RefCell<EmptyVolume>>>; (empty_volumes, _) = EmptyVolume::from_oct_tree(&oct_tree); println!("number of empty volumes is {}", empty_volumes.len()); @@ -124,7 +130,7 @@ impl Scene { let cube = Cuboid { pos: vec3(11.0, 11.0, 11.0), - color: vec3(shade, 1.0, shade), + color: vec3(1.0, 1.0, 1.0), tex_coord: vec2(0.0, 0.0), size: Vector3 {x: 0.5, y: 0.5, z: 0.5} }; @@ -133,7 +139,7 @@ impl Scene { let cube = Cuboid { pos: vec3(9.0, 9.0, 11.0), - color: vec3(shade, 1.0, shade), + color: vec3(1.0, 1.0, 1.0), tex_coord: vec2(0.0, 0.0), size: Vector3 {x: 0.5, y: 0.5, z: 0.5} }; diff --git a/src/scene/oct_tree.rs b/src/scene/oct_tree.rs index bdab4db..7b8212d 100644 --- a/src/scene/oct_tree.rs +++ b/src/scene/oct_tree.rs @@ -7,7 +7,7 @@ use crate::primitives::cube::Cube; extern crate rand; -pub const CHUNK_SIZE_EXPONENT: u32 = 8; +pub const CHUNK_SIZE_EXPONENT: u32 = 6; pub const CHUNK_SIZE: usize = (2 as usize).pow(CHUNK_SIZE_EXPONENT); pub const MAX_TREE_DEPTH: usize = CHUNK_SIZE_EXPONENT as usize - 2; pub const MIN_CHUNK_SIZE: usize = CHUNK_SIZE / (2 as usize).pow(MAX_TREE_DEPTH as u32); @@ -378,13 +378,13 @@ impl<T: Clone> OctTree<T> { } } - pub fn test_element(&self, x: usize, y: usize, z: usize) -> (bool, usize, (usize, usize, usize)) { + pub fn test_element(&self, x: usize, y: usize, z: usize) -> (bool, usize, (usize, usize, usize), Option<T>) { self.test_element_internal(x, y, z, 0, 0, 0) } - fn test_element_internal(&self, x: usize, y: usize, z: usize, node_start_x: usize, node_start_y: usize, node_start_z: usize) -> (bool, usize, (usize, usize, usize)) { + fn test_element_internal(&self, x: usize, y: usize, z: usize, node_start_x: usize, node_start_y: usize, node_start_z: usize) -> (bool, usize, (usize, usize, usize), Option<T>) { if x >= self.size || y >= self.size || z >= self.size { - return (false, 0, (0, 0, 0)) + return (false, 0, (0, 0, 0), None) } if self.size > MIN_CHUNK_SIZE { @@ -396,7 +396,7 @@ impl<T: Clone> OctTree<T> { Some(child) => { child.borrow().test_element_internal(x - mid_point, y - mid_point, z - mid_point, node_start_x + mid_point, node_start_y + mid_point, node_start_z + mid_point) }, - None => (false, mid_point, (node_start_x + mid_point, node_start_y + mid_point, node_start_z + mid_point)) + None => (false, mid_point, (node_start_x + mid_point, node_start_y + mid_point, node_start_z + mid_point), None) } } else { @@ -404,7 +404,7 @@ impl<T: Clone> OctTree<T> { Some(child) => { child.borrow().test_element_internal( x - mid_point, y - mid_point, z, node_start_x + mid_point, node_start_y + mid_point, node_start_z) }, - None => (false, mid_point, (node_start_x + mid_point, node_start_y + mid_point, node_start_z)) + None => (false, mid_point, (node_start_x + mid_point, node_start_y + mid_point, node_start_z), None) } } } @@ -414,7 +414,7 @@ impl<T: Clone> OctTree<T> { Some(child) => { child.borrow().test_element_internal(x - mid_point, y, z - mid_point, node_start_x + mid_point, node_start_y, node_start_z + mid_point) }, - None => (false, mid_point, (node_start_x + mid_point, node_start_y, node_start_z + mid_point)) + None => (false, mid_point, (node_start_x + mid_point, node_start_y, node_start_z + mid_point), None) } } else { @@ -422,7 +422,7 @@ impl<T: Clone> OctTree<T> { Some(child) => { child.borrow().test_element_internal(x - mid_point, y, z, node_start_x + mid_point, node_start_y, node_start_z) }, - None => (false, mid_point, (node_start_x + mid_point, node_start_y, node_start_z)) + None => (false, mid_point, (node_start_x + mid_point, node_start_y, node_start_z), None) } } } @@ -434,7 +434,7 @@ impl<T: Clone> OctTree<T> { Some(child) => { child.borrow().test_element_internal(x, y - mid_point, z - mid_point, node_start_x, node_start_y + mid_point, node_start_z + mid_point) }, - None => (false, mid_point, (node_start_x, node_start_y + mid_point, node_start_z + mid_point)) + None => (false, mid_point, (node_start_x, node_start_y + mid_point, node_start_z + mid_point), None) } } else { @@ -442,7 +442,7 @@ impl<T: Clone> OctTree<T> { Some(child) => { child.borrow().test_element_internal(x, y - mid_point, z, node_start_x, node_start_y + mid_point, node_start_z) }, - None => (false, mid_point, (node_start_x, node_start_y + mid_point, node_start_z)) + None => (false, mid_point, (node_start_x, node_start_y + mid_point, node_start_z), None) } } } @@ -452,7 +452,7 @@ impl<T: Clone> OctTree<T> { Some(child) => { child.borrow().test_element_internal(x, y, z - mid_point, node_start_x, node_start_y, node_start_z + mid_point) }, - None => (false, mid_point, (node_start_x, node_start_y, node_start_z + mid_point)) + None => (false, mid_point, (node_start_x, node_start_y, node_start_z + mid_point), None) } } else { @@ -460,18 +460,18 @@ impl<T: Clone> OctTree<T> { Some(child) => { child.borrow().test_element_internal(x, y, z, node_start_x, node_start_y, node_start_z) }, - None => (false, mid_point, (node_start_x , node_start_y, node_start_z)) + None => (false, mid_point, (node_start_x , node_start_y, node_start_z), None) } } } } } else { - if let Some(_) = self.blocks[z * MIN_CHUNK_SIZE * MIN_CHUNK_SIZE + y * MIN_CHUNK_SIZE + x] { - (true, 1, (x, y, z)) + if let Some(c) = &self.blocks[z * MIN_CHUNK_SIZE * MIN_CHUNK_SIZE + y * MIN_CHUNK_SIZE + x] { + (true, 1, (x, y, z), Some(c.clone())) } else { - (false, 1, (x, y, z)) + (false, 1, (x, y, z), None) } } }