diff options
author | lamp | 2023-12-29 23:32:34 +0000 |
---|---|---|
committer | lamp | 2023-12-29 23:32:34 +0000 |
commit | eb8a896865a6f3dbb5e3680c43ae408e29176ae4 (patch) | |
tree | 82eeb300be148a987d26aefd6c2c7afb2a92f541 | |
parent | b3bb54ca9cdcca60adb401fd69278a12d8fd367a (diff) |
initial dsw_mixin stuffmain
-rwxr-xr-x | convert.sh | 5 | ||||
-rw-r--r-- | src/main.rs | 79 | ||||
-rw-r--r-- | src/perlin.rs | 65 |
3 files changed, 112 insertions, 37 deletions
diff --git a/convert.sh b/convert.sh new file mode 100755 index 0000000..2a5072e --- /dev/null +++ b/convert.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +size=512x512 + +convert "$1" -background white -flatten -alpha off -fx '(r+g+b)/3' -colorspace Gray -resize "$size" -gravity center -extent "$size" "$2" 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(); |