diff --git a/src/app/mod.rs b/src/app/mod.rs index 8d52d52..0a04bfa 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -41,8 +41,8 @@ impl App { let mut rng = rand::thread_rng(); let start = std::time::Instant::now(); - for bx in 0..32 { - for bz in 0..32 { + for bx in 0..16 { + for bz in 0..16 { let brick_id = renderer.brick_get_id(bx, 0, bz); renderer.brick_mark_changed(brick_id); @@ -62,7 +62,7 @@ impl App { for x in 0..32 { for z in 0..32 { // Dirt - let h = (rng.gen::() * 16.0) as usize; + let h = (rng.gen::() * 4.0) as usize; for y in 0..h { renderer.brick_set_voxel(brick_id, x, y, z, 2); } @@ -70,6 +70,18 @@ impl App { } } } + + let brick_id = renderer.brick_get_id(8, 2, 8); + for x in 0..32 { + for z in 0..32 { + // White block + for y in 0..32 { + renderer.brick_set_voxel(brick_id, x, y, z, 3); + } + } + } + renderer.brick_mark_changed(brick_id); + println!("Generated in {}ms", start.elapsed().as_millis()); diff --git a/src/renderer/buffers/material_buffer.rs b/src/renderer/buffers/material_buffer.rs index dee9124..96b426d 100644 --- a/src/renderer/buffers/material_buffer.rs +++ b/src/renderer/buffers/material_buffer.rs @@ -30,7 +30,8 @@ impl MaterialBuffer { // 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.49,0.74,0.00); + materials[1].set_albedo(0.15,0.5,0.05); + materials[2].set_albedo(0.8,0.8,0.8); // Create buffer let buffer = device.create_buffer_init( diff --git a/src/renderer/buffers/uniform_buffer.rs b/src/renderer/buffers/uniform_buffer.rs index b64f7f5..f115ee0 100644 --- a/src/renderer/buffers/uniform_buffer.rs +++ b/src/renderer/buffers/uniform_buffer.rs @@ -1,5 +1,5 @@ use crate::renderer::camera::Camera; -use cgmath::SquareMatrix; +use cgmath::{SquareMatrix, Vector3, InnerSpace}; use wgpu::util::DeviceExt; #[repr(C)] @@ -8,13 +8,19 @@ pub struct UniformValues { view_inv: [[f32; 4]; 4], proj_inv: [[f32; 4]; 4], cam_pos: [f32; 3], + padding: f32, + sun_dir: [f32; 3], + padding2: f32, time: f32 } impl UniformValues { pub fn new() -> Self { - Self::default() + + let sun_vec: Vector3 = (1.0, 1.0, 1.0).into(); + let sun_dir: [f32; 3] = sun_vec.normalize().into(); + Self { sun_dir, .. Default::default() } } pub fn update(&mut self, camera: &Camera, time: f32) { diff --git a/src/shaders/bin/shader.frag.spv b/src/shaders/bin/shader.frag.spv index 608d6e3..5d1cafa 100644 Binary files a/src/shaders/bin/shader.frag.spv and b/src/shaders/bin/shader.frag.spv differ diff --git a/src/shaders/raycasting.cginc b/src/shaders/raycasting.cginc index 80ce95e..cd906de 100644 --- a/src/shaders/raycasting.cginc +++ b/src/shaders/raycasting.cginc @@ -5,7 +5,7 @@ * incAxis: Last axis that was used to increment position * addr: Number given by node, brick offset in brick array */ -vec4 castBricks(vec3 origin, vec3 start, vec3 dir, vec3 incAxis, uint addr) +HitResult castBricks(vec3 origin, vec3 start, vec3 dir, vec3 incAxis, uint addr) { vec3 o = origin; @@ -34,7 +34,7 @@ vec4 castBricks(vec3 origin, vec3 start, vec3 dir, vec3 incAxis, uint addr) // Normal vector (negate previous increment axis and mult by sign) vec3 normal = -incAxis * raySign; - return vec4(solve(hitPoint, dir, normal, brick-1), 1.0); + return HitResult(brick-1, hitPoint, normal); } // Get new closest axis to increment @@ -47,14 +47,14 @@ vec4 castBricks(vec3 origin, vec3 start, vec3 dir, vec3 incAxis, uint addr) if(pos.x > 31 || pos.y > 31 || pos.z > 31) { break; } } - return vec4(1.0,0.0,0.5,0.0); + return HitResult(0, vec3(0,0,0), vec3(0,0,0)); } /* * origin: Camera position * dir: Ray coming from camera position going through currently drawn pixel */ -vec3 castNodes(vec3 origin, vec3 dir) +HitResult castNodes(vec3 origin, vec3 dir) { // Round input pos to nearest voxel vec3 pos = floor(origin); @@ -81,8 +81,8 @@ vec3 castNodes(vec3 origin, vec3 dir) vec3 hitPoint = origin + dir * len; // Cast brick - vec4 result = castBricks(pos, hitPoint, dir, incAxis, node); - if(result.a > 0.0) return result.rgb; + HitResult result = castBricks(pos, hitPoint, dir, incAxis, node); + if(result.data > 0) return result; } // Get new closest axis to increment @@ -96,5 +96,5 @@ vec3 castNodes(vec3 origin, vec3 dir) } // Not found - return vec3(0.0, 0.0, 0.0); + return HitResult(0, vec3(0,0,0), vec3(0,0,0)); } \ No newline at end of file diff --git a/src/shaders/shader.frag b/src/shaders/shader.frag index a805a26..d6761b5 100644 --- a/src/shaders/shader.frag +++ b/src/shaders/shader.frag @@ -13,6 +13,7 @@ layout(set=0,binding=0) uniform Uniforms { mat4 _ViewMatrix; mat4 _ProjMatrixInv; vec3 _CamPos; + vec3 _SunDir; float _Time; }; layout(set=1,binding=0) uniform usampler3D _NodesTexture; @@ -27,16 +28,27 @@ layout(set=3, binding=0) uniform Materials { // #define NEAR 0.01 // Include +#include "structs.cginc" #include "shading.cginc" #include "raycasting.cginc" void main() { + // Black by default + out_color = vec4(0,0,0,1); + // Calculate ray direction vec3 view_dir = (_ProjMatrixInv * vec4(vert_uv, 0, 1)).xyz; vec3 ray_dir = normalize(_ViewMatrix * vec4(view_dir,0)).xyz; // Raycast - out_color = vec4(castNodes(_CamPos, ray_dir), 1.0); + HitResult primary = castNodes(_CamPos, ray_dir); + if(primary.data > 0) + { + out_color = vec4(applyLighting(primary.pos, ray_dir, primary.normal, primary.data), 1.0); + + HitResult shadow = castNodes(primary.pos-ray_dir*0.000001, _SunDir); + if(shadow.data > 0) out_color *= 0.1; + } } \ No newline at end of file diff --git a/src/shaders/shading.cginc b/src/shaders/shading.cginc index a72a36f..95d2c6d 100644 --- a/src/shaders/shading.cginc +++ b/src/shaders/shading.cginc @@ -3,15 +3,14 @@ view: View vector (camera ray) normal: Normal vector */ -vec3 solve(vec3 hitPoint, vec3 view, vec3 normal, uint brick) +vec3 applyLighting(vec3 hitPoint, vec3 view, vec3 normal, uint brick) { // Lighting vec3 light_color = vec3(1.0, 1.0, 1.0); - vec3 light_dir = normalize(hitPoint-vec3(0.0, 1.5, 4.0)); vec3 ambient = light_color * 0.1; - vec3 diffuse = light_color * max(1.0-dot(normal, light_dir), 0.0); - vec3 specular = light_color * pow(max(dot(view, reflect(-light_dir, normal)), 0.0), 32); + 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); // Combine colors vec3 object_color = _Materials[brick].albedo.rgb;//vec3(0.0, 0.1, 0.5); diff --git a/src/shaders/structs.cginc b/src/shaders/structs.cginc new file mode 100644 index 0000000..101e9cc --- /dev/null +++ b/src/shaders/structs.cginc @@ -0,0 +1,6 @@ + +struct HitResult { + uint data; // Voxel data + vec3 pos; // Position in world + vec3 normal; // Normal vector +}; \ No newline at end of file