Working realtime tracing
This commit is contained in:
155
src/main.rs
155
src/main.rs
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user