first gradient

This commit is contained in:
2023-01-27 00:34:08 +01:00
parent b7db0ed40a
commit bdda31935e
5 changed files with 652 additions and 262153 deletions

262547
img.ppm

File diff suppressed because it is too large Load Diff

11
src/color.rs Normal file
View File

@@ -0,0 +1,11 @@
use std::io::{Write};
use crate::vec3::*;
pub fn write_color<T: Write>(buffer: &mut T, pixel_color: Color) {
write!(buffer, "{} {} {} ",
(255.999 * pixel_color.x()).round(),
(255.999 * pixel_color.y()).round(),
(255.999 * pixel_color.z()).round())
.expect("Error writing Pixel");
}

View File

@@ -1,19 +1,57 @@
use std::{io::{BufWriter, Write}, fs::File};
pub mod vec3;
pub mod color;
pub mod ray;
const IMAGE_WIDTH: usize = 512;
const IMAGE_HEIGHT: usize = 512;
use std::{io::{BufWriter, Write}, fs::File};
use crate::{
vec3::*,
color::*,
ray::*
};
fn ray_color(r: &Ray) -> Color {
let unit_direction: Vec3 = r.direction().unit_vector();
let t = 0.5 * (unit_direction.y() + 1.0);
//println!("{}", t);
((1.0 - t) * Color::new(1.0, 1.0, 1.0)) + (t * Color::new(0.5, 0.7, 1.0))
}
fn main() {
// Image
let aspect_ratio: f64 = 1.0 / 1.0;
let image_width: i32 = 400;
let image_height: i32 = (image_width as f64 / aspect_ratio as f64) as i32;
println!();
// Camera
let viewport_height: f64 = 2.0;
let viewport_width: f64 = aspect_ratio * viewport_height;
let focal_length: f64 = 1.0;
let origin = Point3::new(0.0,0.0,0.0);
let horizontal = Vec3::new(viewport_width, 0.0, 0.0);
let vertical = Vec3::new(0.0, viewport_height, 0.0);
let lower_left_corner = origin - horizontal/2.0 - vertical/2.0 - Vec3::new(0.0,0.0, focal_length);
// Render
let mut file = BufWriter::new(File::create("img.ppm").expect("File creation failed"));
writeln!(file, "P3\n{IMAGE_WIDTH} {IMAGE_HEIGHT}\n255").expect("Error while writing Magicbyte");
writeln!(file, "P3\n{image_width} {image_height}\n255").expect("Error while writing Magic Byte");
for _i in 0..IMAGE_WIDTH {
for _j in 0..IMAGE_HEIGHT {
writeln!(file, "234 100 255").expect("Error while writing Pixel X: {_i} Y: {_j}");
for j in (0..image_width).rev() {
//println!("{}", j);
//println!("Rows remaining: {j}");
write!(file, "\n").expect("grr");
for i in (0..image_height).rev() {
//println!("{}", i);
let u: f64 = i as f64 / image_width as f64;
let v: f64 = j as f64 / image_height as f64;
let r = Ray::new(origin, lower_left_corner + u * horizontal + v * vertical - origin);
let pixel_color = ray_color(&r);
write_color(&mut file, pixel_color);
}
}
}

25
src/ray.rs Normal file
View File

@@ -0,0 +1,25 @@
use crate::vec3::*;
#[derive(Debug)]
pub struct Ray {
pub origin: Point3,
pub direction: Vec3
}
impl Ray {
pub fn new(origin: Point3, direction: Vec3) -> Self {
Ray { origin, direction }
}
pub fn origin(&self) -> Point3 {
self.origin
}
pub fn direction(&self) -> Vec3 {
self.direction
}
pub fn at(&self, t: f64) -> Point3 {
self.origin + t * self.direction
}
}

168
src/vec3.rs Normal file
View File

@@ -0,0 +1,168 @@
use std::{ops::{Add, Sub, AddAssign, SubAssign, Mul, Div, MulAssign, DivAssign}};
#[derive(Debug, Clone, Copy)]
pub struct Vec3 {
pub elements: [f64; 3],
}
impl Vec3 {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Vec3 { elements: [x, y, z] }
}
pub fn x(&self) -> f64 {
self.elements[0]
}
pub fn y(&self) -> f64 {
self.elements[1]
}
pub fn z(&self) -> f64 {
self.elements[2]
}
pub fn length(&self) -> f64 {
self.length_squared().sqrt()
}
pub fn length_squared(&self) -> f64 {
self.dot(self)
}
pub fn dot(&self, rhs: &Self) -> f64 {
self.x() * rhs.x()
+ self.y() * rhs.y()
+ self.z() * rhs.z()
}
pub fn cross(&self, rhs: &Self) -> Self {
Self {
elements: [
self.y() * rhs.z() + self.z() * rhs.y(),
self.z() * rhs.x() + self.x() * rhs.z(),
self.x() * rhs.y() + self.y() * rhs.x()
]
}
}
pub fn unit_vector(self) -> Self {
self / self.length()
}
}
impl Add for Vec3 {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self {
elements: [
self.x() + rhs.x(),
self.y() + rhs.y(),
self.z() + rhs.z()
]
}
}
}
impl Sub for Vec3 {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self {
elements: [
self.x() - rhs.x(),
self.y() - rhs.y(),
self.z() - rhs.z()
]
}
}
}
impl Mul<f64> for Vec3 {
type Output = Self;
fn mul(self, rhs: f64) -> Self::Output {
Self {
elements: [
self.x() * rhs,
self.y() * rhs,
self.z() * rhs
]
}
}
}
impl Mul<Vec3> for f64 {
type Output = Vec3;
fn mul(self, rhs: Vec3) -> Self::Output {
rhs * self
}
}
impl Div<f64> for Vec3 {
type Output = Self;
fn div(self, rhs: f64) -> Self::Output {
Self {
elements: [
self.x() / rhs,
self.y() / rhs,
self.z() / rhs
]
}
}
}
impl AddAssign for Vec3 {
fn add_assign(&mut self, rhs: Self) {
*self = Self {
elements: [
self.x() + rhs.x(),
self.y() + rhs.y(),
self.z() + rhs.z()
]
}
}
}
impl SubAssign for Vec3 {
fn sub_assign(&mut self, rhs: Self) {
*self = Self {
elements: [
self.x() - rhs.x(),
self.y() - rhs.y(),
self.z() - rhs.z()
]
}
}
}
impl MulAssign<f64> for Vec3 {
fn mul_assign(&mut self, rhs: f64) {
*self = Self {
elements: [
self.x() * rhs,
self.y() * rhs,
self.z() * rhs
]
}
}
}
impl DivAssign<f64> for Vec3 {
fn div_assign(&mut self, rhs: f64) {
*self = Self {
elements: [
self.x() / rhs,
self.y() / rhs,
self.z() / rhs
]
}
}
}
pub type Color = Vec3;
pub type Point3 = Vec3;