summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs79
-rw-r--r--src/perlin.rs65
2 files changed, 107 insertions, 37 deletions
diff --git a/src/main.rs b/src/main.rs
index 5acfbd1..0f8a07e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,6 +4,8 @@ mod image;
use std::{println, format};
+use perlin::MixInImage;
+
use crate::perlin::Perlin;
use crate::vec3::{Vec3,Point3, Color};
use crate::image::Image;
@@ -85,55 +87,58 @@ fn sample(h: f64, l: f64) -> Color {
}.hsl_to_rgb()
}
+fn main() {
+ // params
+ let height = 512;
+ let width = 512;
+ let scale = 1.0;
+ let turb_depth = 15;
+ let dsw_factor = 1.5;
+ let mixin_factor = 0.015;
+ let mixin_strength = 0.3;
+ let mixin_image = MixInImage::from_bmp(&include_bytes!("../mixin.bmp").to_vec());
+ //let palette = GradientPalette{start: hex_color("0000ff"), end: hex_color("ff0000")};
+ //let palette = IdenPalette{};
+ let palette = FirePalette{};
+
+ let hue_perlin = Perlin::new();
+ //let light_perlin = Perlin::new();
+ let mut image = Image::new(width, height);
+ for x in 0..width {
+ for y in 0..height {
+ let hue_noise = hue_perlin.turb_dsw_mixin(&Point3{x: (x as f64 / width as f64) * scale, y: (y as f64 / height as f64) * scale, z: 0.0}, turb_depth, dsw_factor, &mixin_image, mixin_factor, mixin_strength);
+ //let light_noise = light_perlin.turb_dsw(&Point3{x: (x as f64 / width as f64) * scale, y: (y as f64 / height as f64) * scale, z: 0.0}, 7);
+ //image.set(x, y, &sample(hue_noise, light_noise)).unwrap();
+ //image.set(x, y, &Color{x: hue_noise, y: hue_noise, z: hue_noise}).unwrap();
+ image.set(x, y, &palette.sample(hue_noise)).unwrap();
+ }
+ }
+ image.write(&mut std::io::stdout());
+}
+
// fn main() {
// // params
// let height = 512;
// let width = 512;
+// let frames = 600;
// let scale = 1.0;
// let turb_depth = 20;
// let dsw_factor = 1.5;
-// //let palette = GradientPalette{start: hex_color("0000ff"), end: hex_color("ff0000")};
-// //let palette = IdenPalette{};
// let palette = FirePalette{};
// let hue_perlin = Perlin::new();
-// //let light_perlin = Perlin::new();
// let mut image = Image::new(width, height);
-// for x in 0..width {
-// for y in 0..height {
-// let hue_noise = hue_perlin.turb_dsw(&Point3{x: (x as f64 / width as f64) * scale, y: (y as f64 / height as f64) * scale, z: 0.0}, turb_depth, dsw_factor);
-// //let light_noise = light_perlin.turb_dsw(&Point3{x: (x as f64 / width as f64) * scale, y: (y as f64 / height as f64) * scale, z: 0.0}, 7);
-// //image.set(x, y, &sample(hue_noise, light_noise)).unwrap();
-// //image.set(x, y, &Color{x: hue_noise, y: hue_noise, z: hue_noise}).unwrap();
-// image.set(x, y, &palette.sample(hue_noise)).unwrap();
+// for f in 0..frames {
+// for x in 0..width {
+// for y in 0..height {
+// let hue_noise = hue_perlin.turb_dsw(&Point3{x: (x as f64 / width as f64) * scale, y: (y as f64 / height as f64) * scale, z: (f as f64 / frames as f64) * scale}, turb_depth, dsw_factor);
+// image.set(x, y, &palette.sample(hue_noise)).unwrap();
+// }
// }
+// let path = format!("./anim/{}.ppm", f);
+// image.write(&mut std::fs::File::create(path).unwrap());
+
+// println!("Finished frame {} of {}!", f, frames);
// }
-// image.write(&mut std::io::stdout());
// }
-fn main() {
- // params
- let height = 512;
- let width = 512;
- let frames = 600;
- let scale = 1.0;
- let turb_depth = 20;
- let dsw_factor = 1.5;
- let palette = FirePalette{};
-
- let hue_perlin = Perlin::new();
- let mut image = Image::new(width, height);
- for f in 0..frames {
- for x in 0..width {
- for y in 0..height {
- let hue_noise = hue_perlin.turb_dsw(&Point3{x: (x as f64 / width as f64) * scale, y: (y as f64 / height as f64) * scale, z: (f as f64 / frames as f64) * scale}, turb_depth, dsw_factor);
- image.set(x, y, &palette.sample(hue_noise)).unwrap();
- }
- }
- let path = format!("./anim/{}.ppm", f);
- image.write(&mut std::fs::File::create(path).unwrap());
-
- println!("Finished frame {} of {}!", f, frames);
- }
-}
-
diff --git a/src/perlin.rs b/src/perlin.rs
index 393582b..0b29f48 100644
--- a/src/perlin.rs
+++ b/src/perlin.rs
@@ -1,7 +1,53 @@
+use std::eprintln;
+
use crate::vec3::{Vec3, Point3};
const POINT_COUNT: usize = 256;
+// Mix-in images are necessarily monochrome, so each data entry is a pixel.
+pub struct MixInImage {
+ width: usize,
+ height: usize,
+ data: Vec<f64>,
+}
+
+impl MixInImage {
+ pub fn from_bmp(bmp_data: &Vec<u8>) -> Self {
+ let data_position = u32::from_le_bytes([
+ bmp_data[0x0A],
+ bmp_data[0x0B],
+ bmp_data[0x0C],
+ bmp_data[0x0D],
+ ]);
+ // assuming windows BITMAPINFOHEADER, these are i32
+ let width = i32::from_le_bytes([
+ bmp_data[0x12],
+ bmp_data[0x13],
+ bmp_data[0x14],
+ bmp_data[0x15],
+ ]) as usize;
+ let height = i32::from_le_bytes([
+ bmp_data[0x16],
+ bmp_data[0x17],
+ bmp_data[0x18],
+ bmp_data[0x19],
+ ]) as usize;
+ // assuming 3 channels, all of which are equal
+ let data = bmp_data[(data_position as usize)..bmp_data.len()].iter().skip(2).step_by(3).map(|x| *x as f64 / 255.0).collect();
+ Self {
+ width,
+ height,
+ data,
+ }
+ }
+
+ pub fn get(&self, point: &Point3) -> &f64 {
+ let disc_x = ((point.x * self.width as f64) % self.width as f64) as usize;
+ let disc_y = ((point.y * self.height as f64) % self.height as f64) as usize;
+ self.data.get((disc_y * self.width) + disc_x).unwrap()
+ }
+}
+
pub struct Perlin {
ranvec: Vec<Vec3>,
perm_x: Vec<usize>,
@@ -50,6 +96,25 @@ impl Perlin {
accum.abs()
}
+
+ pub fn turb_dsw_mixin(&self, point: &Point3, depth: u32, factor: f64, mixin: &MixInImage, mixin_factor: f64, mixin_strength: f64) -> f64 {
+ let mut accum = 0.0;
+ let mut temp_point = point.clone();
+ let mut mixin_point = point.clone();
+ let mut weight = 1.0;
+
+ for _ in 0..depth {
+ accum += weight * (1.0 - mixin_strength) * self.noise(&temp_point);
+ temp_point *= 2.0;
+ let diff = temp_point.xy_diff(&|p: &Vec3| -> f64 {weight * self.noise(p)});
+ temp_point += &diff * factor;
+ mixin_point += &diff * mixin_factor;
+ accum += weight * mixin_strength * mixin.get(&mixin_point);
+ weight *= 0.5;
+ }
+ accum.abs()
+ }
+
pub fn noise(&self, point: &Point3) -> f64 {
let u = point.x - point.x.floor();
let v = point.y - point.y.floor();