feat: add 3d support
This commit is contained in:
+75
-24
@@ -19,30 +19,81 @@ fn vs_main(@builtin(vertex_index) idx: u32) -> @builtin(position) vec4<f32> {
|
||||
return vec4<f32>(fullscreen_triangle_pos(idx), 0.0, 1.0);
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_main(@builtin(position) pos: vec4<f32>) -> @location(0) vec4<f32> {
|
||||
if u.shadow != 0u {
|
||||
let x = i32(pos.x);
|
||||
let y = i32(pos.y);
|
||||
if textureLoad(data_tex, vec2<i32>(x, y), 0).b != 0. {
|
||||
return vec4<f32>(0.1, 0.1, 0.1, 1.0);
|
||||
} else {
|
||||
let h0 = textureLoad(data_tex, vec2<i32>(x, y), 0).g;
|
||||
let h1 = textureLoad(data_tex, vec2<i32>(x + 1, y), 0).g;
|
||||
let h2 = textureLoad(data_tex, vec2<i32>(x, y + 1), 0).g;
|
||||
let normal = normal_from_heights(h0, h1, h2);
|
||||
return vec4<f32>(shadow_color(normal), 1.0);
|
||||
}
|
||||
} else {
|
||||
let d = textureLoad(data_tex, vec2<i32>(i32(pos.x), i32(pos.y)), 0);
|
||||
let ci = d.r;
|
||||
let de = d.g;
|
||||
let interior_frac = d.b;
|
||||
fn shadow_fragment(pos: vec3<f32>) -> vec4<f32> {
|
||||
|
||||
var col = classic_color(ci, de);
|
||||
// Anti-alias the set boundary: fade toward black by the fraction of the
|
||||
// pixel's sub-samples that landed in the interior.
|
||||
col = col * (1.0 - interior_frac);
|
||||
return vec4<f32>(col, 1.0);
|
||||
let x = i32(pos.x);
|
||||
let y = i32(pos.y);
|
||||
if textureLoad(data_tex, vec2<i32>(x, y), 0).b != 0. {
|
||||
return vec4<f32>(0.1, 0.1, 0.1, 1.0);
|
||||
} else {
|
||||
let h0 = textureLoad(data_tex, vec2<i32>(x, y), 0).g;
|
||||
let h1 = textureLoad(data_tex, vec2<i32>(x + 1, y), 0).g;
|
||||
let h2 = textureLoad(data_tex, vec2<i32>(x, y + 1), 0).g;
|
||||
let normal = normal_from_heights(h0, h1, h2);
|
||||
return vec4<f32>(shadow_color(normal), 1.0);
|
||||
}
|
||||
}
|
||||
@fragment
|
||||
fn fs_main(@builtin(position) pos: vec4<f32>) -> @location(0) vec4<f32> {
|
||||
if u.dimension3 == 0u {
|
||||
if u.shadow != 0u {
|
||||
return shadow_fragment(pos.xyz);
|
||||
} else {
|
||||
let d = textureLoad(data_tex, vec2<i32>(i32(pos.x), i32(pos.y)), 0);
|
||||
let ci = d.r;
|
||||
let de = d.g;
|
||||
let interior_frac = d.b;
|
||||
|
||||
var col = classic_color(ci, de);
|
||||
// Anti-alias the set boundary: fade toward black by the fraction of the
|
||||
// pixel's sub-samples that landed in the interior.
|
||||
col = col * (1.0 - interior_frac);
|
||||
return vec4<f32>(col, 1.0);
|
||||
}
|
||||
} else {
|
||||
return ray_marching(pos);
|
||||
}
|
||||
}
|
||||
|
||||
fn sdf(pos: vec3<f32>) -> f32 {
|
||||
let texture_pos = vec2<i32>(i32(pos.x), i32(pos.y));
|
||||
let px = textureLoad(data_tex, texture_pos, 0);
|
||||
let de = px.g;
|
||||
let z = pos.z;
|
||||
if px.b != 0. {
|
||||
return 0.;
|
||||
} else {
|
||||
return sqrt(z * z + (de * de));
|
||||
}
|
||||
}
|
||||
|
||||
fn ray_marching(pos: vec4<f32>) -> vec4<f32> {
|
||||
let size = vec2<f32>(textureDimensions(data_tex));
|
||||
let in_texture = vec2<f32>(
|
||||
pos.x / 1980. * size.x,
|
||||
pos.y / 1080. * size.y,
|
||||
);
|
||||
|
||||
var world_pos = u.camera_inv_proj * vec4<f32>(in_texture, pos.z - 10, 1.0);
|
||||
|
||||
let ray_origin = world_pos.xyz;
|
||||
let ray_dir = u.camera_direction;
|
||||
|
||||
var p = ray_origin;
|
||||
var i = 0u;
|
||||
var dist = 0.0;
|
||||
|
||||
while i < 1000u {
|
||||
dist = sdf(p);
|
||||
if dist < 0.0001 {
|
||||
break;
|
||||
}
|
||||
p += dist * ray_dir;
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
if dist < 0.0001 {
|
||||
return shadow_fragment(p);
|
||||
}
|
||||
return vec4<f32>(1., 0., 0., 1.);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,13 @@ struct Uniforms {
|
||||
de_coloring: u32,
|
||||
// 0 = classic colors, 1 = shadows
|
||||
shadow: u32,
|
||||
// Use 3D raymarching rendering
|
||||
dimension3: u32,
|
||||
// camera direction vector
|
||||
camera_direction: vec3<f32>,
|
||||
// inverse of the camera's view-projection matrix, for reconstructing a
|
||||
// world-space ray origin per pixel in the raymarcher
|
||||
camera_inv_proj: mat4x4<f32>,
|
||||
};
|
||||
|
||||
// Smooth cyclic palettes (Inigo Quilez cosine palettes), selected by id.
|
||||
@@ -146,10 +153,10 @@ fn shadow_color(normal: vec3<f32>) -> vec3<f32> {
|
||||
for (var i = 0u; i < 16; i++) {
|
||||
let light_color = unpack4x8unorm(lights[i].color);
|
||||
if any(light_color != vec4<f32>(0)) {
|
||||
light_count += 1;
|
||||
light_count += 1;
|
||||
}
|
||||
|
||||
color += compute_light(normal, vec3<f32>(
|
||||
color += compute_light(normal, vec3<f32>(
|
||||
cos(lights[i].azimuth) * cos(lights[i].altitude),
|
||||
sin(lights[i].azimuth) * cos(lights[i].altitude),
|
||||
sin(lights[i].altitude))) * light_color.xyz * light_color.a;
|
||||
|
||||
Reference in New Issue
Block a user