diff --git a/src/app/mod.rs b/src/app/mod.rs index 4c7fc75..9ed1847 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -2,8 +2,9 @@ use winit::{ event::{Event, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode, MouseButton}, window::Window }; +use cgmath::Point3; use std::sync::Arc; -use rand::Rng; + mod camera_controller; use camera_controller::CameraController; mod world_gen; use world_gen::WorldGen; @@ -23,61 +24,16 @@ impl App { let camera_controller = CameraController::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(); - - // Ground - for bx in 0..16 { - for bz in 0..16 { - 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::() * 5.0) as usize; - for y in 1..h { - renderer.brick_set_voxel(brick_id, x, y, z, 2); - } - } + for x in 0..32 { + for y in 0..16 { + for z in 0..32 { + world_gen.generate(&mut renderer, Point3{x, y, z}); } } } - - // 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()); - - Self { window, renderer, camera_controller, world_gen } } diff --git a/src/app/world_gen.rs b/src/app/world_gen.rs index 9b147a2..785f318 100644 --- a/src/app/world_gen.rs +++ b/src/app/world_gen.rs @@ -1,4 +1,6 @@ -use std::sync::Arc; +use cgmath::{Point3, InnerSpace}; +use rand::Rng; + use crate::renderer::Renderer; pub struct WorldGen { @@ -11,6 +13,44 @@ impl WorldGen { Self{} } - pub fn generate(&mut self, renderer: Renderer) { + pub fn generate(&mut self, renderer: &mut Renderer, pos: Point3) { + 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::() < 0.3 { + let h = (rng.gen::() * 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?"); + } + } } } \ No newline at end of file diff --git a/src/renderer/buffers/brick_buffer.rs b/src/renderer/buffers/blocks.rs similarity index 62% rename from src/renderer/buffers/brick_buffer.rs rename to src/renderer/buffers/blocks.rs index 4ee2955..fcca948 100644 --- a/src/renderer/buffers/brick_buffer.rs +++ b/src/renderer/buffers/blocks.rs @@ -1,18 +1,18 @@ use std::convert::TryInto; -use crate::renderer::buffers::{BRICK_SIZE, BRICK_NUM, BRICK_LEN}; -const DATA_LEN : usize = BRICK_LEN * BRICK_NUM; +use crate::renderer::buffers::{BLOCK_SIZE, BLOCK_NUM, BLOCK_LEN}; +const DATA_LEN : usize = BLOCK_LEN * BLOCK_NUM; -pub struct BrickBuffer { - pub bricks: Box<[u8]>, - pub free_brick: usize, +pub struct Blocks { + pub blocks: Box<[u8]>, + pub free_block: usize, texture: wgpu::Texture, pub bind_layout: wgpu::BindGroupLayout, pub bind_group: wgpu::BindGroup } -impl BrickBuffer { +impl Blocks { /* * Create buffer in memory and gpu @@ -20,7 +20,7 @@ impl BrickBuffer { pub fn new(device: &wgpu::Device) -> Self { // 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( &wgpu::TextureDescriptor { size: size, @@ -29,7 +29,7 @@ impl BrickBuffer { dimension: wgpu::TextureDimension::D3, format: wgpu::TextureFormat::R8Uint, 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: 1, resource: wgpu::BindingResource::Sampler(&sampler) } ], - label: Some("Brick texture group"), + label: Some("block texture group"), } ); // Data - let mut bricks = vec![0_u8; DATA_LEN].into_boxed_slice(); - bricks[0] = 1; - println!("Brick buffer size: {} MB", DATA_LEN as f32 / 1024.0 / 1024.0); + let mut blocks = vec![0_u8; DATA_LEN].into_boxed_slice(); + blocks[0] = 1; + println!("block buffer size: {} MB", DATA_LEN as f32 / 1024.0 / 1024.0); // 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 - offset: Brick index to copy + Write block data to gpu, should be called to apply changes + offset: block index to copy */ - pub fn write(&mut self, queue: &wgpu::Queue, brick: usize) { - // Get first brick - let brick_offset = brick*BRICK_LEN; - let brick_bytes : [u8;BRICK_LEN] = self.bricks[brick_offset..brick_offset+BRICK_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 brick_origin = wgpu::Origin3d{ x:0, y:0, z: (brick*BRICK_SIZE) as u32 }; + pub fn write(&mut self, queue: &wgpu::Queue, block: usize) { + // Get first block + let block_offset = block*BLOCK_LEN; + let block_bytes : [u8;BLOCK_LEN] = self.blocks[block_offset..block_offset+BLOCK_LEN].try_into().unwrap(); + let block_size = wgpu::Extent3d{ width: BLOCK_SIZE as u32, height: BLOCK_SIZE as u32, depth: BLOCK_SIZE as u32 }; + let block_origin = wgpu::Origin3d{ x:0, y:0, z: (block*BLOCK_SIZE) as u32 }; // Write queue.write_texture( - wgpu::TextureCopyView { texture: &self.texture, mip_level: 0, origin: brick_origin }, - &brick_bytes, - wgpu::TextureDataLayout { offset: 0, bytes_per_row: brick_size.width, rows_per_image: brick_size.height }, - brick_size + wgpu::TextureCopyView { texture: &self.texture, mip_level: 0, origin: block_origin }, + &block_bytes, + wgpu::TextureDataLayout { offset: 0, bytes_per_row: block_size.width, rows_per_image: block_size.height }, + block_size ); } /* - * Get id of next free brick - * Later: reusing old bricks + * Get id of next free block + * Later: reusing old blocks */ - pub fn next_brick(&mut self) -> usize { - if self.free_brick >= self.bricks.len() { - panic!("No more free bricks! we should consider reusing bricks..."); + pub fn next_block(&mut self, consume: bool) -> usize { + if self.free_block >= self.blocks.len() { + panic!("No more free blocks! we should consider reusing blocks..."); } - self.free_brick += 1; - self.free_brick + let next = self.free_block + 1; + if consume { self.free_block = next; } + next } } \ No newline at end of file diff --git a/src/renderer/buffers/material_buffer.rs b/src/renderer/buffers/materials.rs similarity index 77% rename from src/renderer/buffers/material_buffer.rs rename to src/renderer/buffers/materials.rs index 96b426d..b960050 100644 --- a/src/renderer/buffers/material_buffer.rs +++ b/src/renderer/buffers/materials.rs @@ -1,37 +1,38 @@ use wgpu::util::DeviceExt; - +use cgmath::Point3; #[repr(C)] #[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] struct Material { - pub albedo: [f32; 4], + pub albedo: [f32; 3], + pub specular: f32, } impl Material { - pub fn set_albedo(&mut self, r: f32, g: f32, b:f32) + pub fn set(&mut self, color: Point3, specular: f32) { - self.albedo[0] = r; - self.albedo[1] = g; - self.albedo[2] = b; + self.albedo = color.into(); + self.specular = specular; } } -pub struct MaterialBuffer { +pub struct Materials { + #[allow(dead_code)] materials: [Material; 256], pub buffer: wgpu::Buffer, pub bind_layout: wgpu::BindGroupLayout, pub bind_group: wgpu::BindGroup } -impl MaterialBuffer { +impl Materials { pub fn new(device: &wgpu::Device) -> Self { // Create values let mut materials: [Material; 256] = [Default::default(); 256]; - materials[0].set_albedo(0.41,0.33,0.20); - materials[1].set_albedo(0.15,0.5,0.05); - materials[2].set_albedo(0.8,0.8,0.8); + materials[0].set(Point3{x:0.41, y:0.33, z:0.20}, 0.0); // Dirt + materials[1].set(Point3{x:0.15, y:0.50, z:0.05}, 0.3); // Grass + materials[2].set(Point3{x:0.90, y:0.90, z:0.90}, 1.0); // White // Create buffer let buffer = device.create_buffer_init( @@ -70,6 +71,6 @@ impl MaterialBuffer { }); // Done - MaterialBuffer { buffer, materials, bind_layout, bind_group } + Materials { buffer, materials, bind_layout, bind_group } } } \ No newline at end of file diff --git a/src/renderer/buffers/mod.rs b/src/renderer/buffers/mod.rs index 9bf5c1e..e5f426f 100644 --- a/src/renderer/buffers/mod.rs +++ b/src/renderer/buffers/mod.rs @@ -4,25 +4,25 @@ pub const WORLD_SIZE: usize = 32; pub const NUM_NODES: usize = (WORLD_SIZE*WORLD_SIZE*WORLD_SIZE) as usize; -pub const BRICK_SIZE : usize = 32; // 32x32x32 brick size -pub const BRICK_NUM : usize = 32768; // max bricks in texture -pub const BRICK_LEN : usize = BRICK_SIZE*BRICK_SIZE*BRICK_SIZE; +pub const BLOCK_SIZE : usize = 32; // 32x32x32 brick size +pub const BLOCK_NUM : usize = 32768; // max bricks in texture +pub const BLOCK_LEN : usize = BLOCK_SIZE*BLOCK_SIZE*BLOCK_SIZE; // Import names -mod node_buffer; -pub use node_buffer::NodeBuffer; +mod nodes; +pub use nodes::Nodes; -mod brick_buffer; -pub use brick_buffer::{BrickBuffer}; +mod blocks; +pub use blocks::Blocks; -mod uniform_buffer; -pub use uniform_buffer::UniformBuffer; -pub use uniform_buffer::UniformValues; +mod uniform; +pub use uniform::Uniform; +pub use uniform::UniformValues; -mod raster_buffer; -pub use raster_buffer::RasterBuffer; -pub use raster_buffer::Vertex; +mod raster; +pub use raster::Raster; +pub use raster::Vertex; -mod material_buffer; -pub use material_buffer::MaterialBuffer; \ No newline at end of file +mod materials; +pub use materials::Materials; \ No newline at end of file diff --git a/src/renderer/buffers/node_buffer.rs b/src/renderer/buffers/nodes.rs similarity index 98% rename from src/renderer/buffers/node_buffer.rs rename to src/renderer/buffers/nodes.rs index 11a415e..0ab90a7 100644 --- a/src/renderer/buffers/node_buffer.rs +++ b/src/renderer/buffers/nodes.rs @@ -3,7 +3,7 @@ use rand::prelude::*; use crate::renderer::buffers::{WORLD_SIZE, NUM_NODES}; -pub struct NodeBuffer { +pub struct Nodes { pub nodes: Box<[u32]>, texture: wgpu::Texture, size: wgpu::Extent3d, @@ -11,7 +11,7 @@ pub struct NodeBuffer { pub bind_group: wgpu::BindGroup } -impl NodeBuffer { +impl Nodes { pub fn new(device: &wgpu::Device) -> Self { diff --git a/src/renderer/buffers/raster_buffer.rs b/src/renderer/buffers/raster.rs similarity index 97% rename from src/renderer/buffers/raster_buffer.rs rename to src/renderer/buffers/raster.rs index f6e072f..7e19cd0 100644 --- a/src/renderer/buffers/raster_buffer.rs +++ b/src/renderer/buffers/raster.rs @@ -40,13 +40,13 @@ const VERTICES: &[Vertex] = &[ pub const INDICES: &[u16] = &[ 0, 1, 3, 3, 1, 2 ]; -pub struct RasterBuffer { +pub struct Raster { pub vertex_buffer: wgpu::Buffer, pub index_buffer: wgpu::Buffer, pub index_len: u32 } -impl RasterBuffer { +impl Raster { pub fn new(device: &wgpu::Device) -> Self { // Create vertex buffer diff --git a/src/renderer/buffers/uniform_buffer.rs b/src/renderer/buffers/uniform.rs similarity index 95% rename from src/renderer/buffers/uniform_buffer.rs rename to src/renderer/buffers/uniform.rs index ef12dc7..13b6a4f 100644 --- a/src/renderer/buffers/uniform_buffer.rs +++ b/src/renderer/buffers/uniform.rs @@ -32,14 +32,14 @@ impl UniformValues { } -pub struct UniformBuffer { +pub struct Uniform { pub values: UniformValues, pub buffer: wgpu::Buffer, pub bind_layout: wgpu::BindGroupLayout, pub bind_group: wgpu::BindGroup, } -impl UniformBuffer { +impl Uniform { pub fn new(device: &wgpu::Device) -> Self { // Create values let values = UniformValues::new(); @@ -81,7 +81,7 @@ impl UniformBuffer { }); // Done - UniformBuffer { buffer, values, bind_layout, bind_group } + Uniform { buffer, values, bind_layout, bind_group } } } diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index fb1619d..993c010 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -1,7 +1,11 @@ use winit::{window::Window, dpi::PhysicalSize}; +use cgmath::{Point3}; 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; @@ -12,13 +16,13 @@ pub struct Renderer { queue: wgpu::Queue, swapchain_desc: wgpu::SwapChainDescriptor, swapchain: wgpu::SwapChain, - pipeline: wgpu::RenderPipeline, + raytrace: RaytracePass, // Buffers - raster_buffer: RasterBuffer, - uniform_buffer: UniformBuffer, - node_buffer: NodeBuffer, - brick_buffer: BrickBuffer, - material_buffer: MaterialBuffer, + raster_buffer: Raster, + uniform_buffer: Uniform, + node_buffer: Nodes, + brick_buffer: Blocks, + material_buffer: Materials, // Other pub camera: Camera, start: std::time::Instant, @@ -38,53 +42,6 @@ impl Renderer { let swapchain = device.create_swap_chain(&surface, &swapchain_desc); (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 @@ -112,11 +69,11 @@ impl Renderer { let camera = Camera::new(aspect, 60.0); // Buffers - let uniform_buffer = UniformBuffer::new(&device); - let raster_buffer = RasterBuffer::new(&device); - let node_buffer = NodeBuffer::new(&device); - let brick_buffer = BrickBuffer::new(&device); - let material_buffer = MaterialBuffer::new(&device); + let uniform_buffer = Uniform::new(&device); + let raster_buffer = Raster::new(&device); + let node_buffer = Nodes::new(&device); + let brick_buffer = Blocks::new(&device); + let material_buffer = Materials::new(&device); // Pipeline let bind_layouts = [ @@ -125,13 +82,13 @@ impl Renderer { &brick_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 println!("Initialized"); let start = std::time::Instant::now(); let changed_bricks: Vec = 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 - 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(1, &self.node_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_index_buffer(self.raster_buffer.index_buffer.slice(..), wgpu::IndexFormat::Uint16); render_pass.draw_indexed(0..self.raster_buffer.index_len, 0, 0..1); + } // Submit encoder (command buffer) @@ -216,43 +174,43 @@ impl Renderer { */ #[allow(dead_code)] 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); - self.brick_set_voxel(brick_id, x%32, y%32, z%32, value); + let brick_id = self.block_get_id(Point3{x:x/32, y:y/32, z:z/32}, true); + self.block_set_voxel(brick_id, x%32, y%32, z%32, value); } /* * 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) { - let voxel_id = x + buffers::BRICK_SIZE * (y + buffers::BRICK_SIZE * z); - let brick_offset = brick_id * buffers::BRICK_LEN; - self.brick_buffer.bricks[brick_offset + voxel_id] = value; + pub fn block_set_voxel(&mut self, brick_id:usize, x: usize, y: usize, z:usize, value: u8) { + let voxel_id = x + buffers::BLOCK_SIZE * (y + buffers::BLOCK_SIZE * z); + let brick_offset = brick_id * buffers::BLOCK_LEN; + self.brick_buffer.blocks[brick_offset + voxel_id] = value; } /* * 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, apply: bool) -> usize { // 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]; // Use new brick if neccesary if node_value == 0 { - node_value = self.brick_buffer.next_brick() as u32; - self.node_buffer.nodes[node_idx] = node_value; + node_value = self.brick_buffer.next_block(apply) as u32; + if apply { self.node_buffer.nodes[node_idx] = node_value; } } // Get brick id from node value 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 } /* * 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) { self.changed_bricks.push(brick_id); } diff --git a/src/renderer/passes/mod.rs b/src/renderer/passes/mod.rs new file mode 100644 index 0000000..21eb545 --- /dev/null +++ b/src/renderer/passes/mod.rs @@ -0,0 +1,3 @@ + +mod raytrace; +pub use raytrace::RaytracePass; \ No newline at end of file diff --git a/src/renderer/passes/raytrace.rs b/src/renderer/passes/raytrace.rs new file mode 100644 index 0000000..ff0871a --- /dev/null +++ b/src/renderer/passes/raytrace.rs @@ -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 } + } +} \ No newline at end of file diff --git a/src/shaders/bin/shader.frag.spv b/src/shaders/bin/shader.frag.spv index 541d11c..4e09391 100644 Binary files a/src/shaders/bin/shader.frag.spv and b/src/shaders/bin/shader.frag.spv differ diff --git a/src/shaders/shader.frag b/src/shaders/shader.frag index 0a443ca..4f575f5 100644 --- a/src/shaders/shader.frag +++ b/src/shaders/shader.frag @@ -2,7 +2,8 @@ #version 450 struct Material { - vec4 albedo; + vec3 albedo; + float specular; }; // Variables @@ -65,7 +66,7 @@ vec3 solve() if(primary.data > 0) { 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 Ray shadowRay = Ray(hitPos, _SunDir); @@ -73,9 +74,9 @@ vec3 solve() if(shadow.data > 0) color *= 0.1; // Secondary ray - Ray secondRay = Ray(hitPos, randomHemisphere(primary.normal)); - HitResult second = castNodes(secondRay, 25); - if(second.data > 0) color += getAlbedo(second.data) * 0.8; + // Ray secondRay = Ray(hitPos, randomHemisphere(primary.normal)); + // HitResult second = castNodes(secondRay, 25); + // if(second.data > 0) color += getAlbedo(second.data) * 0.8; return color; } diff --git a/src/shaders/shading.cginc b/src/shaders/shading.cginc index 6208bba..4087ddb 100644 --- a/src/shaders/shading.cginc +++ b/src/shaders/shading.cginc @@ -1,10 +1,8 @@ /* * Returns material albedo for given voxel */ -vec3 getAlbedo(uint data) -{ - return _Materials[data-1].albedo.rgb; -} +vec3 getAlbedo(uint data) { return _Materials[data-1].albedo.rgb; } +float getSpecular(uint data) { return _Materials[data-1].specular; } /* point: Hit point @@ -14,12 +12,14 @@ vec3 getAlbedo(uint data) vec3 applyLighting(vec3 hitPoint, vec3 view, vec3 normal, uint data) { // 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 diffuse = light_color * max(1.0-dot(normal, _SunDir), 0.0); - vec3 specular = light_color * pow(max(dot(view, reflect(_SunDir, normal)), 0.0), 32); + vec3 sunColor = vec3(1.0, 1.0, 0.9); + vec3 diffuse = sunColor * max(1.0-dot(normal, _SunDir), 0.0); + vec3 specular = sunColor * getSpecular(data) * pow(max(dot(view, reflect(_SunDir, normal)), 0.0), 32); // Combine colors - return (ambient + diffuse + specular) * getAlbedo(data); + return (ambient + sky + diffuse + specular) * getAlbedo(data); } \ No newline at end of file diff --git a/src/shaders/shapes.cginc b/src/shaders/shapes.cginc deleted file mode 100644 index 88d60be..0000000 --- a/src/shaders/shapes.cginc +++ /dev/null @@ -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; -} \ No newline at end of file