From 61ec3e5a21fcf0f2d697e4ac6e0d62dd4fe77ef6 Mon Sep 17 00:00:00 2001 From: Piotrek Date: Sat, 24 Apr 2021 20:47:04 +0200 Subject: [PATCH] shadows --- src/app/mod.rs | 18 +++++++++++++++--- src/renderer/buffers/material_buffer.rs | 3 ++- src/renderer/buffers/uniform_buffer.rs | 10 ++++++++-- src/shaders/bin/shader.frag.spv | Bin 10648 -> 11328 bytes src/shaders/raycasting.cginc | 14 +++++++------- src/shaders/shader.frag | 14 +++++++++++++- src/shaders/shading.cginc | 7 +++---- src/shaders/structs.cginc | 6 ++++++ 8 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 src/shaders/structs.cginc 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 608d6e37826e220d387ffae9bfbce11676e3a679..5d1cafada330bec78165e5fd01f9758d634a8333 100644 GIT binary patch literal 11328 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 literal 10648 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 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