fix: correct 3d rendering

This commit is contained in:
2026-09-23 18:34:00 +02:00
parent 694f63ab9d
commit 63cee5d8b2
9 changed files with 290 additions and 173 deletions
+22 -37
View File
@@ -9,9 +9,7 @@ pub struct Camera {
pub yaw: f32,
pub pitch: f32,
/// Demi-hauteur du volume visible (remplace fov_y_radians)
ortho_height: f32,
aspect_ratio: f32,
pub aspect_ratio: f32,
z_near: f32,
z_far: f32,
}
@@ -21,8 +19,7 @@ impl Camera {
Self {
position: Vec3::new(0., 0., -1.),
yaw: 0. * PI / 180.,
pitch: 0. * PI / 180.,
ortho_height: 1.0,
pitch: -30. * PI / 180.,
aspect_ratio: 1.,
z_near: 0.1,
z_far: 100.,
@@ -33,19 +30,6 @@ impl Camera {
self.aspect_ratio = aspect_ratio;
}
/// Camera-local right vector: perpendicular to yaw, ignoring pitch (so
/// strafing stays level regardless of where the camera is looking).
pub fn right(&self) -> glam::Vec3 {
glam::Mat3::from_rotation_y(-self.yaw) * glam::Vec3::X
}
/// Move the camera in its own local space: `forward`/`right` follow the
/// (pitch-aware) view direction and its horizontal right vector, `up`
/// moves along the fixed world Y axis.
pub fn translate(&mut self, forward: f32, right: f32, up: f32) {
self.position += self.direction() * forward + self.right() * right + Vec3::Y * up;
}
/// Adjust yaw/pitch by the given deltas (radians). Pitch is clamped just
/// short of straight up/down to avoid the view flipping past the pole.
pub fn rotate(&mut self, dyaw: f32, dpitch: f32) {
@@ -54,33 +38,34 @@ impl Camera {
self.pitch = (self.pitch + dpitch).clamp(-PITCH_LIMIT, PITCH_LIMIT);
}
/// Scale the visible ortho volume by `factor` (<1 zooms in, >1 zooms
/// out), clamped to a sane range.
pub fn zoom(&mut self, factor: f32) {
self.ortho_height = (self.ortho_height * factor).clamp(0.001, 1000.0);
}
pub fn orthographic(&self, t: f32) -> glam::Mat4 {
let yaw = self.yaw * t;
let pitch = self.pitch * t;
pub fn orthographic(&self) -> glam::Mat4 {
let view = glam::Mat4::from_translation(self.position)
* glam::Mat4::from_rotation_y(-self.yaw)
* glam::Mat4::from_rotation_x(-self.pitch);
let half_height = self.ortho_height;
let half_width = half_height * self.aspect_ratio;
let zoom = 0.5 * (1. + t);
// Orbit pivot: the center of the fractal texture, which the raymarcher's
// `sdf` lays out over world x ∈ [0, aspect], y ∈ [0, 1] on the z = 0 plane.
let view = glam::Mat4::from_translation(Vec3::new(0.5 * self.aspect_ratio, 0.5, 0.))
* glam::Mat4::from_rotation_z(-yaw)
* glam::Mat4::from_rotation_x(-pitch)
* glam::Mat4::from_translation(self.position);
glam::camera::lh::proj::directx::orthographic(
-half_width,
half_width,
-half_height,
half_height,
-self.aspect_ratio / 4. / zoom,
self.aspect_ratio / 4. / zoom,
-0.25 / zoom,
0.25 / zoom,
self.z_near,
self.z_far,
) * view.inverse()
}
pub fn direction(&self) -> glam::Vec3 {
let forward = glam::Mat3::from_rotation_y(-self.yaw)
* glam::Mat3::from_rotation_x(-self.pitch)
pub fn direction(&self, t: f32) -> glam::Vec3 {
let yaw = self.yaw * t;
let pitch = self.pitch * t;
let forward = glam::Mat3::from_rotation_z(-yaw)
* glam::Mat3::from_rotation_x(-pitch)
* glam::Vec3::Z;
forward.normalize()