Skip to content

Instantly share code, notes, and snippets.

@seanjensengrey
Forked from joshmarinacci/main.rs
Last active November 6, 2015 18:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save seanjensengrey/b32d8bce178fcbbd52a1 to your computer and use it in GitHub Desktop.
Save seanjensengrey/b32d8bce178fcbbd52a1 to your computer and use it in GitHub Desktop.
text mode ray tracer in rust, updated for 1.0.0 https://play.rust-lang.org/?gist=e456eccb298bf26da4f8&version=stable
#[derive(Copy,Clone,Debug)]
struct Vector {
x:f32,
y:f32,
z:f32
}
impl Vector {
fn new(x:f32,y:f32,z:f32) -> Vector {
Vector { x:x, y:y, z:z }
}
fn scale(&self, s:f32) -> Vector { Vector { x:self.x*s, y:self.y*s, z:self.z*s } }
fn plus(&self, b:&Vector) -> Vector { Vector::new(self.x+b.x, self.y+b.y, self.z+b.z) }
fn minus(&self, b:&Vector) -> Vector { Vector::new(self.x-b.x, self.y-b.y, self.z-b.z) }
fn dot(&self, b:&Vector) -> f32 { self.x*b.x + self.y*b.y + self.z*b.z }
fn magnitude(&self) -> f32 { (self.dot(self)).sqrt() }
fn normalize(&self) -> Vector { self.scale(1.0/self.magnitude()) }
}
#[derive(Copy,Clone,Debug)]
struct Ray {
orig:Vector,
dir:Vector,
}
#[derive(Copy,Clone,Debug)]
struct Color {
r:f32,
g:f32,
b:f32,
}
impl Color {
fn scale (&self, s:f32) -> Color {
Color { r: self.r*s, g:self.g*s, b:self.b*s }
}
fn plus (&self, b:Color) -> Color {
Color { r: self.r + b.r, g: self.g + b.g, b: self.b + b.b }
}
}
#[derive(Copy,Clone,Debug)]
struct Sphere {
center:Vector,
radius:f32,
color: Color,
}
impl Sphere {
fn get_normal(&self, pt:Vector) -> Vector {
return pt.minus(&self.center).normalize();
}
}
struct Light {
position: Vector,
color: Color,
}
const WHITE:Color = Color { r:1.0, g:1.0, b:1.0};
#[allow(dead_code)]
const RED:Color = Color { r:1.0, g:0.0, b:0.0};
const GREEN:Color = Color { r:0.0, g:1.0, b:0.0};
#[allow(dead_code)]
const BLUE:Color = Color { r:0.0, g:0.0, b:1.0};
const LIGHT1:Light = Light {
position: Vector { x: 0.7, y: -1.0, z: 1.7} ,
color: WHITE
};
fn main() {
println!("Hello, worlds!");
let lut = vec!(".","-","+","*","X","M");
let w = 40;
let h = w/2;
let scene = vec!(
//Sphere{ center: Vector::new(-1.0, 0.0, 3.0), radius: 0.3, color: RED },
Sphere{ center: Vector::new( 0.0, 0.0, 3.0), radius: 0.8, color: GREEN }
//Sphere{ center: Vector::new( 1.0, 0.0, 3.0), radius: 0.3, color: BLUE }
);
for j in (0..h) {
println!("--");
for i in (0..w) {
//let tMax = 10000f32;
let fw:f32 = w as f32;
let fi:f32 = i as f32;
let fj:f32 = j as f32;
let fh:f32 = h as f32;
let ray = Ray {
orig: Vector::new(0.0,0.0,0.0),
dir: Vector::new((fi-fw/2.0)/fw, (fj-fh/2.0)/fh,1.0).normalize(),
};
let mut obj_hit_obj:Option<(Sphere,f32)> = None;
for obj in scene.iter() {
let ret = intersect_sphere(&ray, &obj.center, obj.radius);
if ret.hit {
obj_hit_obj = Some((*obj,ret.tval));
}
}
let pixel = match obj_hit_obj {
Some((obj,tval)) => lut[shade_pixel(ray,obj,tval)],
None => " "
};
print!("{}",pixel);
}
}
println!("we are done!");
}
fn shade_pixel(ray:Ray, obj:Sphere, tval:f32) -> usize {
let pi = ray.orig.plus(&ray.dir.scale(tval));
let color = diffuse_shading(pi, obj, LIGHT1);
let col = (color.r + color.g + color.b) / 3.0;
(col * 6.0) as usize
}
struct HitPoint {
hit:bool,
tval:f32,
}
fn intersect_sphere(ray:&Ray, center:&Vector, radius:f32) -> HitPoint {
let l = center.minus(&ray.orig);
let tca = l.dot(&ray.dir);
if tca < 0.0 {
return HitPoint { hit:false, tval:-1.0 };
}
let d2 = l.dot(&l) - tca*tca;
let r2 = radius*radius;
if d2 > r2 {
return HitPoint { hit: false, tval:-1.0 };
}
let thc = (r2-d2).sqrt();
let t0 = tca-thc;
//let t1 = tca+thc;
if t0 > 10000.0 {
return HitPoint { hit: false, tval: -1.0 };
}
return HitPoint { hit: true, tval: t0}
}
fn clamp(x:f32,a:f32,b:f32) -> f32{
if x < a { return a; }
if x > b { return b; }
return x;
}
fn diffuse_shading(pi:Vector, obj:Sphere, light:Light) -> Color{
let n = obj.get_normal(pi);
let lam1 = light.position.minus(&pi).normalize().dot(&n);
let lam2 = clamp(lam1,0.0,1.0);
light.color.scale(lam2*0.5).plus(obj.color.scale(0.3))
}
@seanjensengrey
Copy link
Author


Hello, worlds!
--
                                        --
                                        --
                                        --
                                        --
                                        --
                --++++**+               --
             .---++++*******            --
           ..----+++++*******+          --
          ....----++++++*****++         --
          ....------+++++++++++         --
         .......-------+++++++--        --
          ........-------------         --
          ...........---------.         --
           ...................          --
             ...............            --
                .........               --
                                        --
                                        --
                                        --
                                        we are done!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment