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