Implement image based textures.
This commit is contained in:
parent
415cb7be9a
commit
34ce373269
BIN
rtiow/images/world.jpg
Normal file
BIN
rtiow/images/world.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 295 KiB |
@ -1,67 +0,0 @@
|
|||||||
use aabb::AABB;
|
|
||||||
use hitable::Hit;
|
|
||||||
use hitable::HitRecord;
|
|
||||||
use material::Material;
|
|
||||||
use ray::Ray;
|
|
||||||
use vec3::dot;
|
|
||||||
use vec3::Vec3;
|
|
||||||
|
|
||||||
// Cube is an axis-aligned cube with dimensions length x length x length with center in the middle.
|
|
||||||
pub struct Cube {
|
|
||||||
center: Vec3,
|
|
||||||
length: f32,
|
|
||||||
material: Box<Material>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Cube {
|
|
||||||
pub fn new(center: Vec3, length: f32, material: Box<Material>) -> Cube {
|
|
||||||
Cube {
|
|
||||||
center,
|
|
||||||
length,
|
|
||||||
material,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hit for Cube {
|
|
||||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
|
||||||
info!("Cube info");
|
|
||||||
eprintln!("Cube eprintln");
|
|
||||||
// See if it hit the positive X wall first.
|
|
||||||
let oc = r.origin - self.center;
|
|
||||||
let a = dot(r.direction, r.direction);
|
|
||||||
let b = dot(oc, r.direction);
|
|
||||||
let c = dot(oc, oc) - self.length * self.length;
|
|
||||||
let discriminant = b * b - a * c;
|
|
||||||
if discriminant > 0. {
|
|
||||||
let temp = (-b - (b * b - a * c).sqrt()) / a;
|
|
||||||
if temp < t_max && temp > t_min {
|
|
||||||
let point = r.point_at_parameter(temp);
|
|
||||||
return Some(HitRecord {
|
|
||||||
t: temp,
|
|
||||||
p: point,
|
|
||||||
normal: (point - self.center) / self.length,
|
|
||||||
material: &*self.material,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let temp = (-b + (b * b - a * c).sqrt()) / a;
|
|
||||||
if temp < t_max && temp > t_min {
|
|
||||||
let point = r.point_at_parameter(temp);
|
|
||||||
return Some(HitRecord {
|
|
||||||
t: temp,
|
|
||||||
p: point,
|
|
||||||
normal: (point - self.center) / self.length,
|
|
||||||
material: &*self.material,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bounding_box(&self, _t_min: f32, _t_max: f32) -> Option<AABB> {
|
|
||||||
Some(AABB::new(
|
|
||||||
self.center - Vec3::new(self.length / 2., self.length / 2., self.length / 2.),
|
|
||||||
self.center + Vec3::new(self.length / 2., self.length / 2., self.length / 2.),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -5,6 +5,7 @@ use vec3::Vec3;
|
|||||||
|
|
||||||
pub struct HitRecord<'m> {
|
pub struct HitRecord<'m> {
|
||||||
pub t: f32,
|
pub t: f32,
|
||||||
|
pub uv: (f32, f32),
|
||||||
pub p: Vec3,
|
pub p: Vec3,
|
||||||
pub normal: Vec3,
|
pub normal: Vec3,
|
||||||
pub material: &'m Material,
|
pub material: &'m Material,
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
pub mod aabb;
|
pub mod aabb;
|
||||||
pub mod bvh;
|
pub mod bvh;
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
pub mod cube;
|
|
||||||
pub mod hitable;
|
pub mod hitable;
|
||||||
pub mod hitable_list;
|
pub mod hitable_list;
|
||||||
pub mod kdtree;
|
pub mod kdtree;
|
||||||
|
|||||||
@ -47,8 +47,9 @@ impl Lambertian {
|
|||||||
impl Material for Lambertian {
|
impl Material for Lambertian {
|
||||||
fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse {
|
fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse {
|
||||||
let target = rec.p + rec.normal + random_in_unit_sphere();
|
let target = rec.p + rec.normal + random_in_unit_sphere();
|
||||||
|
let (u, v) = rec.uv;
|
||||||
ScatterResponse {
|
ScatterResponse {
|
||||||
attenutation: self.albedo.value(0., 0., rec.p),
|
attenutation: self.albedo.value(u, v, rec.p),
|
||||||
scattered: Ray::new(rec.p, target - rec.p, r_in.time),
|
scattered: Ray::new(rec.p, target - rec.p, r_in.time),
|
||||||
reflected: true,
|
reflected: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use hitable::Hit;
|
|||||||
use hitable::HitRecord;
|
use hitable::HitRecord;
|
||||||
use material::Material;
|
use material::Material;
|
||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
|
use sphere::get_sphere_uv;
|
||||||
use vec3::dot;
|
use vec3::dot;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
@ -51,8 +52,10 @@ impl Hit for MovingSphere {
|
|||||||
let temp = (-b - (b * b - a * c).sqrt()) / a;
|
let temp = (-b - (b * b - a * c).sqrt()) / a;
|
||||||
if temp < t1 && temp > t0 {
|
if temp < t1 && temp > t0 {
|
||||||
let point = r.point_at_parameter(temp);
|
let point = r.point_at_parameter(temp);
|
||||||
|
let uv = get_sphere_uv((point - self.center(r.time)) / self.radius);
|
||||||
return Some(HitRecord {
|
return Some(HitRecord {
|
||||||
t: temp,
|
t: temp,
|
||||||
|
uv,
|
||||||
p: point,
|
p: point,
|
||||||
normal: (point - self.center(r.time)) / self.radius,
|
normal: (point - self.center(r.time)) / self.radius,
|
||||||
material: &*self.material,
|
material: &*self.material,
|
||||||
@ -61,8 +64,10 @@ impl Hit for MovingSphere {
|
|||||||
let temp = (-b + (b * b - a * c).sqrt()) / a;
|
let temp = (-b + (b * b - a * c).sqrt()) / a;
|
||||||
if temp < t1 && temp > t0 {
|
if temp < t1 && temp > t0 {
|
||||||
let point = r.point_at_parameter(temp);
|
let point = r.point_at_parameter(temp);
|
||||||
|
let uv = get_sphere_uv((point - self.center(r.time)) / self.radius);
|
||||||
return Some(HitRecord {
|
return Some(HitRecord {
|
||||||
t: temp,
|
t: temp,
|
||||||
|
uv,
|
||||||
p: point,
|
p: point,
|
||||||
normal: (point - self.center(r.time)) / self.radius,
|
normal: (point - self.center(r.time)) / self.radius,
|
||||||
material: &*self.material,
|
material: &*self.material,
|
||||||
|
|||||||
@ -74,6 +74,18 @@ fn perlin_interp(c: [[[Vec3; 2]; 2]; 2], u: f32, v: f32, w: f32) -> f32 {
|
|||||||
accum
|
accum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn turb(p: Vec3, depth: usize) -> f32 {
|
||||||
|
let mut accum = 0.;
|
||||||
|
let mut temp_p = p;
|
||||||
|
let mut weight = 1.;
|
||||||
|
for _ in 0..depth {
|
||||||
|
accum += weight * GENERATOR.noise(temp_p);
|
||||||
|
weight *= 0.5;
|
||||||
|
temp_p = temp_p * 0.2;
|
||||||
|
}
|
||||||
|
accum.abs()
|
||||||
|
}
|
||||||
|
|
||||||
impl Perlin {
|
impl Perlin {
|
||||||
fn new() -> Perlin {
|
fn new() -> Perlin {
|
||||||
Perlin {
|
Perlin {
|
||||||
|
|||||||
@ -24,7 +24,6 @@ pub enum Model {
|
|||||||
Bench,
|
Bench,
|
||||||
Book,
|
Book,
|
||||||
Tutorial,
|
Tutorial,
|
||||||
Cube,
|
|
||||||
BVH,
|
BVH,
|
||||||
Test,
|
Test,
|
||||||
}
|
}
|
||||||
@ -34,7 +33,6 @@ impl Model {
|
|||||||
match self {
|
match self {
|
||||||
Model::Book => scenes::book::new(&opt),
|
Model::Book => scenes::book::new(&opt),
|
||||||
Model::Bench => scenes::bench::new(&opt),
|
Model::Bench => scenes::bench::new(&opt),
|
||||||
Model::Cube => scenes::cube::new(&opt),
|
|
||||||
Model::Tutorial => scenes::tutorial::new(&opt),
|
Model::Tutorial => scenes::tutorial::new(&opt),
|
||||||
Model::BVH => scenes::bvh::new(&opt),
|
Model::BVH => scenes::bvh::new(&opt),
|
||||||
Model::Test => scenes::test::new(&opt),
|
Model::Test => scenes::test::new(&opt),
|
||||||
@ -58,7 +56,6 @@ impl str::FromStr for Model {
|
|||||||
"bench" => Ok(Model::Bench),
|
"bench" => Ok(Model::Bench),
|
||||||
"book" => Ok(Model::Book),
|
"book" => Ok(Model::Book),
|
||||||
"tutorial" => Ok(Model::Tutorial),
|
"tutorial" => Ok(Model::Tutorial),
|
||||||
"cube" => Ok(Model::Cube),
|
|
||||||
"bvh" => Ok(Model::BVH),
|
"bvh" => Ok(Model::BVH),
|
||||||
"test" => Ok(Model::Test),
|
"test" => Ok(Model::Test),
|
||||||
_ => Err(ModelParseError(s.to_owned())),
|
_ => Err(ModelParseError(s.to_owned())),
|
||||||
@ -78,7 +75,7 @@ pub struct Opt {
|
|||||||
/// Sub-samples per pixel
|
/// Sub-samples per pixel
|
||||||
#[structopt(short = "s", long = "subsample", default_value = "8")]
|
#[structopt(short = "s", long = "subsample", default_value = "8")]
|
||||||
pub subsamples: usize,
|
pub subsamples: usize,
|
||||||
/// Select scene to render, one of: "bench", "book", "tutorial" "cube", "bvh", "test"
|
/// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test"
|
||||||
#[structopt(long = "model", default_value = "test")]
|
#[structopt(long = "model", default_value = "test")]
|
||||||
pub model: Model,
|
pub model: Model,
|
||||||
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
|
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
|
||||||
|
|||||||
@ -1,60 +0,0 @@
|
|||||||
use camera::Camera;
|
|
||||||
use cube::Cube;
|
|
||||||
use hitable::Hit;
|
|
||||||
use hitable_list::HitableList;
|
|
||||||
use material::Lambertian;
|
|
||||||
use renderer::Opt;
|
|
||||||
use renderer::Scene;
|
|
||||||
use sphere::Sphere;
|
|
||||||
use texture::ConstantTexture;
|
|
||||||
use vec3::Vec3;
|
|
||||||
|
|
||||||
pub fn new(opt: &Opt) -> Scene {
|
|
||||||
let lookfrom = Vec3::new(3., 3., 2.);
|
|
||||||
let lookat = Vec3::new(0., 0., 0.);
|
|
||||||
let dist_to_focus = (lookfrom - lookat).length();
|
|
||||||
let aperture = 0.1;
|
|
||||||
let time_min = 0.;
|
|
||||||
let time_max = 1.;
|
|
||||||
let camera = Camera::new(
|
|
||||||
lookfrom,
|
|
||||||
lookat,
|
|
||||||
Vec3::new(0., 1., 0.),
|
|
||||||
45.,
|
|
||||||
opt.width as f32 / opt.height as f32,
|
|
||||||
aperture,
|
|
||||||
dist_to_focus,
|
|
||||||
time_min,
|
|
||||||
time_max,
|
|
||||||
);
|
|
||||||
let world: Box<Hit> = Box::new(HitableList::new(vec![
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(0., 0., -1.),
|
|
||||||
0.5,
|
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
|
||||||
0.1, 0.2, 0.5,
|
|
||||||
))))),
|
|
||||||
)),
|
|
||||||
Box::new(Cube::new(
|
|
||||||
Vec3::new(0., 0., 0.),
|
|
||||||
0.5,
|
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
|
||||||
0.5, 0.2, 0.1,
|
|
||||||
))))),
|
|
||||||
)),
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(0., -100.5, -1.),
|
|
||||||
100.,
|
|
||||||
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
|
||||||
0.8, 0.8, 0.8,
|
|
||||||
))))),
|
|
||||||
)),
|
|
||||||
]));
|
|
||||||
Scene {
|
|
||||||
camera,
|
|
||||||
world,
|
|
||||||
subsamples: opt.subsamples,
|
|
||||||
width: opt.width,
|
|
||||||
height: opt.height,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
pub mod bench;
|
pub mod bench;
|
||||||
pub mod book;
|
pub mod book;
|
||||||
pub mod bvh;
|
pub mod bvh;
|
||||||
pub mod cube;
|
|
||||||
pub mod test;
|
pub mod test;
|
||||||
pub mod tutorial;
|
pub mod tutorial;
|
||||||
|
|||||||
@ -1,29 +1,30 @@
|
|||||||
|
use image;
|
||||||
|
|
||||||
use camera::Camera;
|
use camera::Camera;
|
||||||
use hitable::Hit;
|
use hitable::Hit;
|
||||||
use hitable_list::HitableList;
|
use hitable_list::HitableList;
|
||||||
use kdtree::KDTree;
|
use kdtree::KDTree;
|
||||||
use material::Lambertian;
|
use material::Lambertian;
|
||||||
use material::Metal;
|
|
||||||
use moving_sphere::MovingSphere;
|
|
||||||
use renderer::Opt;
|
use renderer::Opt;
|
||||||
use renderer::Scene;
|
use renderer::Scene;
|
||||||
use sphere::Sphere;
|
use sphere::Sphere;
|
||||||
use texture::ConstantTexture;
|
use texture::ConstantTexture;
|
||||||
|
use texture::ImageTexture;
|
||||||
use texture::NoiseTexture;
|
use texture::NoiseTexture;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
pub fn new(opt: &Opt) -> Scene {
|
pub fn new(opt: &Opt) -> Scene {
|
||||||
let lookfrom = Vec3::new(5., 5., 5.);
|
let lookfrom = Vec3::new(0., 5., 20.);
|
||||||
let lookat = Vec3::new(0., 0., 0.);
|
let lookat = Vec3::new(0., 1., 0.);
|
||||||
let dist_to_focus = (lookfrom - lookat).length();
|
let dist_to_focus = 10.0;
|
||||||
let aperture = 0.1;
|
let aperture = 0.0;
|
||||||
let time_min = 0.;
|
let time_min = 0.;
|
||||||
let time_max = 1.;
|
let time_max = 1.;
|
||||||
let camera = Camera::new(
|
let camera = Camera::new(
|
||||||
lookfrom,
|
lookfrom,
|
||||||
lookat,
|
lookat,
|
||||||
Vec3::new(0., 1., 0.),
|
Vec3::new(0., 1., 0.),
|
||||||
45.,
|
20.,
|
||||||
opt.width as f32 / opt.height as f32,
|
opt.width as f32 / opt.height as f32,
|
||||||
aperture,
|
aperture,
|
||||||
dist_to_focus,
|
dist_to_focus,
|
||||||
@ -36,7 +37,23 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
Box::new(ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4)))
|
Box::new(ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4)))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let world_image_bytes = include_bytes!("../../images/world.jpg");
|
||||||
|
let it = ImageTexture::new(image::load_from_memory(world_image_bytes).unwrap().to_rgb());
|
||||||
let objects: Vec<Box<Hit>> = vec![
|
let objects: Vec<Box<Hit>> = vec![
|
||||||
|
// Big sphere
|
||||||
|
Box::new(Sphere::new(
|
||||||
|
Vec3::new(0., 2., 0.),
|
||||||
|
2.0,
|
||||||
|
Box::new(Lambertian::new(Box::new(it))),
|
||||||
|
)),
|
||||||
|
// Earth sized sphere
|
||||||
|
Box::new(Sphere::new(
|
||||||
|
Vec3::new(0., -1000., 0.),
|
||||||
|
1000.,
|
||||||
|
// Box::new(Lambertian::new(ground_color)),
|
||||||
|
Box::new(Lambertian::new(Box::new(NoiseTexture::with_scale(10.)))),
|
||||||
|
)),
|
||||||
|
/*
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(0., 0., 0.),
|
Vec3::new(0., 0., 0.),
|
||||||
0.5,
|
0.5,
|
||||||
@ -44,19 +61,6 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
0.1, 0.2, 0.5,
|
0.1, 0.2, 0.5,
|
||||||
))))),
|
))))),
|
||||||
)),
|
)),
|
||||||
// Big sphere
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(0., 0., -2.),
|
|
||||||
1.0,
|
|
||||||
Box::new(Lambertian::new(Box::new(NoiseTexture::with_scale(10.)))),
|
|
||||||
)),
|
|
||||||
// Earth sized sphere
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(0., -100.5, 0.),
|
|
||||||
100.,
|
|
||||||
// Box::new(Lambertian::new(ground_color)),
|
|
||||||
Box::new(Lambertian::new(Box::new(NoiseTexture::new()))),
|
|
||||||
)),
|
|
||||||
// Shiny sphere
|
// Shiny sphere
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vec3::new(1., 0., 0.),
|
Vec3::new(1., 0., 0.),
|
||||||
@ -73,6 +77,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
0.2, 0.8, 0.2,
|
0.2, 0.8, 0.2,
|
||||||
))))),
|
))))),
|
||||||
)),
|
)),
|
||||||
|
*/
|
||||||
];
|
];
|
||||||
let world: Box<Hit> = if opt.use_accel {
|
let world: Box<Hit> = if opt.use_accel {
|
||||||
Box::new(KDTree::new(objects, time_min, time_max))
|
Box::new(KDTree::new(objects, time_min, time_max))
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use std::f32::consts::PI;
|
||||||
|
|
||||||
use aabb::AABB;
|
use aabb::AABB;
|
||||||
use hitable::Hit;
|
use hitable::Hit;
|
||||||
use hitable::HitRecord;
|
use hitable::HitRecord;
|
||||||
@ -12,6 +14,14 @@ pub struct Sphere {
|
|||||||
material: Box<Material>,
|
material: Box<Material>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_sphere_uv(p: Vec3) -> (f32, f32) {
|
||||||
|
let phi = p.z.atan2(p.x);
|
||||||
|
let theta = p.y.asin();
|
||||||
|
let u = 1. - (phi + PI) / (2. * PI);
|
||||||
|
let v = (theta + PI / 2.) / PI;
|
||||||
|
(u, v)
|
||||||
|
}
|
||||||
|
|
||||||
impl Sphere {
|
impl Sphere {
|
||||||
pub fn new(center: Vec3, radius: f32, material: Box<Material>) -> Sphere {
|
pub fn new(center: Vec3, radius: f32, material: Box<Material>) -> Sphere {
|
||||||
Sphere {
|
Sphere {
|
||||||
@ -33,8 +43,10 @@ impl Hit for Sphere {
|
|||||||
let temp = (-b - (b * b - a * c).sqrt()) / a;
|
let temp = (-b - (b * b - a * c).sqrt()) / a;
|
||||||
if temp < t_max && temp > t_min {
|
if temp < t_max && temp > t_min {
|
||||||
let point = r.point_at_parameter(temp);
|
let point = r.point_at_parameter(temp);
|
||||||
|
let uv = get_sphere_uv((point - self.center) / self.radius);
|
||||||
return Some(HitRecord {
|
return Some(HitRecord {
|
||||||
t: temp,
|
t: temp,
|
||||||
|
uv,
|
||||||
p: point,
|
p: point,
|
||||||
normal: (point - self.center) / self.radius,
|
normal: (point - self.center) / self.radius,
|
||||||
material: &*self.material,
|
material: &*self.material,
|
||||||
@ -43,8 +55,10 @@ impl Hit for Sphere {
|
|||||||
let temp = (-b + (b * b - a * c).sqrt()) / a;
|
let temp = (-b + (b * b - a * c).sqrt()) / a;
|
||||||
if temp < t_max && temp > t_min {
|
if temp < t_max && temp > t_min {
|
||||||
let point = r.point_at_parameter(temp);
|
let point = r.point_at_parameter(temp);
|
||||||
|
let uv = get_sphere_uv((point - self.center) / self.radius);
|
||||||
return Some(HitRecord {
|
return Some(HitRecord {
|
||||||
t: temp,
|
t: temp,
|
||||||
|
uv,
|
||||||
p: point,
|
p: point,
|
||||||
normal: (point - self.center) / self.radius,
|
normal: (point - self.center) / self.radius,
|
||||||
material: &*self.material,
|
material: &*self.material,
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
use image::RgbImage;
|
||||||
|
|
||||||
|
use perlin::turb;
|
||||||
use perlin::GENERATOR;
|
use perlin::GENERATOR;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
@ -58,6 +61,37 @@ impl NoiseTexture {
|
|||||||
|
|
||||||
impl Texture for NoiseTexture {
|
impl Texture for NoiseTexture {
|
||||||
fn value(&self, _u: f32, _v: f32, p: Vec3) -> Vec3 {
|
fn value(&self, _u: f32, _v: f32, p: Vec3) -> Vec3 {
|
||||||
Vec3::new(1., 1., 1.) * 0.5 * (1. + GENERATOR.noise(self.scale * p))
|
//Vec3::new(1., 1., 1.) * turb(self.scale * p, 7)
|
||||||
|
//Vec3::new(1., 1., 1.) * 0.5 * (1. + turb(self.scale * p, 7))
|
||||||
|
Vec3::new(1., 1., 1.) * 0.5 * (1. + (self.scale * p.x + 5. * turb(p, 7)).sin())
|
||||||
|
//Vec3::new(1., 1., 1.) * 0.5 * (1. + GENERATOR.noise(self.scale * p))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ImageTexture {
|
||||||
|
img: RgbImage,
|
||||||
|
width: f32,
|
||||||
|
height: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ImageTexture {
|
||||||
|
pub fn new(img: RgbImage) -> ImageTexture {
|
||||||
|
let (w, h) = img.dimensions();
|
||||||
|
ImageTexture {
|
||||||
|
img,
|
||||||
|
width: w as f32,
|
||||||
|
height: h as f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Texture for ImageTexture {
|
||||||
|
fn value(&self, u: f32, v: f32, _p: Vec3) -> Vec3 {
|
||||||
|
// Wrap texcoords by default.
|
||||||
|
let x = (u % 1. * self.width) as u32;
|
||||||
|
let y = ((1. - v % 1.) * self.height) as u32;
|
||||||
|
let p = self.img.get_pixel(x, y);
|
||||||
|
let rgb = Vec3::new(p[0] as f32 / 255., p[1] as f32 / 255., p[2] as f32 / 255.);
|
||||||
|
rgb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user