SDF geo hybrid test
This commit is contained in:
parent
8f570b5cc6
commit
44372dfc09
Binary file not shown.
After Width: | Height: | Size: 820 KiB |
Binary file not shown.
After Width: | Height: | Size: 800 KiB |
14
src/main.rs
14
src/main.rs
|
@ -71,12 +71,12 @@ impl Metaballs {
|
||||||
|
|
||||||
let field = |x: i32, y: i32, z: i32| {
|
let field = |x: i32, y: i32, z: i32| {
|
||||||
let c = glam::Vec3A::new(x as f32, y as f32, z as f32);
|
let c = glam::Vec3A::new(x as f32, y as f32, z as f32);
|
||||||
let mut sum = 0.0;
|
let mut sum = metaballs[0].distance(c) - 3.75;
|
||||||
for ball in metaballs.iter() {
|
for ball in metaballs.iter() {
|
||||||
sum += 1.0 / ball.distance(c);
|
sum = sum.min(ball.distance(c) - 3.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
sum - 0.4
|
sum
|
||||||
};
|
};
|
||||||
|
|
||||||
let r = 20;
|
let r = 20;
|
||||||
|
@ -107,7 +107,7 @@ impl Metaballs {
|
||||||
data: vec![0x00; 256],
|
data: vec![0x00; 256],
|
||||||
};
|
};
|
||||||
|
|
||||||
let albedo_raw = include_bytes!("assets/brick_moss_001_diff_1k.jpg");
|
let albedo_raw = include_bytes!("assets/coast_sand_rocks_02_diff_1k.jpg");
|
||||||
let albedo_data = load_texture_data(albedo_raw);
|
let albedo_data = load_texture_data(albedo_raw);
|
||||||
|
|
||||||
let metalrough_raw = include_bytes!("assets/brick_moss_001_metalrough_1k.jpg");
|
let metalrough_raw = include_bytes!("assets/brick_moss_001_metalrough_1k.jpg");
|
||||||
|
@ -245,15 +245,15 @@ fn main() {
|
||||||
},
|
},
|
||||||
PointLight {
|
PointLight {
|
||||||
center: glam::Vec3A::new(-7.0, 5.0, 7.0),
|
center: glam::Vec3A::new(-7.0, 5.0, 7.0),
|
||||||
intensity: glam::Vec3A::new(100.0, 0.0, 0.0),
|
intensity: glam::Vec3A::new(100.0, 100.0, 0.0),
|
||||||
},
|
},
|
||||||
PointLight {
|
PointLight {
|
||||||
center: glam::Vec3A::new(7.0, 5.0, 7.0),
|
center: glam::Vec3A::new(7.0, 5.0, 7.0),
|
||||||
intensity: glam::Vec3A::new(0.0, 100.0, 0.0),
|
intensity: glam::Vec3A::new(100.0, 100.0, 100.0),
|
||||||
},
|
},
|
||||||
PointLight {
|
PointLight {
|
||||||
center: glam::Vec3A::new(0.0, 5.0, -7.0),
|
center: glam::Vec3A::new(0.0, 5.0, -7.0),
|
||||||
intensity: glam::Vec3A::new(0.0, 0.0, 100.0),
|
intensity: glam::Vec3A::new(100.0, 100.0, 100.0),
|
||||||
},
|
},
|
||||||
PointLight {
|
PointLight {
|
||||||
center: glam::Vec3A::new(0.0, 50.0, 0.0),
|
center: glam::Vec3A::new(0.0, 50.0, 0.0),
|
||||||
|
|
|
@ -66,7 +66,7 @@ pub fn marching_cubes(
|
||||||
) -> Vec<Vertex> {
|
) -> Vec<Vertex> {
|
||||||
let samples = sample_corners(scalar_field, domain);
|
let samples = sample_corners(scalar_field, domain);
|
||||||
|
|
||||||
let test = |corner| samples[&corner] > 0.0;
|
let test = |corner| samples[&corner] < 0.0;
|
||||||
|
|
||||||
// TODO this could be optimized using single-edge interpolation
|
// TODO this could be optimized using single-edge interpolation
|
||||||
// TODO improve with glam vector math
|
// TODO improve with glam vector math
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include src/shaders/basic_structs.wgsl
|
#include src/shaders/basic_structs.wgsl
|
||||||
#include src/shaders/basic_pbr.wgsl
|
#include src/shaders/basic_pbr.wgsl
|
||||||
#include src/shaders/tri_sampler.wgsl
|
#include src/shaders/tri_sampler.wgsl
|
||||||
|
#include src/shaders/raymarch.wgsl
|
||||||
|
|
||||||
[[group(0), binding(0)]]
|
[[group(0), binding(0)]]
|
||||||
var<uniform> camera: CameraUniform;
|
var<uniform> camera: CameraUniform;
|
||||||
|
@ -39,11 +40,13 @@ fn fs_main(
|
||||||
let normal = normalize(frag.normal);
|
let normal = normalize(frag.normal);
|
||||||
let view = normalize(camera.eye.xyz - frag.position);
|
let view = normalize(camera.eye.xyz - frag.position);
|
||||||
|
|
||||||
|
let march_result = Raymarch(camera.eye.xyz, -1.0 * view);
|
||||||
|
|
||||||
//let albedo = textureSample(m_albedo, m_sampler, frag.tex_coords).xyz;
|
//let albedo = textureSample(m_albedo, m_sampler, frag.tex_coords).xyz;
|
||||||
let albedo = TriSampler(m_albedo, m_sampler, frag.position / 5.0, normal, 10.0);
|
let albedo = TriSampler(m_albedo, m_sampler, march_result.position / 5.0, march_result.normal, 10.0);
|
||||||
|
|
||||||
//let metallic_roughness = textureSample(m_metallic_roughness, m_sampler, frag.tex_coords).bg;
|
//let metallic_roughness = textureSample(m_metallic_roughness, m_sampler, frag.tex_coords).bg;
|
||||||
let metallic_roughness = TriSampler(m_metallic_roughness, m_sampler, frag.position / 5.0, normal, 10.0);
|
let metallic_roughness = TriSampler(m_metallic_roughness, m_sampler, march_result.position / 5.0, march_result.normal, 10.0);
|
||||||
let metallic = metallic_roughness.x;
|
let metallic = metallic_roughness.x;
|
||||||
let roughness = metallic_roughness.y;
|
let roughness = metallic_roughness.y;
|
||||||
|
|
||||||
|
@ -57,12 +60,12 @@ fn fs_main(
|
||||||
let radiance = light_intensity / dot(light_position, light_position);
|
let radiance = light_intensity / dot(light_position, light_position);
|
||||||
|
|
||||||
let reflected = BRDF(
|
let reflected = BRDF(
|
||||||
light_direction, normal, view,
|
light_direction, march_result.normal, view,
|
||||||
albedo, metallic, roughness
|
albedo, metallic, roughness
|
||||||
);
|
);
|
||||||
|
|
||||||
lum = lum + (radiance * reflected);
|
lum = lum + (radiance * reflected);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec4<f32>(lum, 1.0);
|
return vec4<f32>(lum * march_result.mask, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
struct MarchResult {
|
||||||
|
position: vec3<f32>;
|
||||||
|
normal: vec3<f32>;
|
||||||
|
mask: f32;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn sdf_sphere(pos: vec3<f32>, origin: vec3<f32>, radius: f32) -> f32 {
|
||||||
|
return length(pos - origin) - radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sdf(pos: vec3<f32>) -> f32 {
|
||||||
|
let a = sdf_sphere(pos, vec3<f32>(-5.0, -5.0, 2.0), 3.5);
|
||||||
|
let b = sdf_sphere(pos, vec3<f32>(8.0, 0.0, -1.0), 3.5);
|
||||||
|
let c = sdf_sphere(pos, vec3<f32>(1.0, 5.0, -3.0), 3.5);
|
||||||
|
return min(min(a, b), c);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sdf_normal(pos: vec3<f32>) -> vec3<f32> {
|
||||||
|
let h = 0.0001;
|
||||||
|
let k = vec2<f32>(1.0, -1.0);
|
||||||
|
return normalize(k.xyy * sdf(pos + (k.xyy * h)) + k.yyx * sdf(pos + (k.yyx * h)) + k.yxy * sdf(pos + (k.yxy * h)) + k.xxx * sdf(pos + (k.xxx * h)));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn Raymarch(cam_pos: vec3<f32>, ray_dir: vec3<f32>) -> MarchResult {
|
||||||
|
let max_steps = 100;
|
||||||
|
let max_dist = 10000.0;
|
||||||
|
let epsilon = 0.0001;
|
||||||
|
|
||||||
|
var depth = 0.0;
|
||||||
|
var pos = vec3<f32>(0.0, 0.0, 0.0);
|
||||||
|
var mask = 1.0;
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
loop {
|
||||||
|
pos = cam_pos + (ray_dir * depth);
|
||||||
|
let dist = sdf(pos);
|
||||||
|
depth = depth + dist;
|
||||||
|
|
||||||
|
if (dist <= epsilon) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth > max_dist) {
|
||||||
|
mask = 0.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var out: MarchResult;
|
||||||
|
out.position = pos;
|
||||||
|
out.normal = sdf_normal(pos);
|
||||||
|
out.mask = mask;
|
||||||
|
return out;
|
||||||
|
}
|
Loading…
Reference in New Issue