Texture?
This commit is contained in:
parent
6b25722627
commit
7c8d67c909
BIN
models/spacecraft2-shape.png
Normal file
BIN
models/spacecraft2-shape.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
|
|
@ -1,6 +1,5 @@
|
||||||
# Blender 3.6.5
|
# Blender 3.6.5
|
||||||
# www.blender.org
|
# www.blender.org
|
||||||
mtllib spacecraft2.mtl
|
|
||||||
o Cube
|
o Cube
|
||||||
v -1.000000 0.000000 3.000000
|
v -1.000000 0.000000 3.000000
|
||||||
v -2.000000 0.000000 2.000000
|
v -2.000000 0.000000 2.000000
|
||||||
|
|
@ -60,50 +59,68 @@ vn 0.3487 -0.9300 -0.1162
|
||||||
vn -0.4444 -0.8889 -0.1111
|
vn -0.4444 -0.8889 -0.1111
|
||||||
vn -0.3015 -0.9045 0.3015
|
vn -0.3015 -0.9045 0.3015
|
||||||
vn 0.2182 -0.4364 0.8729
|
vn 0.2182 -0.4364 0.8729
|
||||||
vt 0.000000 0.000000
|
vt 0.342147 0.420195
|
||||||
|
vt 0.509380 0.482116
|
||||||
|
vt 0.342147 0.586861
|
||||||
|
vt 0.513220 0.668431
|
||||||
|
vt 0.680454 0.813685
|
||||||
|
vt 0.000000 0.840390
|
||||||
|
vt 0.684294 1.000000
|
||||||
|
vt 0.855367 0.914903
|
||||||
|
vt 0.855367 0.748236
|
||||||
|
vt 0.684294 0.666667
|
||||||
|
vt 0.594917 0.481234
|
||||||
|
vt 0.680454 0.147018
|
||||||
|
vt 0.769831 0.415785
|
||||||
|
vt 0.769830 0.582451
|
||||||
|
vt 0.513220 0.335097
|
||||||
|
vt 0.000000 0.173723
|
||||||
|
vt 0.684294 0.000000
|
||||||
|
vt 0.855367 0.248236
|
||||||
|
vt 0.855367 0.081569
|
||||||
|
vt 0.684294 0.333333
|
||||||
s 0
|
s 0
|
||||||
usemtl Material
|
f 8/1/1 18/2/1 16/3/1
|
||||||
f 8/1/1 18/1/1 16/1/1
|
f 16/3/2 18/2/2 15/4/2
|
||||||
f 16/1/2 18/1/2 15/1/2
|
f 18/2/3 19/5/3 15/4/3
|
||||||
f 18/1/3 19/1/3 15/1/3
|
f 15/4/4 19/5/4 14/6/4
|
||||||
f 15/1/4 19/1/4 14/1/4
|
f 14/6/5 19/5/5 13/7/5
|
||||||
f 14/1/5 19/1/5 13/1/5
|
f 13/7/6 19/5/6 12/8/6
|
||||||
f 13/1/6 19/1/6 12/1/6
|
f 12/8/7 19/5/7 11/9/7
|
||||||
f 12/1/7 19/1/7 11/1/7
|
f 10/10/8 11/9/8 19/5/8
|
||||||
f 10/1/8 11/1/8 19/1/8
|
f 20/11/9 18/2/9 17/12/9
|
||||||
f 20/1/9 18/1/9 17/1/9
|
f 1/13/7 9/14/7 20/11/7
|
||||||
f 1/1/7 9/1/7 20/1/7
|
f 9/14/10 10/10/10 20/11/10
|
||||||
f 9/1/10 10/1/10 20/1/10
|
f 20/11/11 10/10/11 19/5/11
|
||||||
f 20/1/11 10/1/11 19/1/11
|
f 6/15/12 18/2/12 8/1/12
|
||||||
f 6/1/12 18/1/12 8/1/12
|
f 18/2/13 6/15/13 17/12/13
|
||||||
f 18/1/13 6/1/13 17/1/13
|
f 6/15/14 7/16/14 17/12/14
|
||||||
f 6/1/14 7/1/14 17/1/14
|
f 5/17/15 17/12/15 7/16/15
|
||||||
f 5/1/15 17/1/15 7/1/15
|
f 3/18/7 17/12/7 4/19/7
|
||||||
f 3/1/7 17/1/7 4/1/7
|
f 4/19/8 17/12/8 5/17/8
|
||||||
f 4/1/8 17/1/8 5/1/8
|
f 2/20/6 17/12/6 3/18/6
|
||||||
f 2/1/6 17/1/6 3/1/6
|
f 1/13/16 20/11/16 2/20/16
|
||||||
f 1/1/16 20/1/16 2/1/16
|
f 17/12/17 2/20/17 20/11/17
|
||||||
f 17/1/17 2/1/17 20/1/17
|
f 20/11/9 19/5/9 18/2/9
|
||||||
f 20/1/9 19/1/9 18/1/9
|
f 8/1/18 16/3/18 22/2/18
|
||||||
f 8/1/18 16/1/18 22/1/18
|
f 16/3/19 15/4/19 22/2/19
|
||||||
f 16/1/19 15/1/19 22/1/19
|
f 22/2/20 15/4/20 23/5/20
|
||||||
f 22/1/20 15/1/20 23/1/20
|
f 15/4/21 14/6/21 23/5/21
|
||||||
f 15/1/21 14/1/21 23/1/21
|
f 14/6/22 13/7/22 23/5/22
|
||||||
f 14/1/22 13/1/22 23/1/22
|
f 13/7/23 12/8/23 23/5/23
|
||||||
f 13/1/23 12/1/23 23/1/23
|
f 12/8/24 11/9/24 23/5/24
|
||||||
f 12/1/24 11/1/24 23/1/24
|
f 10/10/25 23/5/25 11/9/25
|
||||||
f 10/1/25 23/1/25 11/1/25
|
f 24/11/26 21/12/26 22/2/26
|
||||||
f 24/1/26 21/1/26 22/1/26
|
f 1/13/24 24/11/24 9/14/24
|
||||||
f 1/1/24 24/1/24 9/1/24
|
f 9/14/27 24/11/27 10/10/27
|
||||||
f 9/1/27 24/1/27 10/1/27
|
f 24/11/28 23/5/28 10/10/28
|
||||||
f 24/1/28 23/1/28 10/1/28
|
f 6/15/29 8/1/29 22/2/29
|
||||||
f 6/1/29 8/1/29 22/1/29
|
f 22/2/30 21/12/30 6/15/30
|
||||||
f 22/1/30 21/1/30 6/1/30
|
f 6/15/31 21/12/31 7/16/31
|
||||||
f 6/1/31 21/1/31 7/1/31
|
f 5/17/32 7/16/32 21/12/32
|
||||||
f 5/1/32 7/1/32 21/1/32
|
f 3/18/24 4/19/24 21/12/24
|
||||||
f 3/1/24 4/1/24 21/1/24
|
f 4/19/25 5/17/25 21/12/25
|
||||||
f 4/1/25 5/1/25 21/1/25
|
f 2/20/23 3/18/23 21/12/23
|
||||||
f 2/1/23 3/1/23 21/1/23
|
f 1/13/33 2/20/33 24/11/33
|
||||||
f 1/1/33 2/1/33 24/1/33
|
f 21/12/34 24/11/34 2/20/34
|
||||||
f 21/1/34 24/1/34 2/1/34
|
f 24/11/26 22/2/26 23/5/26
|
||||||
f 24/1/26 22/1/26 23/1/26
|
|
||||||
|
|
|
||||||
153
src/bin/textured/main.rs
Normal file
153
src/bin/textured/main.rs
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
use glam::*;
|
||||||
|
use refraction::mesh_loader::load_mesh;
|
||||||
|
use refraction::mesh_tracer::{trace_to_mesh, Mesh};
|
||||||
|
use show_image::event::{ElementState, VirtualKeyCode, WindowEvent};
|
||||||
|
use show_image::{exit, ImageInfo, ImageView, WindowOptions};
|
||||||
|
use std::env;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::f32::consts::PI;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
|
||||||
|
|
||||||
|
const W: i32 = 320;
|
||||||
|
const H: i32 = 240;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct Color(u8, u8, u8);
|
||||||
|
|
||||||
|
struct Image {
|
||||||
|
w: i32,
|
||||||
|
h: i32,
|
||||||
|
data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Image {
|
||||||
|
fn data(&self) -> &[u8] {
|
||||||
|
self.data.as_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn put_pixel(&mut self, x: i32, y: i32, color: Color) {
|
||||||
|
if x < 0 || x >= self.w || y < 0 || y > self.h {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let index = 3 * (x + self.w * y) as usize;
|
||||||
|
self.data[index] = color.0;
|
||||||
|
self.data[index + 1] = color.1;
|
||||||
|
self.data[index + 2] = color.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ypr_to_mat(ypr: Vec3) -> Mat3 {
|
||||||
|
let Vec3 {
|
||||||
|
x: yaw,
|
||||||
|
y: pitch,
|
||||||
|
z: roll,
|
||||||
|
} = ypr;
|
||||||
|
let m_roll = mat3(
|
||||||
|
vec3(roll.cos(), roll.sin(), 0.0),
|
||||||
|
vec3(-roll.sin(), roll.cos(), 0.0),
|
||||||
|
vec3(0.0, 0.0, 1.0),
|
||||||
|
);
|
||||||
|
let m_yaw = mat3(
|
||||||
|
vec3(yaw.cos(), 0.0, yaw.sin()),
|
||||||
|
vec3(0.0, 1.0, 0.0),
|
||||||
|
vec3(-yaw.sin(), 0.0, yaw.cos()),
|
||||||
|
);
|
||||||
|
let m_pitch = mat3(
|
||||||
|
vec3(1.0, 0.0, 0.0),
|
||||||
|
vec3(0.0, pitch.cos(), -pitch.sin()),
|
||||||
|
vec3(0.0, pitch.sin(), pitch.cos()),
|
||||||
|
);
|
||||||
|
m_roll * m_pitch * m_yaw
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(mesh: &Mesh, camera: impl Fn(Vec2) -> (Vec3, Vec3)) -> Image {
|
||||||
|
let bkg = vec3(0.0, 0.0, 0.0);
|
||||||
|
let mut img = Image {
|
||||||
|
w: W,
|
||||||
|
h: H,
|
||||||
|
data: vec![0; (3 * W * H) as usize],
|
||||||
|
};
|
||||||
|
let img_size = vec2(W as f32, H as f32);
|
||||||
|
for y in 0..H {
|
||||||
|
for x in 0..W {
|
||||||
|
let img_coords = vec2(x as f32, y as f32);
|
||||||
|
let off = (img_coords - img_size * 0.5) / img_size.y;
|
||||||
|
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.)
|
||||||
|
} else {
|
||||||
|
bkg
|
||||||
|
};
|
||||||
|
let color = (color * 255.0).as_ivec3().clamp(IVec3::splat(0), IVec3::splat(255));
|
||||||
|
img.put_pixel(x, y, Color(color.x as u8, color.y as u8, color.z as u8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
img
|
||||||
|
}
|
||||||
|
|
||||||
|
fn persp(dist: f32, off: Vec2) -> (Vec3, Vec3) {
|
||||||
|
(vec3(0., 0., -dist), vec3(off.x, off.y, dist))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ortho(dist: f32, off: Vec2) -> (Vec3, Vec3) {
|
||||||
|
(vec3(off.x, off.y, -dist), vec3(0., 0., 1.))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_projs() {
|
||||||
|
fn check(f: fn(dist: f32, off: Vec2) -> (Vec3, Vec3), x: f32, y: f32, z: f32) {
|
||||||
|
let (base, ray) = f(z, vec2(x, y));
|
||||||
|
let at_dist = base + ray * (z / ray.z);
|
||||||
|
assert_eq!(at_dist, vec3(x, y, 0.));
|
||||||
|
}
|
||||||
|
check(persp, 1., 2., 3.);
|
||||||
|
check(ortho, 1., 2., 3.);
|
||||||
|
check(persp, 5., 3., 7.);
|
||||||
|
check(ortho, 9., 1., 8.);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add_event_handler wants 'static + Send. Let it be so.
|
||||||
|
static PROJ_INDEX: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
static PROJS: [fn(dist: f32, off: Vec2) -> (Vec3, Vec3); 2] = [persp, ortho];
|
||||||
|
|
||||||
|
#[show_image::main]
|
||||||
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
if args.len() != 2 {
|
||||||
|
println!("Usage: {} path/to/model.obj", args[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
let mesh = {
|
||||||
|
let f = File::open(&args[1])?;
|
||||||
|
let mut f = BufReader::new(f);
|
||||||
|
load_mesh(&mut f)?
|
||||||
|
};
|
||||||
|
let window = show_image::create_window("Raytracing", WindowOptions::default())?;
|
||||||
|
window.add_event_handler(|_wnd, ev, _ctl| {
|
||||||
|
if let WindowEvent::KeyboardInput(ev) = ev {
|
||||||
|
if ev.input.state != ElementState::Pressed {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some(VirtualKeyCode::Tab) = ev.input.key_code {
|
||||||
|
PROJ_INDEX.store((PROJ_INDEX.load(Relaxed) + 1) % PROJS.len(), Relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
loop {
|
||||||
|
for phi in 0..360 {
|
||||||
|
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 (base, ray) = proj(40., 20. * off);
|
||||||
|
(m_camera * base, m_camera * ray)
|
||||||
|
});
|
||||||
|
|
||||||
|
let image = ImageView::new(ImageInfo::rgb8(W as u32, H as u32), img.data());
|
||||||
|
window.set_image("image", image)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ use std::io;
|
||||||
struct ObjVertex {
|
struct ObjVertex {
|
||||||
vertex: usize,
|
vertex: usize,
|
||||||
normal: usize,
|
normal: usize,
|
||||||
// tex_coord: usize,
|
tex_coord: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
|
@ -39,7 +39,7 @@ impl ObjMesh {
|
||||||
assert_eq!(tokens.len(), 3);
|
assert_eq!(tokens.len(), 3);
|
||||||
ObjVertex {
|
ObjVertex {
|
||||||
vertex: tokens[0],
|
vertex: tokens[0],
|
||||||
// tex_coord: tokens[1],
|
tex_coord: tokens[1],
|
||||||
normal: tokens[2],
|
normal: tokens[2],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -80,6 +80,7 @@ impl ObjMesh {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|face| Face {
|
.map(|face| Face {
|
||||||
vertices: face.vertices.map(|iv| self.vertices[iv.vertex]),
|
vertices: face.vertices.map(|iv| self.vertices[iv.vertex]),
|
||||||
|
tex_coords: face.vertices.map(|iv| self.tex_coords[iv.tex_coord]),
|
||||||
normal: self.normals[face.vertices[0].normal],
|
normal: self.normals[face.vertices[0].normal],
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|
@ -89,6 +90,7 @@ impl ObjMesh {
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Face {
|
pub struct Face {
|
||||||
pub vertices: [Vec3; 3],
|
pub vertices: [Vec3; 3],
|
||||||
|
pub tex_coords: [Vec2; 3],
|
||||||
pub normal: Vec3,
|
pub normal: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
use crate::mesh_loader::Face;
|
use crate::mesh_loader::Face;
|
||||||
use glam::{mat3, Vec3};
|
use glam::{mat3, vec3, Vec2, Vec3};
|
||||||
|
|
||||||
pub type Mesh = [Face];
|
pub type Mesh = [Face];
|
||||||
|
|
||||||
pub struct TraceResult {
|
pub struct TraceResult {
|
||||||
pub distance: f32,
|
pub distance: f32,
|
||||||
|
pub tex_coords: Vec2,
|
||||||
pub normal: Vec3,
|
pub normal: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -17,8 +18,10 @@ pub fn trace_to_mesh_all(mesh: &Mesh, base: Vec3, ray: Vec3) -> impl Iterator<It
|
||||||
let m = mat3(f.vertices[1] - f.vertices[0], f.vertices[2] - f.vertices[0], -ray);
|
let m = mat3(f.vertices[1] - f.vertices[0], f.vertices[2] - f.vertices[0], -ray);
|
||||||
let m = m.inverse();
|
let m = m.inverse();
|
||||||
let rel = m * (base - f.vertices[0]);
|
let rel = m * (base - f.vertices[0]);
|
||||||
|
let w = vec3(1. - rel.x - rel.y, rel.x, rel.y);
|
||||||
Some(TraceResult {
|
Some(TraceResult {
|
||||||
distance: rel.z,
|
distance: rel.z,
|
||||||
|
tex_coords: w.x * f.tex_coords[0] + w.y * f.tex_coords[1] + w.z * f.tex_coords[2],
|
||||||
normal: f.normal,
|
normal: f.normal,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user