|
|
|
@ -39,22 +39,7 @@ struct Vector3f { x: f32, y: f32, z: f32 }
|
|
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
|
|
|
|
struct Vector4f { x: f32, y: f32, z: f32, w: f32 }
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
|
|
|
|
struct Lighting
|
|
|
|
|
{
|
|
|
|
|
diffuse: Vector3f,
|
|
|
|
|
specular: Vector3f,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
|
|
|
|
struct PointLight
|
|
|
|
|
{
|
|
|
|
|
position : Vector3f,
|
|
|
|
|
diffuseColor : Vector3f,
|
|
|
|
|
diffusePower : f32,
|
|
|
|
|
specularColor : Vector3f,
|
|
|
|
|
specularPower : f32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn saturate(v: f32) -> f32 {
|
|
|
|
|
f32::min(f32::max(v, 0.0), 1.0)
|
|
|
|
@ -174,16 +159,34 @@ fn get_surface_data(phit: Vector3f, sphere_center: Vector3f) -> (Vector2f, Vecto
|
|
|
|
|
}, nhit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
|
|
|
|
struct Lighting
|
|
|
|
|
{
|
|
|
|
|
diffuse: Vector3f,
|
|
|
|
|
specular: Vector3f,
|
|
|
|
|
distance: f32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
|
|
|
|
struct PointLight
|
|
|
|
|
{
|
|
|
|
|
position : Vector3f,
|
|
|
|
|
diffuseColor : Vector3f,
|
|
|
|
|
diffusePower : f32,
|
|
|
|
|
specularColor : Vector3f,
|
|
|
|
|
specularPower : f32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// returns the diffuse and specular
|
|
|
|
|
fn get_point_light(light: PointLight, pos3D: Vector3f, viewDir: Vector3f, normal: Vector3f) -> Lighting
|
|
|
|
|
{
|
|
|
|
|
let mut out = Lighting::default();
|
|
|
|
|
if (light.diffusePower > 0.0)
|
|
|
|
|
{
|
|
|
|
|
let lightDir = sub(light.position, pos3D); //3D position in space of the surface
|
|
|
|
|
let distance = len(lightDir);
|
|
|
|
|
let lightDir = div(lightDir, distance); // = normalize(lightDir);
|
|
|
|
|
let distance = distance * distance; //This line may be optimised using Inverse square root
|
|
|
|
|
out.distance = len(lightDir);
|
|
|
|
|
let lightDir = div(lightDir, out.distance); // = normalize(lightDir);
|
|
|
|
|
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.
|
|
|
|
|
let NdotL = dot(normal, lightDir);
|
|
|
|
@ -251,7 +254,7 @@ fn main() {
|
|
|
|
|
// Create a new ImgBuf with width: imgx and height: imgy
|
|
|
|
|
let mut imgbuf = image::ImageBuffer::new(view_res.x as u32, view_res.y as u32);
|
|
|
|
|
|
|
|
|
|
let sphere_center = Vector3f { x: -70.0, y: 20.0, z: -10.0 };
|
|
|
|
|
let sphere_center = Vector3f { x: -10.0, y: 0.0, z: 0.0 };
|
|
|
|
|
let sphere_color = Vector3f {
|
|
|
|
|
x: 78.0,
|
|
|
|
|
y: 22.0,
|
|
|
|
@ -292,8 +295,24 @@ fn main() {
|
|
|
|
|
z: -dir.z,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let light = PointLight {
|
|
|
|
|
position : Vector3f{x:0.0,y:0.0,z:0.0},
|
|
|
|
|
diffuseColor : Vector3f{x:255.0,y:255.0,z:255.0},
|
|
|
|
|
diffusePower : 100.0,
|
|
|
|
|
specularColor : Vector3f{x:255.0,y:255.0,z:255.0},
|
|
|
|
|
specularPower : 70.0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let red = Vector3f {x:255.0, y:0.0, z:0.0};
|
|
|
|
|
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 = mult(mix(sphere_color, mult(sphere_color, 0.8), f32::max(0.0, dot(nhit, ndir))), pattern);
|
|
|
|
|
println!("{:?}", hit_color);
|
|
|
|
|
println!("{:?}", add(nhit, sphere_center));
|
|
|
|
|
// println!("{:?}", lighting);
|
|
|
|
|
*pixel = image::Rgb([hit_color.x as u8, hit_color.y as u8, hit_color.z as u8]);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|