3D isometric renderer: chunked meshes with noise-displaced walls, lit shader with flickering torches, billboard sprites, rotatable/tiltable ortho camera, ray picking
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
91bb91b6ee
commit
220d9543cc
6 files changed
+180
-589
No files matched your search
+22
-9
@@ -446,7 +446,7 @@ fn build_chunk(map: &Map, amb: &[f32], cx: i32, cz: i32, gold_fill: f32, atlas:
|
||||
[Vec3::Y; 4],
|
||||
);
|
||||
let n = WALL_SUB;
|
||||
let top_amb = amb_at(amb, xf + 0.5, zf + 0.5) * 0.85 + 0.05;
|
||||
let top_amb = amb_at(amb, xf + 0.5, zf + 0.5) * 0.95 + 0.1;
|
||||
build_grid(
|
||||
&mut mb,
|
||||
|u, v| vec3(xf + u, WALL_H, zf + v),
|
||||
@@ -690,6 +690,7 @@ impl R3d {
|
||||
let t = time as f32;
|
||||
self.update_chunks(g, gfx);
|
||||
let m = cam.matrix();
|
||||
EYE.with(|e| e.set(cam.eye_dir()));
|
||||
set_camera(&cam.camera());
|
||||
|
||||
// ---- lit geometry
|
||||
@@ -855,6 +856,20 @@ impl R3d {
|
||||
|
||||
// ------------------------------------------------------------------ landmarks, fx, overlay
|
||||
|
||||
// Camera direction for camera-facing line quads (set once per frame)
|
||||
thread_local! {
|
||||
static EYE: std::cell::Cell<Vec3> = std::cell::Cell::new(Vec3::Y);
|
||||
}
|
||||
|
||||
// Thick 3D line as a camera-facing quad (GL lines don't work with custom materials)
|
||||
fn line3(a: Vec3, b: Vec3, w: f32, color: Color) {
|
||||
let eye = EYE.with(|e| e.get());
|
||||
let side = (b - a).cross(eye).normalize_or_zero() * (w * 0.5);
|
||||
let c = [(color.r * 255.0) as u8, (color.g * 255.0) as u8, (color.b * 255.0) as u8, (color.a * 255.0) as u8];
|
||||
let v = |p: Vec3| Vertex { position: p, uv: Vec2::ZERO, color: c, normal: Vec4::Y };
|
||||
draw_mesh(&Mesh { vertices: vec![v(a - side), v(a + side), v(b + side), v(b - side)], indices: vec![0, 1, 2, 0, 2, 3], texture: None });
|
||||
}
|
||||
|
||||
fn disc(c: Vec3, r: f32, color: Color, seg: usize) {
|
||||
let mut v = Vec::with_capacity(seg + 1);
|
||||
let cc = [(color.r * 255.0) as u8, (color.g * 255.0) as u8, (color.b * 255.0) as u8, (color.a * 255.0) as u8];
|
||||
@@ -875,7 +890,7 @@ fn ring(c: Vec3, r: f32, color: Color) {
|
||||
for k in 0..seg {
|
||||
let a0 = k as f32 / seg as f32 * std::f32::consts::TAU;
|
||||
let a1 = (k + 1) as f32 / seg as f32 * std::f32::consts::TAU;
|
||||
draw_line_3d(c + vec3(a0.cos() * r, 0.0, a0.sin() * r), c + vec3(a1.cos() * r, 0.0, a1.sin() * r), color);
|
||||
line3(c + vec3(a0.cos() * r, 0.0, a0.sin() * r), c + vec3(a1.cos() * r, 0.0, a1.sin() * r), 0.035, color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,7 +950,7 @@ fn draw_landmarks_glow(g: &Game, t: f32) {
|
||||
draw_sphere(gc, 0.8, None, Color::new(0.7, 0.85, 1.0, 0.2));
|
||||
for k in 0..8 {
|
||||
let a = t * 0.6 + k as f32 * 0.785;
|
||||
draw_line_3d(gc, gc + vec3(a.cos() * 1.0, a.sin() * 0.9, 0.0), Color::new(0.85, 0.92, 1.0, 0.6));
|
||||
line3(gc, gc + vec3(a.cos() * 1.0, a.sin() * 0.9, 0.0), 0.05, Color::new(0.85, 0.92, 1.0, 0.6));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -986,7 +1001,7 @@ fn draw_fx(f: &Fx, t: f32) {
|
||||
let to = vec3(f.x2, 0.45, f.y2);
|
||||
let head = from.lerp(to, p);
|
||||
let tail = from.lerp(to, (p - 0.35).max(0.0));
|
||||
draw_line_3d(tail, head, a(0.8));
|
||||
line3(tail, head, 0.06, a(0.8));
|
||||
draw_sphere(head, 0.08, None, c);
|
||||
}
|
||||
1 => {
|
||||
@@ -995,7 +1010,7 @@ fn draw_fx(f: &Fx, t: f32) {
|
||||
let y = 7.0 - 7.0 * k as f32 / 9.0;
|
||||
let j = if k == 9 { 0.0 } else { (t * 50.0 + k as f32 * 13.7).sin() * 0.5 };
|
||||
let next = vec3(f.x + j, y, f.y + j * 0.5);
|
||||
draw_line_3d(prev, next, Color::new(1.0, 1.0, 0.85, 1.0 - p));
|
||||
line3(prev, next, 0.12, Color::new(1.0, 1.0, 0.85, 1.0 - p));
|
||||
prev = next;
|
||||
}
|
||||
disc(vec3(f.x, 0.05, f.y), 1.6 * (0.5 + p), Color::new(1.0, 1.0, 0.7, 0.35 * (1.0 - p)), 24);
|
||||
@@ -1004,7 +1019,7 @@ fn draw_fx(f: &Fx, t: f32) {
|
||||
let r = 0.1 + 0.3 * p;
|
||||
for k in 0..6 {
|
||||
let ang = k as f32 * 1.047;
|
||||
draw_line_3d(at, at + vec3(ang.cos() * r, (k as f32 - 2.5) * 0.06, ang.sin() * r), a(1.0 - p));
|
||||
line3(at, at + vec3(ang.cos() * r, (k as f32 - 2.5) * 0.06, ang.sin() * r), 0.04, a(1.0 - p));
|
||||
}
|
||||
}
|
||||
3 => draw_sphere(vec3(f.x, 0.3, f.y), 0.2 + 0.5 * p, None, a(0.4 * (1.0 - p))),
|
||||
@@ -1038,9 +1053,7 @@ fn draw_fx(f: &Fx, t: f32) {
|
||||
fn outline(x0: f32, z0: f32, x1: f32, z1: f32, y: f32, c: Color) {
|
||||
let p = [vec3(x0, y, z0), vec3(x1, y, z0), vec3(x1, y, z1), vec3(x0, y, z1)];
|
||||
for k in 0..4 {
|
||||
draw_line_3d(p[k], p[(k + 1) % 4], c);
|
||||
// double line for visibility
|
||||
draw_line_3d(p[k] + vec3(0.0, 0.015, 0.0), p[(k + 1) % 4] + vec3(0.0, 0.015, 0.0), c);
|
||||
line3(p[k], p[(k + 1) % 4], 0.06, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user