From 2b95e32b130e1270483501ae260147e765f465a3 Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 8 Dec 2024 02:59:36 +0300 Subject: [PATCH] Basic texturing --- Cargo.lock | 1 + Cargo.toml | 1 + models/spacecraft2.png | Bin 0 -> 57470 bytes src/bin/textured/main.rs | 14 +++++++++----- 4 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 models/spacecraft2.png diff --git a/Cargo.lock b/Cargo.lock index 0950020..35bbdd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3049,6 +3049,7 @@ dependencies = [ "flo_canvas", "flo_draw", "glam 0.27.0", + "image", "itertools 0.13.0", "itertools-num", "pollster", diff --git a/Cargo.toml b/Cargo.toml index 813c97a..7e4991a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ itertools = "0.13.0" wgpu = "22.1.0" bytemuck = { version = "1.18.0", features = ["derive"] } pollster = "0.3.0" +image = {version = "0.23", default-features = false, features = ["png"] } [dev-dependencies] approx = "0.5.1" diff --git a/models/spacecraft2.png b/models/spacecraft2.png new file mode 100644 index 0000000000000000000000000000000000000000..320a7e6f7a7a31cea913017d087311b3a8190b51 GIT binary patch literal 57470 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ʒnmgJ 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 O*A6Wm&3JW-3;zcfat(a| literal 0 HcmV?d00001 diff --git a/src/bin/textured/main.rs b/src/bin/textured/main.rs index b9e19c2..331fb1c 100644 --- a/src/bin/textured/main.rs +++ b/src/bin/textured/main.rs @@ -1,4 +1,5 @@ use glam::*; +use image::RgbImage; use refraction::mesh_loader::load_mesh; use refraction::mesh_tracer::{trace_to_mesh, Mesh}; use show_image::event::{ElementState, VirtualKeyCode, WindowEvent}; @@ -62,7 +63,7 @@ fn ypr_to_mat(ypr: Vec3) -> Mat3 { m_roll * m_pitch * m_yaw } -fn render(mesh: &Mesh, camera: impl Fn(Vec2) -> (Vec3, Vec3)) -> Image { +fn render(mesh: &Mesh, texture: &RgbImage, camera: impl Fn(Vec2) -> (Vec3, Vec3)) -> Image { let bkg = vec3(0.0, 0.0, 0.0); let mut img = Image { w: W, @@ -77,7 +78,9 @@ fn render(mesh: &Mesh, camera: impl Fn(Vec2) -> (Vec3, Vec3)) -> Image { let (base, ray) = camera(off); let color = if let Some(r) = trace_to_mesh(mesh, base, ray.normalize()) { // to_vec3(0.45) * dot(r.normal, normalize(vec3(-1.0, 1.0, -1.0))) + 0.50 - vec3(r.tex_coords.x, r.tex_coords.y, 0.) + let x = (r.tex_coords.x * texture.width() as f32) as u32; + let y = (r.tex_coords.y * texture.height() as f32) as u32; + texture.get_pixel(x, y).0.map(|channel| channel as f32 / 255.).into() } else { bkg }; @@ -116,8 +119,8 @@ static PROJS: [fn(dist: f32, off: Vec2) -> (Vec3, Vec3); 2] = [persp, ortho]; #[show_image::main] fn main() -> Result<(), Box> { let args: Vec = env::args().collect(); - if args.len() != 2 { - println!("Usage: {} path/to/model.obj", args[0]); + if args.len() != 3 { + println!("Usage: {} path/to/model.obj path/to/texture.png", args[0]); exit(1); } let mesh = { @@ -125,6 +128,7 @@ fn main() -> Result<(), Box> { let mut f = BufReader::new(f); load_mesh(&mut f)? }; + let texture = image::io::Reader::open(&args[2])?.decode()?.into_rgb8(); let window = show_image::create_window("Raytracing", WindowOptions::default())?; window.add_event_handler(|_wnd, ev, _ctl| { if let WindowEvent::KeyboardInput(ev) = ev { @@ -141,7 +145,7 @@ fn main() -> Result<(), Box> { let proj = PROJS[PROJ_INDEX.load(Relaxed)]; let m_view = ypr_to_mat(vec3((135.0 + phi as f32) * PI / 180.0, -30.0 * PI / 180.0, 0.0f32)); let m_camera = m_view.transpose(); - let img = render(mesh.as_slice(), |off| { + let img = render(mesh.as_slice(), &texture, |off| { let (base, ray) = proj(40., 20. * off); (m_camera * base, m_camera * ray) });