MULTIPLE VOXEL GROUPS

This commit is contained in:
2024-06-06 01:38:57 -04:00
parent 02f5a94fe5
commit 2fe5d2ecfe
3 changed files with 131 additions and 51 deletions

View File

@@ -32,4 +32,12 @@ impl VoxelColor {
a: 255, a: 255,
} }
} }
pub fn random() -> Self {
Self {
r: rand::random(),
g: rand::random(),
b: rand::random(),
a: rand::random(),
}
}
} }

View File

@@ -117,8 +117,7 @@ impl VoxelPipeline {
let lx = 15; let lx = 15;
let ly = 10; let ly = 10;
let lz = 10; let lz = 10;
let size = lx * ly * lz; let mut data = vec![VoxelColor::none(); lx * ly * lz];
let mut data = vec![VoxelColor::none(); size];
for x in 0..lx { for x in 0..lx {
for y in 0..ly { for y in 0..ly {
data[x + y * lx] = VoxelColor { data[x + y * lx] = VoxelColor {
@@ -142,6 +141,32 @@ impl VoxelPipeline {
for i in 0..lx.min(ly.min(lz)) { for i in 0..lx.min(ly.min(lz)) {
data[i + i * lx + i * lx * ly] = VoxelColor::white(); data[i + i * lx + i * lx * ly] = VoxelColor::white();
} }
let lx2 = 1000;
let ly2 = 2;
let lz2 = 1000;
let offset2 = data.len();
let mut data2 = vec![VoxelColor::none(); lx2 * ly2 * lz2];
let paint = VoxelColor {
r: 255,
g: 0,
b: 255,
a: 255,
};
for x in 0..lx2 {
data2[x + (ly2 - 1) * lx2] = paint;
data2[x + (ly2 - 1) * lx2 + (lz2 - 1) * lx2 * ly2] = paint;
}
for z in 0..lz2 {
data2[(ly2 - 1) * lx2 + z * lx2 * ly2] = paint;
data2[lx2 - 1 + (ly2 - 1) * lx2 + z * lx2 * ly2] = paint;
}
for x in 0..lx2 {
for z in 0..lz2 {
data2[x + z * lx2 * ly2] = VoxelColor::random();
}
}
data.append(&mut data2);
self.voxels.update( self.voxels.update(
device, device,
encoder, encoder,
@@ -157,14 +182,25 @@ impl VoxelPipeline {
dimensions: Vector3::new(lx as u32, ly as u32, lz as u32), dimensions: Vector3::new(lx as u32, ly as u32, lz as u32),
offset: 0, offset: 0,
}; };
let thing2 = Translation3::new(0.0, -10.0, 20.0)
* Translation3::new(
-(lx2 as f32 / 2.0),
-(ly2 as f32 / 2.0),
-(lz2 as f32 / 2.0),
);
let group2 = VoxelGroup {
transform: Transform3::identity() * thing2.inverse(),
dimensions: Vector3::new(lx2 as u32, ly2 as u32, lz2 as u32),
offset: offset2 as u32,
};
self.voxel_groups.update( self.voxel_groups.update(
device, device,
encoder, encoder,
belt, belt,
1, 2,
&[ArrBufUpdate { &[ArrBufUpdate {
offset: 0, offset: 0,
data: vec![group], data: vec![group, group2],
}], }],
); );
self.bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { self.bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {

View File

@@ -44,14 +44,9 @@ fn vs_main(
// Fragment shader // Fragment shader
const X_AXIS = vec3<f32>(1.0, 0.0, 0.0);
const Y_AXIS = vec3<f32>(0.0, 1.0, 0.0);
const Z_AXIS = vec3<f32>(0.0, 0.0, 1.0);
const AXIS = mat3x3<f32>(X_AXIS, Y_AXIS, Z_AXIS);
const ZERO3F = vec3<f32>(0.0); const ZERO3F = vec3<f32>(0.0);
const ZERO2F = vec2<f32>(0.0); const ZERO2F = vec2<f32>(0.0);
const NO_COLOR = vec4<f32>(0.0); const DEPTH = 20;
@fragment @fragment
fn fs_main( fn fs_main(
@@ -65,87 +60,128 @@ fn fs_main(
1.0 1.0
); );
let group = voxel_groups[0]; // move to position in world
let dir_view = view.transform * vec4<f32>(normalize(pixel_pos), 0.0);
let pos_view = view.transform * vec4<f32>(pixel_pos, 1.0);
var depths = array<f32,DEPTH>();
var colors = array<vec4<f32>,DEPTH>();
for (var gi: u32 = 0; gi < arrayLength(&voxel_groups); gi = gi + 1) {
draw_group(gi, pos_view, dir_view, &depths, &colors);
}
var color = vec4<f32>(0.0);
for(var di = 0; di < DEPTH; di += 1) {
// p sure if it can't unroll colors the performance dies; switch to buffer
let vcolor = colors[di];
color += vec4<f32>(vcolor.xyz * vcolor.a * (1.0 - color.a), (1.0 - color.a) * vcolor.a);
if vcolor.a == 0.0 || color.a >= 0.99999 {
return color;
}
}
return color;
}
fn draw_group(
gi: u32, pos_view: vec4<f32>, dir_view: vec4<f32>,
depths: ptr<function, array<f32, DEPTH>>,
colors: ptr<function, array<vec4<f32>,DEPTH>>,
) {
let group = voxel_groups[gi];
let dim_f = vec3<f32>(group.dimensions); let dim_f = vec3<f32>(group.dimensions);
let dim_i = vec3<i32>(group.dimensions); let dim_i = vec3<i32>(group.dimensions);
// transform position so that group is at 0,0 & find direction // transform so that group is at 0,0
let transform = group.transform * view.transform; var pos = (group.transform * pos_view).xyz;
let dir = (transform * vec4<f32>(normalize(pixel_pos), 0.0)).xyz; let dir = (group.transform * dir_view).xyz;
var pos = (transform * vec4<f32>(pixel_pos, 1.0)).xyz;
let dir_if = sign(dir);
// find where ray intersects with group // find where ray intersects with group
let plane_point = (vec3<f32>(1.0) - sign(dir)) / 2.0 * dim_f; let plane_point = (vec3<f32>(1.0) - dir_if) / 2.0 * dim_f;
var t_offset = 0.0;
if outside3f(pos, ZERO3F, dim_f) { if outside3f(pos, ZERO3F, dim_f) {
// x = td + p, solve for t // time of intersection; x = td + p, solve for t
let t = (plane_point - pos) / dir; let t_i = (plane_point - pos) / dir;
// points of intersection // points of intersection
let px = pos + t.x * dir; let px = pos + t_i.x * dir;
let py = pos + t.y * dir; let py = pos + t_i.y * dir;
let pz = pos + t.z * dir; let pz = pos + t_i.z * dir;
// check if point is in bounds // check if point is in bounds
let hit = vec3<bool>( let hit = vec3<bool>(
inside2f(px.yz, ZERO2F, dim_f.yz), inside2f(px.yz, ZERO2F, dim_f.yz),
inside2f(py.xz, ZERO2F, dim_f.xz), inside2f(py.xz, ZERO2F, dim_f.xz),
inside2f(pz.xy, ZERO2F, dim_f.xy), inside2f(pz.xy, ZERO2F, dim_f.xy),
) && (t > ZERO3F); ) && (t_i > ZERO3F);
if !any(hit) { if !any(hit) {
return NO_COLOR; return;
} }
pos = select(select(pz, py, hit.y), px, hit.x); pos = select(select(pz, py, hit.y), px, hit.x);
t_offset = select(select(t_i.z, t_i.y, hit.y), t_i.x, hit.x);
} }
var vox_pos = clamp(vec3<i32>(pos), vec3<i32>(0), dim_i - vec3<i32>(1)); var vox_pos = clamp(vec3<i32>(pos), vec3<i32>(0), dim_i - vec3<i32>(1));
let dir_if = sign(dir) * ceil(abs(dir));
let dir_i = vec3<i32>(dir_if); let dir_i = vec3<i32>(dir_if);
// time to move 1 unit using dir // time to move 1 unit using dir
let inc_t = abs(1.0 / dir); let inc_t = abs(1.0 / dir);
let corner = vec3<f32>(vox_pos) + vec3<f32>(0.5, 0.5, 0.5) + dir_if / 2.0; let corner = vec3<f32>(vox_pos) + vec3<f32>(0.5) + dir_if / 2.0;
// time of next plane hit for each direction // time of next plane hit for each direction
var next_t = inc_t * abs(pos - corner); var next_t = inc_t * abs(pos - corner);
var color = NO_COLOR; var alpha = 0.0;
var safety = 0; var safety = 0;
var t = 0.0;
var prev_t = t;
var depth = 0;
loop { loop {
// should prolly remove when gaming
safety += 1;
let i = u32(vox_pos.x + vox_pos.y * dim_i.x + vox_pos.z * dim_i.x * dim_i.y) + group.offset; let i = u32(vox_pos.x + vox_pos.y * dim_i.x + vox_pos.z * dim_i.x * dim_i.y) + group.offset;
let vcolor = unpack4x8unorm(voxels[i]); var vcolor = unpack4x8unorm(voxels[i]);
color += vec4<f32>(vcolor.xyz * vcolor.a * (1.0 - color.a), (1.0 - color.a) * vcolor.a);
if color.a >= 1.0 {
return color;
}
// select next voxel to move to next based on least time // select next voxel to move to next based on least time
if next_t.x < next_t.y && next_t.x < next_t.z { let axis = select(select(2, 1, next_t.y < next_t.z), 0, next_t.x < next_t.y && next_t.x < next_t.z);
vox_pos.x += dir_i.x; prev_t = t;
next_t.x += inc_t.x; t = next_t[axis];
if vox_pos.x < 0 || vox_pos.x >= dim_i.x { vox_pos[axis] += dir_i[axis];
return color; next_t[axis] += inc_t[axis];
// hit a voxel
if vcolor.a > 0.0 {
let full_t = t_offset + prev_t;
// skip closer depth hits, or completely if behind opaque
while (*depths)[depth] < full_t && (*colors)[depth].a != 0.0 {
depth += 1;
if depth >= DEPTH || (*colors)[depth].a == 1.0 {
return;
}
} }
} else if next_t.y < next_t.z { var move_d = depth;
vox_pos.y += dir_i.y; // move further depth hits back
next_t.y += inc_t.y; while move_d < DEPTH - 1 && (*colors)[move_d].a != 0.0 {
if vox_pos.y < 0 || vox_pos.y >= dim_i.y { (*colors)[move_d + 1] = (*colors)[move_d];
return color; (*depths)[move_d + 1] = (*depths)[move_d];
} move_d += 1;
} else {
vox_pos.z += dir_i.z;
next_t.z += inc_t.z;
if vox_pos.z < 0 || vox_pos.z >= dim_i.z {
return color;
} }
// add hit
(*depths)[depth] = full_t;
(*colors)[depth] = vcolor;
depth += 1;
alpha += (1.0 - alpha) * vcolor.a;
} }
safety += 1; if alpha >= 0.9999 || depth >= DEPTH
if safety > 1000 { || vox_pos[axis] < 0 || vox_pos[axis] >= dim_i[axis]
break; || safety > 1000 {
return;
} }
} }
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
} }
fn outside3f(v: vec3<f32>, low: vec3<f32>, high: vec3<f32>) -> bool { fn outside3f(v: vec3<f32>, low: vec3<f32>, high: vec3<f32>) -> bool {