Skip to content

Commit

Permalink
feat: add image texture to Lambertian material
Browse files Browse the repository at this point in the history
  • Loading branch information
alanjian85 committed Jul 23, 2024
1 parent 79fc2ce commit 9aa2f62
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 29 deletions.
Binary file added assets/earthmap.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions scripts/earth.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
camera.pos = {0.0, 0.0, 6.0}
camera.center = {0.0, 0.0, 0.0}
camera.fov = math.rad(20.0)

scene:set_env(Color3.new{1.0, 1.0, 1.0})

material_ball = Lambertian.new(Image.new("assets/earthmap.jpg"))
scene:add(Sphere.new({0.0, 0.0, 0.0}, 1.0, material_ball))
5 changes: 1 addition & 4 deletions scripts/scene.lua → scripts/glass_ball.lua
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
camera.pos = {0.0, 7.0, 7.0}
camera.center = {0.0, 1.0, 0.0}
camera.up = {0.0, 1.0, 0.0}
camera.fov = math.rad(15.0)
camera.focus_dist = 1.0
camera.lens_angle = math.rad(0.0)

panorama = Panorama.new("assets/panorama.hdr")
scene:set_env(panorama)

material_ground = Lambertian.new({0.4, 0.4, 0.4})
material_ground = Lambertian.new(Color2.new{0.4, 0.4, 0.4})
scene:add(Quad.new({-5.0, 0.0, -5.0}, {10.0, 0.0, 0.0}, {0.0, 0.0, 10.0}, material_ground))

material_ball = Dielectric.new(1.5)
Expand Down
7 changes: 3 additions & 4 deletions src/core/primitive.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::core::{Material, Ray};
use nalgebra::{Point3, Vector3};
use nalgebra::{Point3, Vector2, Vector3};
use std::ops::Range;
use std::sync::Arc;

pub struct RayIntersection {
pub pos: Point3<f64>,
pub front: bool,
pub normal: Vector3<f64>,
pub uv: Vector2<f64>,
pub material: Arc<dyn Material>,
}

Expand All @@ -21,7 +22,5 @@ impl RayIntersection {
}

pub trait Primitive: Send + Sync {
fn intersect(&self, _ray: &Ray, _range: &Range<f64>) -> Option<(f64, RayIntersection)> {
None
}
fn intersect(&self, _ray: &Ray, _range: &Range<f64>) -> Option<(f64, RayIntersection)>;
}
2 changes: 1 addition & 1 deletion src/core/texture.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use nalgebra::{Vector2, Vector3};
use palette::LinSrgb;

pub trait Texture2 {
pub trait Texture2: Send + Sync {
fn sample(&self, uv: Vector2<f64>) -> LinSrgb<f64>;
}

Expand Down
11 changes: 6 additions & 5 deletions src/materials/lambertian.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use crate::core::{Material, Ray, RayIntersection};
use crate::core::{Material, Ray, RayIntersection, Texture2};
use crate::utils;
use palette::LinSrgb;
use rand::prelude::*;
use std::sync::Arc;

pub struct Lambertian {
albedo: LinSrgb<f64>,
texture: Arc<dyn Texture2>,
}

impl Lambertian {
pub fn new(albedo: LinSrgb<f64>) -> Self {
Self { albedo }
pub fn new(texture: Arc<dyn Texture2>) -> Self {
Self { texture }
}
}

Expand All @@ -25,6 +26,6 @@ impl Material for Lambertian {
dir = intersection.normal;
}
let ray = Ray::new(intersection.pos, dir);
Some((ray, self.albedo))
Some((ray, self.texture.sample(intersection.uv)))
}
}
4 changes: 3 additions & 1 deletion src/primitives/quad.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::core::{Material, Primitive, Ray, RayIntersection};
use crate::utils;
use nalgebra::{Point3, Vector3};
use nalgebra::{Point3, Vector2, Vector3};
use std::ops::Range;
use std::sync::Arc;

