diff --git a/src/renderer/buffers/brick_buffer.rs b/src/renderer/buffers/brick_buffer.rs index ab7594e..6c97c81 100644 --- a/src/renderer/buffers/brick_buffer.rs +++ b/src/renderer/buffers/brick_buffer.rs @@ -2,7 +2,7 @@ use wgpu::util::DeviceExt; use std::convert::TryInto; const BRICK_SIZE : usize = 32; // 32x32x32 brick size -const BRICK_NUM : usize = 1; // 64 bricks in texture +const BRICK_NUM : usize = 2; // x bricks in texture const BRICK_LEN : usize = BRICK_SIZE*BRICK_SIZE*BRICK_SIZE; const DATA_LEN : usize = BRICK_LEN * BRICK_NUM; @@ -98,9 +98,11 @@ impl BrickBuffer { for y in 0..16 { for z in 0..32 { bricks.set(0, x, y, z, 1); + bricks.set(1, y, x, z, 1); } } } + bricks.set(0, 0, 0, 0, 0); // Done Self { bricks, texture, size, bind_layout, bind_group } @@ -116,7 +118,7 @@ impl BrickBuffer { let brick_offset = offset*BRICK_LEN; let brick_bytes : [u8;BRICK_LEN] = self.bricks.data[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: offset as u32 }; + let brick_origin = wgpu::Origin3d{ x:0, y:0, z: (offset*BRICK_SIZE) as u32 }; // Write queue.write_texture( diff --git a/src/renderer/buffers/node_buffer.rs b/src/renderer/buffers/node_buffer.rs index b431310..bf24347 100644 --- a/src/renderer/buffers/node_buffer.rs +++ b/src/renderer/buffers/node_buffer.rs @@ -70,7 +70,7 @@ impl NodeBuffer { // Data let mut nodes : [u32; NUM_NODES] = [Default::default(); NUM_NODES]; - nodes[0] = 1; + nodes[0] = 2; // Done Self { nodes, texture, size, bind_layout, bind_group } diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 3333adb..0371774 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -112,6 +112,7 @@ impl Renderer { let mut brick_buffer = BrickBuffer::new(&device); brick_buffer.write(&queue, 0); + brick_buffer.write(&queue, 1); // Pipeline let pipeline = Self::create_pipeline(&device, &swapchain_desc, &[&uniform_buffer.bind_layout, &node_buffer.bind_layout, &brick_buffer.bind_layout]); diff --git a/src/shaders/bin/shader.frag.spv b/src/shaders/bin/shader.frag.spv index 32d518e..e828880 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 311ff9d..b0ce775 100644 --- a/src/shaders/raycasting.cginc +++ b/src/shaders/raycasting.cginc @@ -4,11 +4,11 @@ view: View vector (camera ray) normal: Normal vector */ -vec3 solve(vec3 point, vec3 view, vec3 normal) +vec3 solve(vec3 hitPoint, vec3 view, vec3 normal) { // Lighting vec3 light_color = vec3(1.0, 1.0, 1.0); - vec3 light_dir = normalize(point-vec3(0.0, 1.5, 4.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); @@ -19,11 +19,59 @@ vec3 solve(vec3 point, vec3 view, vec3 normal) return (ambient + diffuse + specular) * object_color; } -vec3 castBricks(vec3 origin, vec3 dir) +/* +* origin: Point hit on the node +* dir: Camera view direction (ray direction) +* addr: Number given by node, afaik brick offset in brick array +*/ +vec3 castBricks(vec3 origin, vec3 start, vec3 dir, uint addr) { - + // Change scale + origin = start - origin; + origin += dir*0.00001; + origin *= 32; + + // Same as in casting nodes + vec3 pos = floor(origin); + vec3 rayInv = 1.0/dir; + vec3 raySign = sign(dir); + vec3 dist = (pos-origin+0.5 + raySign*0.5) * rayInv; + + ivec3 offset = ivec3(0, 0, (addr-1)*32); + vec3 incAxis = vec3(0,0,0); + for(int i=0;i<110;i++) + { + // Get brick + uint brick = texelFetch(bricksTexture, offset+ivec3(pos), 0).r; + if(brick != 0) + { + // Hit point + vec3 mini = (pos-origin+0.5 - raySign*0.5) * rayInv; + float len = max(mini.x, max(mini.y, mini.z)); + vec3 hitPoint = (origin + dir * len) + start; + + // Normal vector (negate previous increment axis and mult by sign) + vec3 normal = -incAxis * raySign; + return solve(hitPoint, dir, normal); + } + + // Get new closest axis to increment + incAxis = step(dist.xyz, dist.yzx) * step(dist.xyz, dist.zxy); + dist += incAxis * raySign * rayInv; + pos += incAxis * raySign; + + // Outside bounds + if(pos.x < 0 || pos.y < 0 || pos.z < 0) { break; } + if(pos.x > 32 || pos.y > 32 || pos.z > 32) { break; } + } + + return vec3(0.5,0.5,0.5); } +/* +* origin: Camera position +* dir: Ray coming from camera position going through currently drawn pixel +*/ vec3 castNodes(vec3 origin, vec3 dir) { // Round input pos to nearest voxel @@ -38,8 +86,8 @@ vec3 castNodes(vec3 origin, vec3 dir) // Closest axis to increment in grid will be stored here (x=1 or y=1 or z=1) vec3 incAxis = vec3(0,0,0); - float level = 1; - for(int i=0;i<50;i++) + // Iterate + for(int i=0;i<56;i++) { // Get node uint node = texelFetch(nodesTexture, ivec3(pos), 0).r; @@ -48,14 +96,13 @@ vec3 castNodes(vec3 origin, vec3 dir) // Hit point vec3 mini = (pos-origin+0.5 - raySign*0.5) * rayInv; float len = max(mini.x, max(mini.y, mini.z)); - vec3 point = origin + dir * len; + vec3 hitPoint = origin + dir * len; // Normal vector (negate previous increment axis and mult by sign) - vec3 normal = -incAxis * raySign; - - // Get subnode - //return step(vec3(0.5, 0.5, 0.5), point - pos); + //vec3 normal = -incAxis * raySign; + //return solve(hitPoint, dir, normal); - return solve(point, dir, normal); + // Cast brick + return castBricks(pos, hitPoint, dir, node); //todo: continue if not hit } // Get new closest axis to increment @@ -63,6 +110,7 @@ vec3 castNodes(vec3 origin, vec3 dir) dist += incAxis * raySign * rayInv; pos += incAxis * raySign; + // Outside bounds // if(pos.x < 0 || pos.y < 0 || pos.z < 0) { break; } // if(pos.x > 1 || pos.y > 1 || pos.z > 1) { break; } }