renamed brick to block, world gen stuff in separate file
This commit is contained in:
+6
-50
@@ -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::<f32>() * 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 }
|
||||
}
|
||||
|
||||
|
||||
+42
-2
@@ -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<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 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
|
||||
}
|
||||
}
|
||||
@@ -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<f32>, 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 }
|
||||
}
|
||||
}
|
||||
+15
-15
@@ -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;
|
||||
mod materials;
|
||||
pub use materials::Materials;
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
+32
-74
@@ -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,
|
||||
@@ -39,53 +43,6 @@ impl Renderer {
|
||||
(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<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
|
||||
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<usize>, 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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
mod raytrace;
|
||||
pub use raytrace::RaytracePass;
|
||||
@@ -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.
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user