Expand Down Expand Up @@ -62,12 +62,14 @@ impl Primitive for Quad {

let normal = self.normal;
let (front, normal) = RayIntersection::flip_normal(ray.dir, normal);
let uv = Vector2::new(u, v);
Some((
t,
RayIntersection {
pos,
front,
normal,
uv,
material: self.material.clone(),
},
))
Expand Down
12 changes: 11 additions & 1 deletion src/primitives/sphere.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::core::{Material, Primitive, Ray, RayIntersection};
use nalgebra::Point3;
use nalgebra::{Point3, Vector2};
use std::f64;
use std::ops::Range;
use std::sync::Arc;

Expand Down Expand Up @@ -40,13 +41,22 @@ impl Primitive for Sphere {

let pos = ray.at(t);
let normal = (pos - self.center) / self.radius;

let theta = (-normal.y).acos();
let phi = (-normal.z).atan2(normal.x) + f64::consts::PI;

let u = phi / (2.0 * f64::consts::PI);
let v = theta / f64::consts::PI;
let uv = Vector2::new(u, v);

let (front, normal) = RayIntersection::flip_normal(ray.dir, normal);
Some((
t,
RayIntersection {
pos,
front,
normal,
uv,
material: self.material.clone(),
},
))
Expand Down
5 changes: 3 additions & 2 deletions src/scripting/materials.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::core::Material;
use crate::materials::{Dielectric, Lambertian, Metal};
use crate::scripting::textures::Texture2Ptr;
use crate::scripting::utils;
use mlua::{prelude::*, Table, UserData};
use std::sync::Arc;
Expand Down Expand Up @@ -27,8 +28,8 @@ pub fn init(lua: &Lua) -> LuaResult<()> {
let lambertian = lua.create_table()?;
lambertian.set(
"new",
lua.create_function(|_lua, albedo: Table| {
let lambertian = Lambertian::new(utils::table_to_color(&albedo)?);
lua.create_function(|_lua, texture: Texture2Ptr| {
let lambertian = Lambertian::new(texture.ptr);
Ok(MaterialPtr {
ptr: Arc::new(lambertian),
})
Expand Down
47 changes: 36 additions & 11 deletions src/scripting/textures.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::core::{Texture2, Texture3};
use crate::textures::{Image, ImageHdr, Panorama};
use mlua::{prelude::*, UserData};
use crate::scripting::utils;
use crate::textures::{Color, Image, ImageHdr, Panorama};
use mlua::{prelude::*, Table, UserData};
use std::sync::Arc;

#[derive(FromLua, Clone)]
Expand All @@ -18,8 +19,32 @@ pub struct Texture3Ptr {
impl UserData for Texture3Ptr {}

pub fn init(lua: &Lua) -> LuaResult<()> {
let texture_image = lua.create_table()?;
texture_image.set(
let color2 = lua.create_table()?;
color2.set(
"new",
lua.create_function(|_lua, color: Table| {
let color = Color::new(utils::table_to_color(&color)?);
Ok(Texture2Ptr {
ptr: Arc::new(color),
})
})?,
)?;
lua.globals().set("Color2", color2)?;

let color3 = lua.create_table()?;
color3.set(
"new",
lua.create_function(|_lua, color: Table| {
let color = Color::new(utils::table_to_color(&color)?);
Ok(Texture3Ptr {
ptr: Arc::new(color),
})
})?,
)?;
lua.globals().set("Color3", color3)?;

let image = lua.create_table()?;
image.set(
"new",
lua.create_function(|_lua, path: String| {
let image = Image::new(&path).map_err(|err| err.into_lua_err())?;
Expand All @@ -28,10 +53,10 @@ pub fn init(lua: &Lua) -> LuaResult<()> {
})
})?,
)?;
lua.globals().set("Image", texture_image)?;
lua.globals().set("Image", image)?;

let texture_image_hdr = lua.create_table()?;
texture_image_hdr.set(
let image_hdr = lua.create_table()?;
image_hdr.set(
"new",
lua.create_function(|_lua, path: String| {
let image_hdr = ImageHdr::new(&path).map_err(|err| err.into_lua_err())?;
Expand All @@ -40,10 +65,10 @@ pub fn init(lua: &Lua) -> LuaResult<()> {
})
})?,
)?;
lua.globals().set("ImageHdr", texture_image_hdr)?;
lua.globals().set("ImageHdr", image_hdr)?;

let texture_panorama = lua.create_table()?;
texture_panorama.set(
let panorama = lua.create_table()?;
panorama.set(
"new",
lua.create_function(|_lua, path: String| {
let panorama = Panorama::new(&path).map_err(|err| err.into_lua_err())?;
Expand All @@ -52,7 +77,7 @@ pub fn init(lua: &Lua) -> LuaResult<()> {
})
})?,
)?;
lua.globals().set("Panorama", texture_panorama)?;
lua.globals().set("Panorama", panorama)?;

Ok(())
}
2 changes: 2 additions & 0 deletions src/textures.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod color;
mod image;
mod image_hdr;
mod panorama;

pub use color::Color;
pub use image::Image;
pub use image_hdr::ImageHdr;
pub use panorama::Panorama;
25 changes: 25 additions & 0 deletions src/textures/color.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::core::{Texture2, Texture3};
use nalgebra::{Vector2, Vector3};
use palette::LinSrgb;

pub struct Color {
color: LinSrgb<f64>,
}

impl Color {
pub fn new(color: LinSrgb<f64>) -> Self {
Self { color }
}
}

impl Texture2 for Color {
fn sample(&self, _uv: Vector2<f64>) -> LinSrgb<f64> {
self.color
}
}

impl Texture3 for Color {
fn sample(&self, _uvw: Vector3<f64>) -> LinSrgb<f64> {
self.color
}
}

0 comments on commit 9aa2f62

Please sign in to comment.