transparency first version

This commit is contained in:
zomseffen 2025-01-30 11:03:30 +01:00
parent f0fa28bdd8
commit 66902df99c
14 changed files with 225 additions and 92 deletions

View file

@ -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)

View file

@ -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> {

View file

@ -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
));

View file

@ -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 {

View file

@ -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}
};

View file

@ -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)
}
}
}