better vector handling

master
mitchellhansen 4 years ago
parent 8281e26cb8
commit 9f9461690c

@ -1,3 +1,6 @@
#![feature(lang_items)]
#![feature(doc_alias)]
extern crate rand; extern crate rand;
use std::cmp::max; use std::cmp::max;
@ -11,6 +14,10 @@ use image::ImageFormat;
use image::io::Reader as ImageReader; use image::io::Reader as ImageReader;
use rand::prelude::*; use rand::prelude::*;
mod util;
use crate::util::*;
struct Circle { struct Circle {
x: i32, x: i32,
y: i32, y: i32,
@ -27,20 +34,6 @@ fn createCircle() -> Circle {
} }
} }
#[derive(Clone, Copy, Debug, Default)]
struct Vector2f { x: f32, y: f32 }
#[derive(Clone, Copy, Debug, Default)]
struct Vector2i { x: i32, y: i32 }
#[derive(Clone, Copy, Debug, Default)]
struct Vector3f { x: f32, y: f32, z: f32 }
#[derive(Clone, Copy, Debug, Default)]
struct Vector4f { x: f32, y: f32, z: f32, w: f32 }
fn saturate(v: f32) -> f32 { fn saturate(v: f32) -> f32 {
f32::min(f32::max(v, 0.0), 1.0) f32::min(f32::max(v, 0.0), 1.0)
} }
@ -50,6 +43,14 @@ fn dot(vec_a: Vector3f, vec_b: Vector3f) -> f32 {
vec_a.x * vec_b.x + vec_a.y * vec_b.y + vec_a.z * vec_b.z vec_a.x * vec_b.x + vec_a.y * vec_b.y + vec_a.z * vec_b.z
} }
fn clamp(vec: Vector3f, lower: f32, upper: f32) -> Vector3f {
Vector3f {
x: f32::min(f32::max(vec.x, lower), upper),
y: f32::min(f32::max(vec.y, lower), upper),
z: f32::min(f32::max(vec.z, lower), upper),
}
}
fn mult(vec: Vector3f, scalar: f32) -> Vector3f { fn mult(vec: Vector3f, scalar: f32) -> Vector3f {
Vector3f { Vector3f {
x: vec.x * scalar, x: vec.x * scalar,
@ -92,7 +93,10 @@ fn pow(vec: Vector3f, scalar: f32) -> Vector3f {
fn mix(a: Vector3f, b: Vector3f, mixValue: f32) -> Vector3f fn mix(a: Vector3f, b: Vector3f, mixValue: f32) -> Vector3f
{ {
add(mult(a, (1.0 - mixValue)), mult(b, mixValue)) add(
mult(a, (1.0 - mixValue)),
mult(b, mixValue)
)
} }
fn len(vec: Vector3f) -> f32 { fn len(vec: Vector3f) -> f32 {
@ -171,41 +175,41 @@ struct Lighting
struct PointLight struct PointLight
{ {
position : Vector3f, position : Vector3f,
diffuseColor : Vector3f, diffuse_color: Vector3f,
diffusePower : f32, diffuse_power: f32,
specularColor : Vector3f, specular_color: Vector3f,
specularPower : f32, specular_power: f32,
} }
// returns the diffuse and specular // returns the diffuse and specular
fn get_point_light(light: PointLight, pos3D: Vector3f, viewDir: Vector3f, normal: Vector3f) -> Lighting fn get_point_light(light: PointLight, pos3d: Vector3f, view_dir: Vector3f, normal: Vector3f) -> Lighting
{ {
let mut out = Lighting::default(); let mut out = Lighting::default();
if (light.diffusePower > 0.0) if (light.diffuse_power > 0.0)
{ {
let lightDir = sub(light.position, pos3D); //3D position in space of the surface let light_dir = sub(light.position, pos3d); //3D position in space of the surface
out.distance = len(lightDir); out.distance = len(light_dir);
let lightDir = div(lightDir, out.distance); // = normalize(lightDir); let light_dir = div(light_dir, out.distance); // = normalize(light_dir);
let distance = out.distance * out.distance; //This line may be optimised using Inverse square root let distance = out.distance * out.distance; //This line may be optimised using Inverse square root
//Intensity of the diffuse light. Saturate to keep within the 0-1 range. //Intensity of the diffuse light. Saturate to keep within the 0-1 range.
let NdotL = dot(normal, lightDir); let ndot_l = dot(normal, light_dir);
let intensity = saturate(NdotL); let intensity = saturate(ndot_l);
// Calculate the diffuse light factoring in light color, power and the attenuation // Calculate the diffuse light factoring in light color, power and the attenuation
out.diffuse = div(mult(mult(light.diffuseColor, intensity), light.diffusePower), distance); out.diffuse = div(mult(mult(light.diffuse_color, intensity), light.diffuse_power), distance);
//Calculate the half vector between the light vector and the view vector. //Calculate the half vector between the light vector and the view vector.
// This is typically slower than calculating the actual reflection vector // This is typically slower than calculating the actual reflection vector
// due to the normalize function's reciprocal square root // due to the normalize function's reciprocal square root
let H = normalize(add(lightDir, viewDir)); let H = normalize(add(light_dir, view_dir));
//Intensity of the specular light //Intensity of the specular light
let NdotH = dot(normal, H); let ndot_h = dot(normal, H);
let intensity = f32::powf(saturate(NdotH), 1.0); let intensity = f32::powf(saturate(ndot_h), 1.0);
//Sum up the specular light factoring //Sum up the specular light factoring
out.specular = div(mult(mult(light.specularColor, intensity), light.specularPower), distance); out.specular = div(mult(mult(light.specular_color, intensity), light.specular_power), distance);
} }
out out
} }
@ -295,24 +299,25 @@ fn main() {
z: -dir.z, z: -dir.z,
}; };
let x = ndir * 1.0;
let light = PointLight { let light = PointLight {
position : Vector3f{x:0.0,y:0.0,z:0.0}, position : Vector3f{x:-13.0,y:0.0,z:0.0},
diffuseColor : Vector3f{x:255.0,y:255.0,z:255.0}, diffuse_color: Vector3f{x:255.0,y:255.0,z:255.0},
diffusePower : 100.0, diffuse_power: 10.0,
specularColor : Vector3f{x:255.0,y:255.0,z:255.0}, specular_color: Vector3f{x:255.0,y:255.0,z:255.0},
specularPower : 70.0, specular_power: 100.0,
}; };
let red = Vector3f {x:255.0, y:0.0, z:0.0}; let lighting = get_point_light(light, phit + sphere_center, dir, nhit);
let color2 = Vector3f {x:200.0, y:90.0, z:120.0};
let lighting = get_point_light(light, add(phit, sphere_center), dir, nhit);
let mut hit_color = add(lighting.diffuse, lighting.specular); let hit_color = clamp(
sphere_color + (lighting.diffuse * light.diffuse_color + lighting.specular * light.specular_color),
0.0, 255.0);
println!("{:?}", hit_color); // println!("hit_color : {:?}", hit_color);
println!("{:?}", add(nhit, sphere_center)); //println!("{:?}", add(nhit, sphere_center));
// println!("{:?}", lighting); // println!("lighting : {:?}", lighting);
*pixel = image::Rgb([hit_color.x as u8, hit_color.y as u8, hit_color.z as u8]); *pixel = image::Rgb([hit_color.x as u8, hit_color.y as u8, hit_color.z as u8]);
} }
}; };

@ -0,0 +1,253 @@
use std::ops::{Add, Div, Mul, Neg, Sub};
pub trait Dot<Rhs = Self> {
/// The resulting type after applying the `*` operator.
type Output;
/// Performs the `*` operation.
#[must_use]
fn dot(self, rhs: Rhs) -> Self::Output;
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Vector2f { pub x: f32, pub y: f32 }
impl Add for Vector2f {
type Output = Self;
fn add(self, other: Self) -> Self {
Self {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
impl Mul for Vector2f {
type Output = Self;
fn mul(self, other: Self) -> Self {
Self {
x: self.x * other.x,
y: self.y * other.y,
}
}
}
impl Mul<f32> for Vector2f {
type Output = Self;
fn mul(self, rhs: f32) -> Self::Output {
Vector2f {
x: self.x * rhs,
y: self.y * rhs,
}
}
}
impl Dot for Vector2f {
type Output = f32;
fn dot(self, other: Self) -> f32 {
self.x * other.x + self.y * other.y
}
}
impl Sub for Vector2f {
type Output = Self;
fn sub(self, other: Self) -> Self {
Self {
x: self.x - other.x,
y: self.y - other.y,
}
}
}
impl Div for Vector2f {
type Output = Self;
fn div(self, other: Self) -> Self {
Self {
x: self.x / other.x,
y: self.y / other.y,
}
}
}
impl Neg for Vector2f {
type Output = Self;
fn neg(self) -> Self {
Self {
x: -self.x,
y: -self.y,
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Vector2i { pub x: i32, pub y: i32 }
impl Add for Vector2i {
type Output = Self;
fn add(self, other: Self) -> Self {
Self {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
impl Mul for Vector2i {
type Output = Self;
fn mul(self, other: Self) -> Self {
Self {
x: self.x * other.x,
y: self.y * other.y,
}
}
}
impl Mul<i32> for Vector2i {
type Output = Self;
fn mul(self, rhs: i32) -> Self::Output {
Vector2i {
x: self.x * rhs,
y: self.y * rhs,
}
}
}
impl Dot for Vector2i {
type Output = i32;
fn dot(self, other: Self) -> i32 {
self.x * other.x + self.y * other.y
}
}
impl Sub for Vector2i {
type Output = Self;
fn sub(self, other: Self) -> Self {
Self {
x: self.x - other.x,
y: self.y - other.y,
}
}
}
impl Div for Vector2i {
type Output = Self;
fn div(self, other: Self) -> Self {
Self {
x: self.x / other.x,
y: self.y / other.y,
}
}
}
impl Neg for Vector2i {
type Output = Self;
fn neg(self) -> Self {
Self {
x: -self.x,
y: -self.y,
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Vector3f { pub x: f32, pub y: f32, pub z: f32 }
impl Add for Vector3f {
type Output = Self;
fn add(self, other: Self) -> Self {
Self {
x: self.x + other.x,
y: self.y + other.y,
z: self.z + other.z,
}
}
}
impl Mul for Vector3f {
type Output = Self;
fn mul(self, other: Self) -> Self {
Self {
x: self.x * other.x,
y: self.y * other.y,
z: self.z * other.z,
}
}
}
impl Mul<f32> for Vector3f {
type Output = Self;
fn mul(self, other: f32) -> Self {
Self {
x: self.x * other,
y: self.y * other,
z: self.z * other,
}
}
}
impl Dot for Vector3f {
type Output = f32;
fn dot(self, other: Self) -> f32 {
self.x * other.x + self.y * other.y + self.z * other.z
}
}
impl Sub for Vector3f {
type Output = Self;
fn sub(self, other: Self) -> Self {
Self {
x: self.x - other.x,
y: self.y - other.y,
z: self.z - other.z,
}
}
}
impl Div for Vector3f {
type Output = Self;
fn div(self, other: Self) -> Self {
Self {
x: self.x / other.x,
y: self.y / other.y,
z: self.z / other.z,
}
}
}
impl Neg for Vector3f {
type Output = Self;
fn neg(self) -> Self {
Self {
x: -self.x,
y: -self.y,
z: -self.z,
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Vector4f { pub x: f32, pub y: f32, pub z: f32, pub w: f32 }

@ -1,71 +0,0 @@
bool CLCaster::create_viewport(int width, int height, float v_fov, float h_fov) {
sf::Vector2i view_res(width, height);
This creates a buffer to give the kernal a [x,y] coord set
if (!create_buffer("viewport_resolution", sizeof(int) * 2, &view_res))
return false;
// And an array of vectors describing the way the "lens" of our
// camera works
viewport_matrix = new sf::Vector4f[width * height * 4];
for (int y = -view_res.y / 2; y < view_res.y / 2; y++) {
for (int x = -view_res.x / 2; x < view_res.x / 2; x++) {
// The base ray direction to slew from
sf::Vector3f ray(-800, x, y);
// correct for the base ray pointing to (1, 0, 0) as (0, 0). Should equal (1.57, 0)
ray = sf::Vector3f(
static_cast<float>(ray.z * sin(1.57) + ray.x * cos(1.57)),
static_cast<float>(ray.y),
static_cast<float>(ray.z * cos(1.57) - ray.x * sin(1.57))
);
// ray.y += (rand() % 1000) / 100000.0;
// ray.x += (rand() % 1000) / 100000.0;
// ray.z += (rand() % 1000) / 100000.0;
ray = Normalize(ray);
int index = (x + view_res.x / 2) + view_res.x * (y + view_res.y / 2);
viewport_matrix[index] = sf::Vector4f(
ray.x,
ray.y,
ray.z,
0
);
}
}
if (!create_buffer("viewport_matrix", sizeof(float) * 4 * view_res.x * view_res.y, viewport_matrix))
return false;
// Create the image that opencl's rays write to
viewport_image = new sf::Uint8[width * height * 4];
for (int i = 0; i < width * height * 4; i += 4) {
viewport_image[i] = 255; // R
viewport_image[i + 1] = 255; // G
viewport_image[i + 2] = 255; // B
viewport_image[i + 3] = 100; // A
}
// Interop lets us keep a reference to it as a texture
viewport_texture.create(width, height);
viewport_texture.update(viewport_image);
viewport_sprite.setTexture(viewport_texture);
// Pass the buffer to opencl
if (!create_image_buffer("image", sizeof(sf::Uint8) * width * height * 4, &viewport_texture, CL_MEM_WRITE_ONLY))
return false;
return true;
}
Loading…
Cancel
Save