SDF geo hybrid test

This commit is contained in:
Skye Terran 2022-03-08 12:41:39 -08:00
parent 8f570b5cc6
commit 44372dfc09
6 changed files with 71 additions and 12 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 KiB

View File

@ -71,12 +71,12 @@ impl Metaballs {
let field = |x: i32, y: i32, z: i32| {
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() {
sum += 1.0 / ball.distance(c);
sum = sum.min(ball.distance(c) - 3.75);
}
sum - 0.4
sum
};
let r = 20;
@ -107,7 +107,7 @@ impl Metaballs {
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 metalrough_raw = include_bytes!("assets/brick_moss_001_metalrough_1k.jpg");
@ -245,15 +245,15 @@ fn main() {
},
PointLight {
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 {
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 {
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 {
center: glam::Vec3A::new(0.0, 50.0, 0.0),

View File

@ -66,7 +66,7 @@ pub fn marching_cubes(
) -> Vec<Vertex> {
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 improve with glam vector math

View File

@ -1,6 +1,7 @@
#include src/shaders/basic_structs.wgsl
#include src/shaders/basic_pbr.wgsl
#include src/shaders/tri_sampler.wgsl
#include src/shaders/raymarch.wgsl
[[group(0), binding(0)]]
var<uniform> camera: CameraUniform;
@ -39,11 +40,13 @@ fn fs_main(
let normal = normalize(frag.normal);
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 = 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 = 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 roughness = metallic_roughness.y;
@ -57,12 +60,12 @@ fn fs_main(
let radiance = light_intensity / dot(light_position, light_position);
let reflected = BRDF(
light_direction, normal, view,
light_direction, march_result.normal, view,
albedo, metallic, roughness
);
lum = lum + (radiance * reflected);
}
return vec4<f32>(lum, 1.0);
return vec4<f32>(lum * march_result.mask, 1.0);
}

56
src/shaders/raymarch.wgsl Normal file
View File

@ -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;
}