Working realtime tracing

This commit is contained in:
STP
2023-11-16 17:14:24 -05:00
parent a80da71455
commit 9383ef5bbf
7 changed files with 182 additions and 248 deletions

View File

@@ -5,16 +5,13 @@
//Cameras
use crate::camera::Camera;
use crate::gui::Gui;
use crate::light::Light;
use crate::primitive::*;
use crate::scene::Scene;
use crate::{camera::Camera, gui::Gui, light::Light, primitive::*, ray::Ray, scene::Scene};
use log::error;
use error_iter::ErrorIter as _;
use log::error;
use nalgebra::{Point3, Vector3};
use pixels::{Error, Pixels, SurfaceTexture};
use std::env;
use std::sync::Arc;
use winit::dpi::LogicalSize;
use winit::event::{Event, VirtualKeyCode};
@@ -30,8 +27,8 @@ mod ray;
mod raytracer;
mod scene;
const START_WIDTH: u32 = 640;
const START_HEIGHT: u32 = 480;
const START_WIDTH: i32 = 600;
const START_HEIGHT: i32 = 555;
const BOX_SIZE: i16 = 64;
const EPSILON: f32 = 1e-7;
@@ -39,12 +36,16 @@ const INFINITY: f32 = 1e7;
struct State {
scene: Scene,
width: u32,
height: u32,
camera: Camera,
rays: Vec<Ray>,
index: usize,
width: i32,
height: i32,
}
fn main() -> Result<(), Error> {
env_logger::init();
//Window
let event_loop = EventLoop::new();
let mut input = WinitInputHelper::new();
let window = {
@@ -56,22 +57,56 @@ fn main() -> Result<(), Error> {
.build(&event_loop)
.unwrap()
};
//Pixel surface
let mut pixels = {
let window_size = window.inner_size();
let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window);
Pixels::new(START_WIDTH, START_HEIGHT, surface_texture)?
Pixels::new(START_WIDTH as u32, START_HEIGHT as u32, surface_texture)?
};
let mut state = State::new(START_WIDTH, START_HEIGHT);
//Camera
let eye = Point3::new(0.0, 0.0, 3.0);
let target = Point3::new(0.0, 0.0, 0.0);
let up = Vector3::new(0.0, 1.0, 0.0);
let arc_camera = Arc::new(Camera::new(
eye,
target,
up,
180.0,
(START_WIDTH as f32 / START_HEIGHT as f32) as f32,
));
let camera = Camera::new(
eye,
target,
up,
180.0,
(START_WIDTH as f32 / START_HEIGHT as f32) as f32,
);
let cameras: Vec<Arc<Camera>> = vec![arc_camera.clone()];
//Primitive
let arc_material = Arc::new(Material::magenta());
let mut primitives: Vec<Arc<dyn Primitive>> = Vec::new();
let arc_sphere = Arc::new(Sphere::unit(arc_material.clone()));
let arc_cone = Arc::new(Cone::unit(arc_material.clone()));
primitives.push(arc_sphere.clone());
primitives.push(arc_cone.clone());
//Lights
let light: Arc<Light>;
let light = Arc::new(Light::white());
let lights = vec![light];
let ambient_light = Arc::new(Vector3::new(1.0, 1.0, 0.0));
//State
let scene = Scene::new(primitives, lights, cameras, ambient_light);
let mut state = State::new(START_WIDTH, START_HEIGHT, scene, camera);
// Set up Dear ImGui
let mut gui = Gui::new(&window, &pixels);
event_loop.run(move |event, _, control_flow| {
// Draw the current frame
if let Event::RedrawRequested(_) = event {
for i in 0..gui.num_rays {
state.draw(pixels.frame_mut());
}
// Draw the world
state.draw(pixels.frame_mut());
// Prepare Dear ImGui
gui.prepare(&window).expect("gui.prepare() failed");
// Render everything together
@@ -80,6 +115,7 @@ fn main() -> Result<(), Error> {
context.scaling_renderer.render(encoder, render_target);
// Render Dear ImGui
gui.render(&window, encoder, render_target, context)?;
// *control_flow = ControlFlow::Exit;
Ok(())
});
// Basic error handling
@@ -98,6 +134,7 @@ fn main() -> Result<(), Error> {
*control_flow = ControlFlow::Exit;
return;
}
if input.key_pressed(VirtualKeyCode::A) {}
// Resize the window
if let Some(size) = input.window_resized() {
if size.width > 0 && size.height > 0 {
@@ -108,13 +145,7 @@ fn main() -> Result<(), Error> {
return;
}
// Resize the world
state.resize(size.width, size.height);
if let Err(err) = pixels.resize_buffer(size.width, size.height) {
log_error("pixels.resize_buffer", err);
*control_flow = ControlFlow::Exit;
return;
}
state.resize(size.width as i32, size.height as i32);
}
}
@@ -134,12 +165,16 @@ fn log_error<E: std::error::Error + 'static>(method_name: &str, err: E) {
impl State {
/// Create a new `World` instance that can draw a moving box.
fn new(width: u32, height: u32) -> Self {
let scene = Scene::empty();
fn new(width: i32, height: i32, scene: Scene, camera: Camera) -> Self {
let index = 0;
let rays = camera.cast_rays(width, height);
Self {
width,
height,
index,
rays,
scene,
camera,
}
}
@@ -147,7 +182,7 @@ impl State {
fn update(&mut self) {}
/// Resize the world
fn resize(&mut self, width: u32, height: u32) {
fn resize(&mut self, width: i32, height: i32) {
self.width = width;
self.height = height;
}
@@ -155,61 +190,23 @@ impl State {
/// Draw the `World` state to the frame buffer.
///
/// Assumes the default texture format: `wgpu::TextureFormat::Rgba8UnormSrgb`
fn draw(&self, frame: &mut [u8]) {
for (i, pixel) in frame.chunks_exact_mut(4).enumerate() {
let x = (i % self.width as usize) as i16;
let y = (i / self.width as usize) as i16;
fn draw(&mut self, frame: &mut [u8]) {
let ray = &self.rays[self.index];
let colour = raytracer::shade_ray(&self.scene, &ray);
let pixel = &mut frame[self.index * 4..(self.index + 1) * 4]
.copy_from_slice(&[colour.x, colour.y, colour.z, 255]);
self.index += 1;
}
//Create our scene
let eye = Point3::new(0.0, 0.0, -1.0);
let target = Point3::new(0.0, 0.0, 0.0);
let up = Vector3::new(0.0, 1.0, 0.0);
let arc_camera = Arc::new(Camera::new(
eye,
target,
up,
90.0,
(self.width / self.height) as f32,
));
let cameras: Vec<Arc<Camera>> = vec![arc_camera.clone()];
let arc_material = Arc::new(Material::magenta());
let arc_cone = Arc::new(Cone::unit(arc_material));
let primitives: Vec<Arc<dyn Primitive>> = vec![arc_cone]
.into_iter()
.map(|arc| arc as Arc<dyn Primitive>)
.collect();
let light: Arc<Light>;
let light = Arc::new(Light::white());
let lights = vec![light];
let ambient_light = Arc::new(Vector3::new(1.0, 1.0, 1.0));
let scene = Scene::new(primitives, lights, cameras, ambient_light);
let rays = arc_camera.as_ref().cast_rays(self.width, self.height);
let colours = raytracer::shade_rays(&scene, &rays, self.width, self.height);
println!("{}", colours.len());
//
// let pixels = pixels.frame().chunks_exact_mut(4);
// for (i, colour) in colours.iter().enumerate() {
// let colour = colours[i];
// let pixel = &mut pixels[i];
// pixel[0] = colour.x;
// pixel[1] = colour.y;
// pixel[2] = colour.z;
// }
//
// // Render the frame
// if pixels.render().is_err() {
// eprintln!("Failed to render frame");
// }
let rgba = [0x48, 0xb2, 0xe8, 0xff];
pixel.copy_from_slice(&rgba);
fn draw_all(&mut self, frame: &mut [u8]) {
let rays = self.camera.cast_rays(self.width, self.height);
let colours = raytracer::shade_rays(&self.scene, &rays, self.width, self.height);
for (i, colour) in colours.iter().enumerate() {
let colour = colours[i];
// pixel[0] = colour.x;
// pixel[1] = colour.y;
// pixel[2] = colour.z;
// pixel[3] = 255;
}
}
}