Skip to content

Commit

Permalink
TRY-27 set up for raytracing
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabus1184 committed Oct 26, 2023
1 parent bddd286 commit d7e821d
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 124 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,6 @@ fabric.properties
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
.idea/caches/build_file_checksums.ser

.vscode/*
173 changes: 50 additions & 123 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::borrow::Cow;

use glium::{
glutin::{
dpi::PhysicalSize,
Expand All @@ -6,21 +8,16 @@ use glium::{
window::WindowBuilder,
ContextBuilder,
},
implement_vertex, uniform, Surface,
texture::{ClientFormat, MipmapsOption, RawImage2d, UncompressedFloatFormat},
uniforms::MagnifySamplerFilter,
BlitTarget, Rect, Surface, Texture2d,
};

#[derive(Copy, Clone)]
struct Vertex {
position: [f32; 2],
}

implement_vertex!(Vertex, position);

pub fn main() {
let window_builder = WindowBuilder::new()
.with_title("TrayRacer!")
.with_resizable(true)
.with_min_inner_size(PhysicalSize::new(800, 600));
.with_inner_size(PhysicalSize::new(1200, 800));
let context_builder = ContextBuilder::new();
let event_loop = EventLoop::new();

Expand All @@ -33,123 +30,53 @@ pub fn main() {
} => {
*c = ControlFlow::Exit;
}
Event::WindowEvent { .. } => {}
Event::RedrawRequested(_) => {
Event::WindowEvent {
event: WindowEvent::Resized(PhysicalSize { width, height }),
..
} => {
let texture = Texture2d::with_format(
&display,
RawImage2d {
data: Cow::Owned(
(0..height)
.flat_map(|y| {
(0..width).flat_map(move |x| {
[x as f32 / width as f32, y as f32 / height as f32, 0.5, 1.0]
})
})
.collect::<Vec<f32>>(),
),
width,
height,
format: ClientFormat::F32F32F32F32,
},
UncompressedFloatFormat::F32F32F32F32,
MipmapsOption::NoMipmap,
)
.unwrap();

let mut frame = display.draw();
draw_gradient_background(&display, &mut frame);
texture.as_surface().blit_color(
&Rect {
left: 0,
bottom: 0,
width: texture.width(),
height: texture.height(),
},
&mut frame,
&BlitTarget {
left: 0,
bottom: 0,
width: width as i32,
height: height as i32,
},
MagnifySamplerFilter::Linear,
);

frame.finish().unwrap();
}
Event::WindowEvent { .. } => {}
Event::RedrawRequested(_) => {}
_ => {}
});
}

fn draw_gradient_background(display: &glium::Display, target: &mut glium::Frame) {
let vertex_buffer = glium::VertexBuffer::new(
display,
&[
Vertex {
position: [-1.0, -1.0],
},
Vertex {
position: [-1.0, 1.0],
},
Vertex {
position: [1.0, -1.0],
},
Vertex {
position: [1.0, 1.0],
},
],
)
.unwrap();

let indices = glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip);

let shader_program = create_shader(display);

target
.draw(
&vertex_buffer,
&indices,
&shader_program,
&uniform! {},
&Default::default(),
)
.unwrap();
}

fn create_shader(display: &glium::Display) -> glium::Program {
let vertex_shader_source = r#"
#version 330 core
in vec2 position;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
}
"#;

let _shader_vertical = r#"
#version 330 core
out vec4 color;
void main() {
float t = (gl_FragCoord.x / 600.0);
color = vec4(1.0, t, 1.0 - t, 1.0);
}
"#;

let _shader_horizontal = r#"
#version 330 core
out vec4 color;
void main() {
float t = (gl_FragCoord.y / 600.0);
color = vec4(1.0, t, 1.0 - t, 1.0);
}
"#;

let _shader_rainbow = r#"
#version 330 core
out vec4 color;
void main() {
float t = gl_FragCoord.x / 800.0; // Adjust the divisor for the gradient width
vec3 rainbowColor;
if (t < 0.14) {
rainbowColor = vec3(1.0, 0.0, 0.0); // Red
} else if (t < 0.28) {
rainbowColor = mix(vec3(1.0, 0.0, 0.0), vec3(1.0, 0.5, 0.0), smoothstep(0.14, 0.28, t));
} else if (t < 0.43) {
rainbowColor = mix(vec3(1.0, 0.5, 0.0), vec3(1.0, 1.0, 0.0), smoothstep(0.28, 0.43, t));
} else if (t < 0.57) {
rainbowColor = mix(vec3(1.0, 1.0, 0.0), vec3(0.0, 1.0, 0.0), smoothstep(0.43, 0.57, t));
} else if (t < 0.71) {
rainbowColor = mix(vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0), smoothstep(0.57, 0.71, t));
} else if (t < 0.85) {
rainbowColor = mix(vec3(0.0, 0.0, 1.0), vec3(0.29, 0.0, 0.51), smoothstep(0.71, 0.85, t));
} else {
rainbowColor = mix(vec3(0.29, 0.0, 0.51), vec3(0.5, 0.0, 0.5), smoothstep(0.85, 1.0, t));
}
color = vec4(rainbowColor, 1.0);
}
"#;

let shader_radial = r#"
#version 330 core
out vec4 color;
void main() {
// Calculate the distance from the center of the screen
vec2 center = vec2(400.0, 300.0); // Center of the screen (adjust as needed)
float distance = length(gl_FragCoord.xy - center) / 400.0; // Adjust divisor for gradient size
// The gradient will be from the center (0.0) to the edge (1.0)
color = vec4(0.0, distance, 1.0 - distance, 1.0);
}
"#;

glium::Program::from_source(display, vertex_shader_source, shader_radial, None).unwrap()
}
141 changes: 141 additions & 0 deletions src/scene/triangle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use bvh::aabb::AABB;
use nalgebra::{Matrix4, Point3, Vector3};

#[derive(Debug, Clone, Copy)]
pub struct Triangle {
pub a: Point3<f32>,
pub b: Point3<f32>,
pub c: Point3<f32>,
pub a_normal: Vector3<f32>,
pub b_normal: Vector3<f32>,
pub c_normal: Vector3<f32>,
pub material_index: usize,
bh_node_index: usize,
}

impl Triangle {
pub fn new(
a: Point3<f32>,
b: Point3<f32>,
c: Point3<f32>,
a_normal: Vector3<f32>,
b_normal: Vector3<f32>,
c_normal: Vector3<f32>,
material_index: usize,
) -> Self {
Self {
a,
b,
c,
a_normal,
b_normal,
c_normal,
material_index,
bh_node_index: 0,
}
}

pub fn transform(&mut self, matrix: &Matrix4<f32>) -> &mut Triangle {
self.a = matrix.transform_point(&self.a);
self.b = matrix.transform_point(&self.b);
self.c = matrix.transform_point(&self.c);

self.a_normal = matrix.transform_vector(&self.a_normal);
self.b_normal = matrix.transform_vector(&self.b_normal);
self.c_normal = matrix.transform_vector(&self.c_normal);

self
}

pub fn intersect(
&self,
ray_dir: &Vector3<f32>,
ray_origin: &Point3<f32>,
) -> Option<Point3<f32>> {
let edge1 = self.b - self.a;
let edge2 = self.c - self.a;

let h = ray_dir.cross(&edge2);
let a = edge1.dot(&h);

if a.abs() < f32::EPSILON {
return None;
}

let f = 1.0 / a;

let s = ray_origin - self.a;
let u = f * s.dot(&h);

if u < 0.0 || u > 1.0 {
return None;
}

let q = s.cross(&edge1);
let v = f * ray_dir.dot(&q);

if v < 0.0 || u + v > 1.0 {
return None;
}

let t = f * edge2.dot(&q);

if t > f32::EPSILON {
Some(ray_origin + ray_dir * t)
} else {
None
}
}

pub fn barycentric(&self, point: Point3<f32>) -> (f32, f32, f32) {
let v0 = self.b - self.a;
let v1 = self.c - self.a;
let v2 = point - self.a;

let d00 = v0.dot(&v0);
let d01 = v0.dot(&v1);
let d11 = v1.dot(&v1);
let d20 = v2.dot(&v0);
let d21 = v2.dot(&v1);

let denom = d00 * d11 - d01 * d01;

let v = (d11 * d20 - d01 * d21) / denom;
let w = (d00 * d21 - d01 * d20) / denom;
let u = 1.0 - v - w;

(u, v, w)
}
}

impl bvh::aabb::Bounded for Triangle {
fn aabb(&self) -> bvh::aabb::AABB {
AABB::default()
.grow(&bvh::Point3::new(self.a.x, self.a.y, self.a.z))
.grow(&bvh::Point3::new(self.b.x, self.b.y, self.b.z))
.grow(&bvh::Point3::new(self.c.x, self.c.y, self.c.z))
}
}

impl bvh::bounding_hierarchy::BHShape for Triangle {
fn set_bh_node_index(&mut self, index: usize) {
self.bh_node_index = index;
}

fn bh_node_index(&self) -> usize {
self.bh_node_index
}
}

impl PartialEq for Triangle {
fn eq(&self, other: &Self) -> bool {
self.a == other.a
&& self.b == other.b
&& self.c == other.c
&& self.a_normal == other.a_normal
&& self.b_normal == other.b_normal
&& self.c_normal == other.c_normal
&& self.material_index == other.material_index
&& self.bh_node_index == other.bh_node_index
}
}

0 comments on commit d7e821d

Please sign in to comment.