renamed brick to block, world gen stuff in separate file

This commit is contained in:
Piotrek
2021-04-25 16:22:24 +02:00
parent 9718ea68dd
commit 1bb45ec31b
15 changed files with 223 additions and 220 deletions
+6 -50
View File
@@ -2,8 +2,9 @@ use winit::{
event::{Event, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode, MouseButton}, event::{Event, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode, MouseButton},
window::Window window::Window
}; };
use cgmath::Point3;
use std::sync::Arc; use std::sync::Arc;
use rand::Rng;
mod camera_controller; use camera_controller::CameraController; mod camera_controller; use camera_controller::CameraController;
mod world_gen; use world_gen::WorldGen; mod world_gen; use world_gen::WorldGen;
@@ -23,61 +24,16 @@ impl App {
let camera_controller = CameraController::new(); let camera_controller = CameraController::new();
let mut world_gen = WorldGen::new(); let mut world_gen = WorldGen::new();
// let start = std::time::Instant::now();
// for x in 0..128 {
// for z in 0..128 {
// // Dirt
// for y in 0..31 {
// renderer.set_voxel(x, y, z, 1);
// }
// // Grass
// renderer.set_voxel(x, 31, z, 2);
// }
// }
// println!("Generated in {}ms", start.elapsed().as_millis());
let mut rng = rand::thread_rng();
let start = std::time::Instant::now(); let start = std::time::Instant::now();
for x in 0..32 {
// Ground for y in 0..16 {
for bx in 0..16 { for z in 0..32 {
for bz in 0..16 { world_gen.generate(&mut renderer, Point3{x, y, z});
let brick_id = renderer.brick_get_id(bx, 0, bz, true);
for x in 0..32 {
for z in 0..32 {
// Dirt
renderer.brick_set_voxel(brick_id, x, 0, z, 1);
// Grass
let h = (rng.gen::<f32>() * 5.0) as usize;
for y in 1..h {
renderer.brick_set_voxel(brick_id, x, y, z, 2);
}
}
} }
} }
} }
// Wall
for bz in 4..8 {
for by in 0..4 {
// Brick
let brick_id = renderer.brick_get_id(8, by, bz, true);
for x in 14..18 {
for z in 0..32 {
for y in 0..32 {
renderer.brick_set_voxel(brick_id, x, y, z, 3);
}
}
}
}
}
println!("Generated in {}ms", start.elapsed().as_millis()); println!("Generated in {}ms", start.elapsed().as_millis());
Self { window, renderer, camera_controller, world_gen } Self { window, renderer, camera_controller, world_gen }
} }
+42 -2
View File
@@ -1,4 +1,6 @@
use std::sync::Arc; use cgmath::{Point3, InnerSpace};
use rand::Rng;
use crate::renderer::Renderer; use crate::renderer::Renderer;
pub struct WorldGen { pub struct WorldGen {
@@ -11,6 +13,44 @@ impl WorldGen {
Self{} Self{}
} }
pub fn generate(&mut self, renderer: Renderer) { pub fn generate(&mut self, renderer: &mut Renderer, pos: Point3<usize>) {
let mut rng = rand::thread_rng();
let mut apply = false;
let block_id = renderer.block_get_id(pos, false);
// Generate grass on ground
if pos.y == 0 {
for x in 0..32 {
for z in 0..32 {
// Dirt
renderer.block_set_voxel(block_id, x, 0, z, 1);
// Grass
if rng.gen::<f32>() < 0.3 {
let h = (rng.gen::<f32>() * 5.0) as usize;
for y in 1..h {
renderer.block_set_voxel(block_id, x, y, z, 2);
}
}
}
}
apply = true;
}
// Generate wall
if pos.x == 8 && pos.y < 3 && pos.z < 8 && pos.z > 4 {
for z in 0..32 {
for y in 0..32 {
renderer.block_set_voxel(block_id, 16, y, z, 3);
}
}
apply = true;
}
// Apply
if apply {
if block_id != renderer.block_get_id(pos, true) {
panic!("Block already consumed?");
}
}
} }
} }
@@ -1,18 +1,18 @@
use std::convert::TryInto; use std::convert::TryInto;
use crate::renderer::buffers::{BRICK_SIZE, BRICK_NUM, BRICK_LEN}; use crate::renderer::buffers::{BLOCK_SIZE, BLOCK_NUM, BLOCK_LEN};
const DATA_LEN : usize = BRICK_LEN * BRICK_NUM; const DATA_LEN : usize = BLOCK_LEN * BLOCK_NUM;
pub struct BrickBuffer { pub struct Blocks {
pub bricks: Box<[u8]>, pub blocks: Box<[u8]>,
pub free_brick: usize, pub free_block: usize,
texture: wgpu::Texture, texture: wgpu::Texture,
pub bind_layout: wgpu::BindGroupLayout, pub bind_layout: wgpu::BindGroupLayout,
pub bind_group: wgpu::BindGroup pub bind_group: wgpu::BindGroup
} }
impl BrickBuffer { impl Blocks {
/* /*
* Create buffer in memory and gpu * Create buffer in memory and gpu
@@ -20,7 +20,7 @@ impl BrickBuffer {
pub fn new(device: &wgpu::Device) -> Self { pub fn new(device: &wgpu::Device) -> Self {
// Create texture // Create texture
let size = wgpu::Extent3d { width: BRICK_SIZE as u32, height: BRICK_SIZE as u32, depth: (BRICK_SIZE*BRICK_NUM) as u32 }; let size = wgpu::Extent3d { width: BLOCK_SIZE as u32, height: BLOCK_SIZE as u32, depth: (BLOCK_SIZE*BLOCK_NUM) as u32 };
let texture = device.create_texture( let texture = device.create_texture(
&wgpu::TextureDescriptor { &wgpu::TextureDescriptor {
size: size, size: size,
@@ -29,7 +29,7 @@ impl BrickBuffer {
dimension: wgpu::TextureDimension::D3, dimension: wgpu::TextureDimension::D3,
format: wgpu::TextureFormat::R8Uint, format: wgpu::TextureFormat::R8Uint,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST, // STORAGE? usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST, // STORAGE?
label: Some("Brick texture"), label: Some("block texture"),
} }
); );
@@ -68,49 +68,50 @@ impl BrickBuffer {
wgpu::BindGroupEntry { binding: 0, resource: wgpu::BindingResource::TextureView(&view) }, wgpu::BindGroupEntry { binding: 0, resource: wgpu::BindingResource::TextureView(&view) },
wgpu::BindGroupEntry { binding: 1, resource: wgpu::BindingResource::Sampler(&sampler) } wgpu::BindGroupEntry { binding: 1, resource: wgpu::BindingResource::Sampler(&sampler) }
], ],
label: Some("Brick texture group"), label: Some("block texture group"),
} }
); );
// Data // Data
let mut bricks = vec![0_u8; DATA_LEN].into_boxed_slice(); let mut blocks = vec![0_u8; DATA_LEN].into_boxed_slice();
bricks[0] = 1; blocks[0] = 1;
println!("Brick buffer size: {} MB", DATA_LEN as f32 / 1024.0 / 1024.0); println!("block buffer size: {} MB", DATA_LEN as f32 / 1024.0 / 1024.0);
// Done // Done
Self { bricks, texture, bind_layout, bind_group, free_brick: 0 } Self { blocks, texture, bind_layout, bind_group, free_block: 0 }
} }
/* /*
Write brick data to gpu, should be called to apply changes Write block data to gpu, should be called to apply changes
offset: Brick index to copy offset: block index to copy
*/ */
pub fn write(&mut self, queue: &wgpu::Queue, brick: usize) { pub fn write(&mut self, queue: &wgpu::Queue, block: usize) {
// Get first brick // Get first block
let brick_offset = brick*BRICK_LEN; let block_offset = block*BLOCK_LEN;
let brick_bytes : [u8;BRICK_LEN] = self.bricks[brick_offset..brick_offset+BRICK_LEN].try_into().unwrap(); let block_bytes : [u8;BLOCK_LEN] = self.blocks[block_offset..block_offset+BLOCK_LEN].try_into().unwrap();
let brick_size = wgpu::Extent3d{ width: BRICK_SIZE as u32, height: BRICK_SIZE as u32, depth: BRICK_SIZE as u32 }; let block_size = wgpu::Extent3d{ width: BLOCK_SIZE as u32, height: BLOCK_SIZE as u32, depth: BLOCK_SIZE as u32 };
let brick_origin = wgpu::Origin3d{ x:0, y:0, z: (brick*BRICK_SIZE) as u32 }; let block_origin = wgpu::Origin3d{ x:0, y:0, z: (block*BLOCK_SIZE) as u32 };
// Write // Write
queue.write_texture( queue.write_texture(
wgpu::TextureCopyView { texture: &self.texture, mip_level: 0, origin: brick_origin }, wgpu::TextureCopyView { texture: &self.texture, mip_level: 0, origin: block_origin },
&brick_bytes, &block_bytes,
wgpu::TextureDataLayout { offset: 0, bytes_per_row: brick_size.width, rows_per_image: brick_size.height }, wgpu::TextureDataLayout { offset: 0, bytes_per_row: block_size.width, rows_per_image: block_size.height },
brick_size block_size
); );
} }
/* /*
* Get id of next free brick * Get id of next free block
* Later: reusing old bricks * Later: reusing old blocks
*/ */
pub fn next_brick(&mut self) -> usize { pub fn next_block(&mut self, consume: bool) -> usize {
if self.free_brick >= self.bricks.len() { if self.free_block >= self.blocks.len() {
panic!("No more free bricks! we should consider reusing bricks..."); panic!("No more free blocks! we should consider reusing blocks...");
} }
self.free_brick += 1; let next = self.free_block + 1;
self.free_brick if consume { self.free_block = next; }
next
} }
} }
@@ -1,37 +1,38 @@
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
use cgmath::Point3;
#[repr(C)] #[repr(C)]
#[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
struct Material { struct Material {
pub albedo: [f32; 4], pub albedo: [f32; 3],
pub specular: f32,
} }
impl Material { impl Material {
pub fn set_albedo(&mut self, r: f32, g: f32, b:f32) pub fn set(&mut self, color: Point3<f32>, specular: f32)
{ {
self.albedo[0] = r; self.albedo = color.into();
self.albedo[1] = g; self.specular = specular;
self.albedo[2] = b;
} }
} }
pub struct MaterialBuffer { pub struct Materials {
#[allow(dead_code)]
materials: [Material; 256], materials: [Material; 256],
pub buffer: wgpu::Buffer, pub buffer: wgpu::Buffer,
pub bind_layout: wgpu::BindGroupLayout, pub bind_layout: wgpu::BindGroupLayout,
pub bind_group: wgpu::BindGroup pub bind_group: wgpu::BindGroup
} }
impl MaterialBuffer { impl Materials {
pub fn new(device: &wgpu::Device) -> Self { pub fn new(device: &wgpu::Device) -> Self {
// Create values // Create values
let mut materials: [Material; 256] = [Default::default(); 256]; let mut materials: [Material; 256] = [Default::default(); 256];
materials[0].set_albedo(0.41,0.33,0.20); materials[0].set(Point3{x:0.41, y:0.33, z:0.20}, 0.0); // Dirt
materials[1].set_albedo(0.15,0.5,0.05); materials[1].set(Point3{x:0.15, y:0.50, z:0.05}, 0.3); // Grass
materials[2].set_albedo(0.8,0.8,0.8); materials[2].set(Point3{x:0.90, y:0.90, z:0.90}, 1.0); // White
// Create buffer // Create buffer
let buffer = device.create_buffer_init( let buffer = device.create_buffer_init(
@@ -70,6 +71,6 @@ impl MaterialBuffer {
}); });
// Done // Done
MaterialBuffer { buffer, materials, bind_layout, bind_group } Materials { buffer, materials, bind_layout, bind_group }
} }
} }
+15 -15
View File
@@ -4,25 +4,25 @@
pub const WORLD_SIZE: usize = 32; pub const WORLD_SIZE: usize = 32;
pub const NUM_NODES: usize = (WORLD_SIZE*WORLD_SIZE*WORLD_SIZE) as usize; pub const NUM_NODES: usize = (WORLD_SIZE*WORLD_SIZE*WORLD_SIZE) as usize;
pub const BRICK_SIZE : usize = 32; // 32x32x32 brick size pub const BLOCK_SIZE : usize = 32; // 32x32x32 brick size
pub const BRICK_NUM : usize = 32768; // max bricks in texture pub const BLOCK_NUM : usize = 32768; // max bricks in texture
pub const BRICK_LEN : usize = BRICK_SIZE*BRICK_SIZE*BRICK_SIZE; pub const BLOCK_LEN : usize = BLOCK_SIZE*BLOCK_SIZE*BLOCK_SIZE;
// Import names // Import names
mod node_buffer; mod nodes;
pub use node_buffer::NodeBuffer; pub use nodes::Nodes;
mod brick_buffer; mod blocks;
pub use brick_buffer::{BrickBuffer}; pub use blocks::Blocks;
mod uniform_buffer; mod uniform;
pub use uniform_buffer::UniformBuffer; pub use uniform::Uniform;
pub use uniform_buffer::UniformValues; pub use uniform::UniformValues;
mod raster_buffer; mod raster;
pub use raster_buffer::RasterBuffer; pub use raster::Raster;
pub use raster_buffer::Vertex; pub use raster::Vertex;
mod material_buffer; mod materials;
pub use material_buffer::MaterialBuffer; pub use materials::Materials;
@@ -3,7 +3,7 @@ use rand::prelude::*;
use crate::renderer::buffers::{WORLD_SIZE, NUM_NODES}; use crate::renderer::buffers::{WORLD_SIZE, NUM_NODES};
pub struct NodeBuffer { pub struct Nodes {
pub nodes: Box<[u32]>, pub nodes: Box<[u32]>,
texture: wgpu::Texture, texture: wgpu::Texture,
size: wgpu::Extent3d, size: wgpu::Extent3d,
@@ -11,7 +11,7 @@ pub struct NodeBuffer {
pub bind_group: wgpu::BindGroup pub bind_group: wgpu::BindGroup
} }
impl NodeBuffer { impl Nodes {
pub fn new(device: &wgpu::Device) -> Self { pub fn new(device: &wgpu::Device) -> Self {
@@ -40,13 +40,13 @@ const VERTICES: &[Vertex] = &[
pub const INDICES: &[u16] = &[ 0, 1, 3, 3, 1, 2 ]; pub const INDICES: &[u16] = &[ 0, 1, 3, 3, 1, 2 ];
pub struct RasterBuffer { pub struct Raster {
pub vertex_buffer: wgpu::Buffer, pub vertex_buffer: wgpu::Buffer,
pub index_buffer: wgpu::Buffer, pub index_buffer: wgpu::Buffer,
pub index_len: u32 pub index_len: u32
} }
impl RasterBuffer { impl Raster {
pub fn new(device: &wgpu::Device) -> Self { pub fn new(device: &wgpu::Device) -> Self {
// Create vertex buffer // Create vertex buffer
@@ -32,14 +32,14 @@ impl UniformValues {
} }
pub struct UniformBuffer { pub struct Uniform {
pub values: UniformValues, pub values: UniformValues,
pub buffer: wgpu::Buffer, pub buffer: wgpu::Buffer,
pub bind_layout: wgpu::BindGroupLayout, pub bind_layout: wgpu::BindGroupLayout,
pub bind_group: wgpu::BindGroup, pub bind_group: wgpu::BindGroup,
} }
impl UniformBuffer { impl Uniform {
pub fn new(device: &wgpu::Device) -> Self { pub fn new(device: &wgpu::Device) -> Self {
// Create values // Create values
let values = UniformValues::new(); let values = UniformValues::new();
@@ -81,7 +81,7 @@ impl UniformBuffer {
}); });
// Done // Done
UniformBuffer { buffer, values, bind_layout, bind_group } Uniform { buffer, values, bind_layout, bind_group }
} }
} }
+32 -74
View File
@@ -1,7 +1,11 @@
use winit::{window::Window, dpi::PhysicalSize}; use winit::{window::Window, dpi::PhysicalSize};
use cgmath::{Point3};
mod buffers; mod buffers;
use buffers::{NodeBuffer, BrickBuffer, UniformBuffer, RasterBuffer, Vertex, MaterialBuffer}; use buffers::{Nodes, Blocks, Uniform, Raster, Materials};
mod passes;
use passes::RaytracePass;
pub mod camera; use camera::Camera; pub mod camera; use camera::Camera;
@@ -12,13 +16,13 @@ pub struct Renderer {
queue: wgpu::Queue, queue: wgpu::Queue,
swapchain_desc: wgpu::SwapChainDescriptor, swapchain_desc: wgpu::SwapChainDescriptor,
swapchain: wgpu::SwapChain, swapchain: wgpu::SwapChain,
pipeline: wgpu::RenderPipeline, raytrace: RaytracePass,
// Buffers // Buffers
raster_buffer: RasterBuffer, raster_buffer: Raster,
uniform_buffer: UniformBuffer, uniform_buffer: Uniform,
node_buffer: NodeBuffer, node_buffer: Nodes,
brick_buffer: BrickBuffer, brick_buffer: Blocks,
material_buffer: MaterialBuffer, material_buffer: Materials,
// Other // Other
pub camera: Camera, pub camera: Camera,
start: std::time::Instant, start: std::time::Instant,
@@ -39,53 +43,6 @@ impl Renderer {
(swapchain_desc, swapchain) (swapchain_desc, swapchain)
} }
fn create_pipeline(device: &wgpu::Device, swapchain_desc: &wgpu::SwapChainDescriptor, bind_group_layouts: &[&wgpu::BindGroupLayout]) -> wgpu::RenderPipeline{
// Pipeline stuff
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Render Pipeline Layout"),
bind_group_layouts: bind_group_layouts,
push_constant_ranges: &[],
});
let vert_state = wgpu::VertexState { //vert
module: &device.create_shader_module(&wgpu::include_spirv!("..\\shaders\\bin\\shader.vert.spv")),
entry_point: "main",
buffers: &[Vertex::desc()],
};
let frag_state = wgpu::FragmentState { // frag
module: &device.create_shader_module(&wgpu::include_spirv!("..\\shaders\\bin\\shader.frag.spv")),
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: swapchain_desc.format,
alpha_blend: wgpu::BlendState::REPLACE,
color_blend: wgpu::BlendState::REPLACE,
write_mask: wgpu::ColorWrite::ALL,
}],
};
let prim_state = wgpu::PrimitiveState { // primitive
topology: wgpu::PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: wgpu::FrontFace::Cw,
cull_mode: wgpu::CullMode::Back,
polygon_mode: wgpu::PolygonMode::Fill,
};
let multisample_state = wgpu::MultisampleState { // multisample
count: 1,
mask: !0,
alpha_to_coverage_enabled: false,
};
// Create pipeline
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Render Pipeline"),
layout: Some(&pipeline_layout),
vertex: vert_state,
fragment: Some(frag_state),
primitive: prim_state,
depth_stencil: None,
multisample: multisample_state,
})
}
/* /*
* Initializes renderer and all buffers * Initializes renderer and all buffers
*/ */
@@ -112,11 +69,11 @@ impl Renderer {
let camera = Camera::new(aspect, 60.0); let camera = Camera::new(aspect, 60.0);
// Buffers // Buffers
let uniform_buffer = UniformBuffer::new(&device); let uniform_buffer = Uniform::new(&device);
let raster_buffer = RasterBuffer::new(&device); let raster_buffer = Raster::new(&device);
let node_buffer = NodeBuffer::new(&device); let node_buffer = Nodes::new(&device);
let brick_buffer = BrickBuffer::new(&device); let brick_buffer = Blocks::new(&device);
let material_buffer = MaterialBuffer::new(&device); let material_buffer = Materials::new(&device);
// Pipeline // Pipeline
let bind_layouts = [ let bind_layouts = [
@@ -125,13 +82,13 @@ impl Renderer {
&brick_buffer.bind_layout, &brick_buffer.bind_layout,
&material_buffer.bind_layout &material_buffer.bind_layout
]; ];
let pipeline = Self::create_pipeline(&device, &swapchain_desc, &bind_layouts); let raytrace = RaytracePass::new(&device, &swapchain_desc, &bind_layouts);
// Save values in app // Save values in app
println!("Initialized"); println!("Initialized");
let start = std::time::Instant::now(); let start = std::time::Instant::now();
let changed_bricks: Vec<usize> = Vec::new(); let changed_bricks: Vec<usize> = Vec::new();
Self { surface, device, queue, swapchain_desc, swapchain, pipeline, raster_buffer, uniform_buffer, node_buffer, brick_buffer, material_buffer, camera, start, changed_bricks } Self { surface, device, queue, swapchain_desc, swapchain, raytrace, raster_buffer, uniform_buffer, node_buffer, brick_buffer, material_buffer, camera, start, changed_bricks }
} }
/* /*
@@ -193,7 +150,7 @@ impl Renderer {
}); });
// Data // Data
render_pass.set_pipeline(&self.pipeline); render_pass.set_pipeline(&self.raytrace.pipeline);
render_pass.set_bind_group(0, &self.uniform_buffer.bind_group, &[]); render_pass.set_bind_group(0, &self.uniform_buffer.bind_group, &[]);
render_pass.set_bind_group(1, &self.node_buffer.bind_group, &[]); render_pass.set_bind_group(1, &self.node_buffer.bind_group, &[]);
render_pass.set_bind_group(2, &self.brick_buffer.bind_group, &[]); render_pass.set_bind_group(2, &self.brick_buffer.bind_group, &[]);
@@ -202,6 +159,7 @@ impl Renderer {
render_pass.set_vertex_buffer(0, self.raster_buffer.vertex_buffer.slice(..)); render_pass.set_vertex_buffer(0, self.raster_buffer.vertex_buffer.slice(..));
render_pass.set_index_buffer(self.raster_buffer.index_buffer.slice(..), wgpu::IndexFormat::Uint16); render_pass.set_index_buffer(self.raster_buffer.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
render_pass.draw_indexed(0..self.raster_buffer.index_len, 0, 0..1); render_pass.draw_indexed(0..self.raster_buffer.index_len, 0, 0..1);
} }
// Submit encoder (command buffer) // Submit encoder (command buffer)
@@ -216,43 +174,43 @@ impl Renderer {
*/ */
#[allow(dead_code)] #[allow(dead_code)]
pub fn set_voxel(&mut self, x: usize, y: usize, z:usize, value: u8) { pub fn set_voxel(&mut self, x: usize, y: usize, z:usize, value: u8) {
let brick_id = self.brick_get_id(x/32, y/32, z/32, true); let brick_id = self.block_get_id(Point3{x:x/32, y:y/32, z:z/32}, true);
self.brick_set_voxel(brick_id, x%32, y%32, z%32, value); self.block_set_voxel(brick_id, x%32, y%32, z%32, value);
} }
/* /*
* Create or update brick at given location * Create or update brick at given location
*/ */
pub fn brick_set_voxel(&mut self, brick_id:usize, x: usize, y: usize, z:usize, value: u8) { pub fn block_set_voxel(&mut self, brick_id:usize, x: usize, y: usize, z:usize, value: u8) {
let voxel_id = x + buffers::BRICK_SIZE * (y + buffers::BRICK_SIZE * z); let voxel_id = x + buffers::BLOCK_SIZE * (y + buffers::BLOCK_SIZE * z);
let brick_offset = brick_id * buffers::BRICK_LEN; let brick_offset = brick_id * buffers::BLOCK_LEN;
self.brick_buffer.bricks[brick_offset + voxel_id] = value; self.brick_buffer.blocks[brick_offset + voxel_id] = value;
} }
/* /*
* Gets brick id * Gets brick id
*/ */
pub fn brick_get_id(&mut self, x: usize, y: usize, z:usize, mark_changed: bool) -> usize { pub fn block_get_id(&mut self, pos: Point3<usize>, apply: bool) -> usize {
// Get node // Get node
let node_idx = x + buffers::WORLD_SIZE * (y + buffers::WORLD_SIZE * z); let node_idx = pos.x + buffers::WORLD_SIZE * (pos.y + buffers::WORLD_SIZE * pos.z);
let mut node_value = self.node_buffer.nodes[node_idx]; let mut node_value = self.node_buffer.nodes[node_idx];
// Use new brick if neccesary // Use new brick if neccesary
if node_value == 0 { if node_value == 0 {
node_value = self.brick_buffer.next_brick() as u32; node_value = self.brick_buffer.next_block(apply) as u32;
self.node_buffer.nodes[node_idx] = node_value; if apply { self.node_buffer.nodes[node_idx] = node_value; }
} }
// Get brick id from node value // Get brick id from node value
let brick_id = (node_value - 1) as usize; let brick_id = (node_value - 1) as usize;
if mark_changed { self.brick_mark_changed(brick_id); } if apply { self.block_mark_changed(brick_id); }
brick_id brick_id
} }
/* /*
* Marks brick as changed * Marks brick as changed
*/ */
pub fn brick_mark_changed(&mut self, brick_id:usize) { pub fn block_mark_changed(&mut self, brick_id:usize) {
if !self.changed_bricks.contains(&brick_id) { if !self.changed_bricks.contains(&brick_id) {
self.changed_bricks.push(brick_id); self.changed_bricks.push(brick_id);
} }
+3
View File
@@ -0,0 +1,3 @@
mod raytrace;
pub use raytrace::RaytracePass;
+57
View File
@@ -0,0 +1,57 @@
use crate::renderer::buffers::Vertex;
pub struct RaytracePass {
pub pipeline: wgpu::RenderPipeline
}
impl RaytracePass {
pub fn new(device: &wgpu::Device, swapchain_desc: &wgpu::SwapChainDescriptor, bind_group_layouts: &[&wgpu::BindGroupLayout]) -> Self {
// Pipeline stuff
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Render Pipeline Layout"),
bind_group_layouts: bind_group_layouts,
push_constant_ranges: &[],
});
let vert_state = wgpu::VertexState { //vert
module: &device.create_shader_module(&wgpu::include_spirv!("..\\..\\shaders\\bin\\shader.vert.spv")),
entry_point: "main",
buffers: &[Vertex::desc()],
};
let frag_state = wgpu::FragmentState { // frag
module: &device.create_shader_module(&wgpu::include_spirv!("..\\..\\shaders\\bin\\shader.frag.spv")),
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: swapchain_desc.format,
alpha_blend: wgpu::BlendState::REPLACE,
color_blend: wgpu::BlendState::REPLACE,
write_mask: wgpu::ColorWrite::ALL,
}],
};
let prim_state = wgpu::PrimitiveState { // primitive
topology: wgpu::PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: wgpu::FrontFace::Cw,
cull_mode: wgpu::CullMode::Back,
polygon_mode: wgpu::PolygonMode::Fill,
};
let multisample_state = wgpu::MultisampleState { // multisample
count: 1,
mask: !0,
alpha_to_coverage_enabled: false,
};
// Create pipeline
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Render Pipeline"),
layout: Some(&pipeline_layout),
vertex: vert_state,
fragment: Some(frag_state),
primitive: prim_state,
depth_stencil: None,
multisample: multisample_state,
});
Self { pipeline }
}
}
Binary file not shown.
+6 -5
View File
@@ -2,7 +2,8 @@
#version 450 #version 450
struct Material { struct Material {
vec4 albedo; vec3 albedo;
float specular;
}; };
// Variables // Variables
@@ -65,7 +66,7 @@ vec3 solve()
if(primary.data > 0) if(primary.data > 0)
{ {
vec3 color = applyLighting(primary.pos, primaryRay.dir, primary.normal, primary.data); vec3 color = applyLighting(primary.pos, primaryRay.dir, primary.normal, primary.data);
vec3 hitPos = primary.pos-primaryRay.dir*0.000001; vec3 hitPos = primary.pos-primaryRay.dir*0.00000001;
// Shadow ray // Shadow ray
Ray shadowRay = Ray(hitPos, _SunDir); Ray shadowRay = Ray(hitPos, _SunDir);
@@ -73,9 +74,9 @@ vec3 solve()
if(shadow.data > 0) color *= 0.1; if(shadow.data > 0) color *= 0.1;
// Secondary ray // Secondary ray
Ray secondRay = Ray(hitPos, randomHemisphere(primary.normal)); // Ray secondRay = Ray(hitPos, randomHemisphere(primary.normal));
HitResult second = castNodes(secondRay, 25); // HitResult second = castNodes(secondRay, 25);
if(second.data > 0) color += getAlbedo(second.data) * 0.8; // if(second.data > 0) color += getAlbedo(second.data) * 0.8;
return color; return color;
} }
+9 -9
View File
@@ -1,10 +1,8 @@
/* /*
* Returns material albedo for given voxel * Returns material albedo for given voxel
*/ */
vec3 getAlbedo(uint data) vec3 getAlbedo(uint data) { return _Materials[data-1].albedo.rgb; }
{ float getSpecular(uint data) { return _Materials[data-1].specular; }
return _Materials[data-1].albedo.rgb;
}
/* /*
point: Hit point point: Hit point
@@ -14,12 +12,14 @@ vec3 getAlbedo(uint data)
vec3 applyLighting(vec3 hitPoint, vec3 view, vec3 normal, uint data) vec3 applyLighting(vec3 hitPoint, vec3 view, vec3 normal, uint data)
{ {
// Lighting // Lighting
vec3 light_color = vec3(1); vec3 ambientColor = vec3(0.9, 0.9, 1.0);
vec3 ambient = ambientColor * 0.05;
vec3 sky = ambientColor * 0.1 * max(normal.y, 0);
vec3 ambient = light_color * 0.1; vec3 sunColor = vec3(1.0, 1.0, 0.9);
vec3 diffuse = light_color * max(1.0-dot(normal, _SunDir), 0.0); vec3 diffuse = sunColor * max(1.0-dot(normal, _SunDir), 0.0);
vec3 specular = light_color * pow(max(dot(view, reflect(_SunDir, normal)), 0.0), 32); vec3 specular = sunColor * getSpecular(data) * pow(max(dot(view, reflect(_SunDir, normal)), 0.0), 32);
// Combine colors // Combine colors
return (ambient + diffuse + specular) * getAlbedo(data); return (ambient + sky + diffuse + specular) * getAlbedo(data);
} }
-14
View File
@@ -1,14 +0,0 @@
float sdSphere(in vec3 pos)
{
return length(pos) - 1.0;
}
float sdPlane(in vec3 pos)
{
return pos.y;
}
vec2 sdUnion(vec2 a, vec2 b)
{
return (a.x < b.x) ? a : b;
}