Skip to content

Commit 93b8c35

Browse files
committed
moved bloom into rust, more refactoring
1 parent 8e16fa6 commit 93b8c35

File tree

7 files changed

+133
-37
lines changed

7 files changed

+133
-37
lines changed

Cargo.lock

Lines changed: 13 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ debug = true
88

99
[dependencies]
1010
image = "*"
11-
mdo = "*"
11+
num = "*"
1212
rand = "*"
1313
num_cpus = "*"
1414
byteorder = "*"

src/camera.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use ray::*;
66
#[derive(Clone)]
77
pub struct Camera {
88
origin : Vec3,
9-
lower_left_corner : Vec3,
9+
upper_left_corner : Vec3,
1010
horizontal : Vec3,
1111
vertical : Vec3,
1212
u : Vec3,
@@ -36,9 +36,9 @@ pub fn camera(
3636

3737
return Camera {
3838
origin: lookfrom,
39-
lower_left_corner: lookfrom
39+
upper_left_corner: lookfrom
4040
- half_width * focus_dist * &u
41-
- half_height * focus_dist * &v
41+
+ half_height * focus_dist * &v
4242
- focus_dist * &w,
4343
horizontal: 2.0 * half_width * focus_dist * &u,
4444
vertical: 2.0 * half_height * focus_dist * &v,
@@ -55,9 +55,9 @@ impl Camera {
5555
let rd = self.lens_radius * rand_in_disk(rng);
5656
let offset = &self.u * rd[X] + &self.v * rd[Y];
5757

58-
let dir = &self.lower_left_corner
58+
let dir = &self.upper_left_corner
5959
+ s * &self.horizontal
60-
+ t * &self.vertical
60+
- t * &self.vertical
6161
- &self.origin - &offset;
6262
let time = self.time0 + rng.gen::<f32>() * (self.time1 - self.time0);
6363
return ray(&self.origin + offset, dir, time);

src/main.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern crate image;
3535
extern crate rand;
3636
extern crate num_cpus;
3737
extern crate byteorder;
38+
extern crate num;
3839

3940
fn render_overlord(base_rng : &mut Rng, render_task : RenderTask) {
4041
let render_task = Arc::new(render_task);
@@ -123,7 +124,7 @@ fn render_overlord(base_rng : &mut Rng, render_task : RenderTask) {
123124

124125
if prev_samp / nsave != main_target.samples / nsave {
125126
main_target.write_png("trace.png");
126-
main_target.write_hdr("raw.rgb");
127+
// main_target.write_hdr("raw.rgb");
127128

128129
print!("{} ", main_target.samples);
129130
io::stdout().flush().unwrap();
@@ -163,6 +164,7 @@ fn render_a_frame(rng : &mut Rng, task : &RenderTask, target : &mut RenderTarget
163164
target.samples += 1;
164165
}
165166

167+
166168
#[inline(never)]
167169
fn ray_trace(rng : &mut Rng, r0 : Ray, world : &Object) -> Vec3 {
168170
let mut accumulator = vec3(0.0, 0.0, 0.0);
@@ -191,8 +193,8 @@ fn ray_trace(rng : &mut Rng, r0 : Ray, world : &Object) -> Vec3 {
191193
break;
192194
}
193195
}
194-
continue;
195196
}
197+
continue;
196198
},
197199
None => {
198200
break;
@@ -214,11 +216,10 @@ fn main() {
214216
x.hit(&r, (0.0, 1.0));
215217

216218
let seed : RngSeed = rand::thread_rng().gen();
217-
let seed = [4221229915, 2284345502, 1839295593, 2276192001];
218219
println!("let seed = {:?};", seed);
219220
let mut rng : Rng = Rng::from_seed(seed);
220221

221-
let task = one_weekend(&mut rng);
222+
let task = the_next_week(&mut rng);
222223

223224
render_overlord(&mut rng, task);
224225
}

src/render_target.rs

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1+
use vec3::*;
2+
13
use std;
24
use std::ops::{Index, IndexMut};
35
use std::fs::File;
46
use std::path::Path;
57
use std::io::Write;
68

79
use image;
10+
use image::{Luma};
11+
use image::math::utils::clamp;
12+
13+
use num::{Float};
14+
15+
type Image32 = image::ImageBuffer<Luma<f32>, Vec<f32>>;
816

917
pub struct RenderTarget {
1018
pub size : (u32, u32),
@@ -14,29 +22,39 @@ pub struct RenderTarget {
1422

1523
impl RenderTarget {
1624
pub fn new(size : (u32, u32)) -> RenderTarget {
17-
RenderTarget{
25+
RenderTarget {
1826
size: size,
1927
buf: vec![[0.0; 3]; (size.0 * size.1) as usize],
2028
samples: 0,
2129
}
2230
}
2331

24-
pub fn write_png(&self, filename : &str) {
32+
#[allow(dead_code)]
33+
pub fn write_png(&mut self, filename : &str) {
2534
let (nx, ny) = self.size;
2635
let ns = self.samples;
2736
let mut img = image::DynamicImage::new_rgb8(nx, ny);
37+
let bloom = self.bloom();
2838

2939
for y in 0..ny {
3040
for x in 0..nx {
3141
let mut col = self[(x, y)].clone();
32-
col[0] = (col[0] / ns as f64).max(0.0).min(1.0).sqrt();
33-
col[1] = (col[1] / ns as f64).max(0.0).min(1.0).sqrt();
34-
col[2] = (col[2] / ns as f64).max(0.0).min(1.0).sqrt();
42+
43+
for e in 0..3 {
44+
col[e] /= ns as f64;
45+
col[e] += bloom.get_pixel(x, y).data[0] as f64;
46+
col[e] = clamp(col[e], 0.0, 1.0);
47+
col[e] = col[e].sqrt();
48+
}
49+
50+
// col[0] = clamp(col[0] / ns as f64, 0.0, 1.0).sqrt();
51+
// col[1] = clamp(col[1] / ns as f64, 0.0, 1.0).sqrt();
52+
// col[2] = clamp(col[2] / ns as f64, 0.0, 1.0).sqrt();
3553

3654
let ir = (255.99 * col[0]) as u8;
3755
let ig = (255.99 * col[1]) as u8;
3856
let ib = (255.99 * col[2]) as u8;
39-
img.as_mut_rgb8().unwrap()[(x, ny - y - 1)]
57+
img.as_mut_rgb8().unwrap()[(x, y)]
4058
= image::Rgb([ir, ig, ib]);
4159
}
4260
}
@@ -45,19 +63,38 @@ impl RenderTarget {
4563
}
4664

4765

66+
#[allow(dead_code)]
4867
pub fn write_hdr(&self, filename : &str) {
4968
let ref mut fout = File::create(&Path::new(filename)).unwrap();
5069

51-
let bytes = unsafe {
52-
let ptr : *const u8 = std::mem::transmute(&self.buf[0][0] as *const _);
53-
let len = 8 * self.size.0 * self.size.1 * 3;
54-
std::slice::from_raw_parts(ptr, len as usize)
70+
let bytes : &[u8] = unsafe {
71+
let ptr : *const u8 = std::mem::transmute(&self.buf[0] as *const _);
72+
std::slice::from_raw_parts(ptr, (8 * self.size.0 * self.size.1 * 3) as usize)
5573
};
5674

5775
write!(fout, "{} {} {}\n\n",
5876
self.size.0, self.size.1, self.samples).unwrap();
5977
fout.write(bytes).unwrap();
6078
}
79+
80+
fn bloom(&mut self) -> Image32 {
81+
let (nx, ny) = self.size;
82+
83+
let luma_matrix = vec3(0.299, 0.587, 0.114);
84+
85+
let lumae : Vec<f32> = self.buf.iter().map(|p| {
86+
let mut l = 0.299 * p[0] + 0.587 * p[1] + 0.114 * p[2];
87+
l /= self.samples as f64;
88+
if l > 1.0 {
89+
l as f32
90+
} else {
91+
0.0
92+
}
93+
}).collect();
94+
95+
let im = Image32::from_vec(nx, ny, lumae).unwrap();
96+
image::imageops::blur(&im, 2.5)
97+
}
6198
}
6299

63100
impl Index<(u32, u32)> for RenderTarget {
@@ -66,6 +103,7 @@ impl Index<(u32, u32)> for RenderTarget {
66103
&self.buf[(y * self.size.0 + x) as usize]
67104
}
68105
}
106+
69107
impl IndexMut<(u32, u32)> for RenderTarget {
70108
fn index_mut<'a>(&'a mut self, (x, y) : (u32, u32)) -> &'a mut [f64; 3] {
71109
&mut self.buf[(y * self.size.0 + x) as usize]

src/tasks.rs

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ pub fn one_weekend(rng : &mut Rng) -> RenderTask {
9696
}
9797

9898
#[allow(dead_code)]
99-
pub fn the_next_week(rng : &mut Rng) -> Box<Object> {
99+
pub fn the_next_week(rng : &mut Rng) -> RenderTask {
100100
let mut list : Vec<Box<Object>> = Vec::new();
101101
let mut boxlist : Vec<Box<Object>> = Vec::new();
102102
let mut boxlist2 : Vec<Box<Object>> = Vec::new();
@@ -215,11 +215,33 @@ pub fn the_next_week(rng : &mut Rng) -> Box<Object> {
215215
into_bvh(rng, boxlist2, (0.0, 1.0))));
216216
}
217217

218-
return into_bvh(rng, list, (0.0, 1.0));
218+
let world = into_bvh(rng, list, (0.0, 1.0));
219+
220+
let size = (500, 500);
221+
222+
let lookfrom = ivec3(478, 278, -600);
223+
let lookat = ivec3(278, 278, 0);
224+
let dist_to_focus = 10.0;
225+
let aperture = 0.0;
226+
let vfov = 40.0;
227+
let aspect = size.0 as f32 / size.1 as f32;
228+
229+
let camera = camera(lookfrom, lookat, vec3(0.0, 1.0, 0.0),
230+
vfov, aspect,
231+
aperture, dist_to_focus,
232+
0.0, 1.0);
233+
234+
235+
RenderTask {
236+
world: world,
237+
camera: camera,
238+
target_size: size,
239+
samples: 10000,
240+
}
219241
}
220242

221243
#[allow(dead_code)]
222-
pub fn simple_light(rng : &mut Rng) -> Box<Object> {
244+
pub fn simple_light(rng : &mut Rng) -> RenderTask {
223245
let noise = Arc::new(PerlinNoise::new(rng, 256));
224246
let ntex = PerlinTexture::new(rng, 4.0);
225247
let mut list : Vec<Box<Object>> = Vec::new();
@@ -253,11 +275,32 @@ pub fn simple_light(rng : &mut Rng) -> Box<Object> {
253275
material: light_material.clone()
254276
});
255277

256-
return into_bvh(rng, list, (0.0, 1.0));
278+
let world = into_bvh(rng, list, (0.0, 1.0));
279+
280+
let size = (200, 200);
281+
282+
let lookfrom = ivec3(13, 2, 3);
283+
let lookat = ivec3(0, 0, 0);
284+
let dist_to_focus = 10.0;
285+
let aperture = 0.1;
286+
let vfov = 20.0;
287+
let aspect = size.0 as f32 / size.1 as f32;
288+
289+
let camera = camera(lookfrom, lookat, ivec3(0, 1, 0),
290+
vfov, aspect,
291+
aperture, dist_to_focus,
292+
0.0, 1.0);
293+
294+
RenderTask {
295+
world: world,
296+
camera: camera,
297+
target_size: size,
298+
samples: 1000,
299+
}
257300
}
258301

259302
#[allow(dead_code)]
260-
pub fn cornell_box(rng : &mut Rng) -> Box<Object> {
303+
pub fn cornell_box(rng : &mut Rng) -> RenderTask {
261304
let mut list : Vec<Box<Object>> = Vec::new();
262305

263306
let red : Arc<Material> = Arc::new(Lambertian(ConstantTex(vec3(0.65, 0.05, 0.05))));
@@ -292,7 +335,7 @@ pub fn cornell_box(rng : &mut Rng) -> Box<Object> {
292335

293336
let size = (500, 500);
294337

295-
let lookfrom = ivec3(478, 278, -600);
338+
let lookfrom = ivec3(278, 278, -800);
296339
let lookat = ivec3(278, 278, 0);
297340
let dist_to_focus = 10.0;
298341
let aperture = 0.0;
@@ -304,5 +347,12 @@ pub fn cornell_box(rng : &mut Rng) -> Box<Object> {
304347
aperture, dist_to_focus,
305348
0.0, 1.0);
306349

307-
return into_bvh(rng, list, (0.0, 1.0));
350+
let world = into_bvh(rng, list, (0.0, 1.0));
351+
352+
RenderTask {
353+
world: world,
354+
camera: camera,
355+
target_size: size,
356+
samples: 1000,
357+
}
308358
}

src/texture.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use random::*;
55
use image;
66

77
use std::sync::Arc;
8-
use std::cmp::{max, min};
8+
use image::math::utils::clamp;
99

1010
pub trait Texture : Send + Sync {
1111
fn tex_lookup(&self, uv : (f32, f32), p : &Vec3) -> Vec3;
@@ -170,9 +170,9 @@ impl Texture for ImageTexture {
170170
let ny = self.im.height();
171171

172172
uv.1 = 1.0 - uv.1;
173-
let i = min(max(0, (uv.0 * nx as f32) as i32) as u32, nx - 1);
174-
let j = min(max(0, (uv.1 * ny as f32) as i32) as u32, ny - 1);
175-
let pix = self.im.get_pixel(i, j);
173+
let i = clamp((uv.0 * nx as f32) as i32, 0, nx as i32 - 1);
174+
let j = clamp((uv.1 * ny as f32) as i32, 0, ny as i32 - 1);
175+
let pix = self.im.get_pixel(i as u32, j as u32);
176176
vec3(pix[0] as f32 / 255.0,
177177
pix[1] as f32 / 255.0,
178178
pix[2] as f32 / 255.0)

0 commit comments

Comments
 (0)