diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/classes/cubemap.rs | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/src/classes/cubemap.rs b/src/classes/cubemap.rs index 0355a05..58e77d6 100644 --- a/src/classes/cubemap.rs +++ b/src/classes/cubemap.rs @@ -4,6 +4,7 @@ use anyhow::Result; use glam::{UVec2, Vec3Swizzles, uvec2, vec2, vec3}; use image::{DynamicImage, ImageBuffer, Rgba}; use log::info; +use rayon::iter::ParallelIterator; use serde::Serialize; use std::f32::consts::PI; @@ -38,35 +39,39 @@ pub fn cubemap_to_equirectangular( faces[0].height() ); let mut output_image = ImageBuffer::<Rgba<f32>, Vec<f32>>::new(output_width, output_height); - for (er_x, er_y, out) in output_image.enumerate_pixels_mut() { - let xy_angle = er_x as f32 / output_width as f32 * PI * 2.; - let cyl_z = er_y as f32 / output_height as f32 * 2. - 1.; - let sphere_azimuth = cyl_z.asin(); - let r = sphere_azimuth.cos(); - let normal = vec3(xy_angle.sin() * r, xy_angle.cos() * r, cyl_z); - assert!(normal.is_normalized()); + output_image + .par_enumerate_pixels_mut() + .for_each(|(er_x, er_y, out)| { + let phi = er_x as f32 / output_width as f32 * PI * 2.; + let theta = (1. - er_y as f32 / output_height as f32) * PI; + let normal = vec3( + phi.sin() * theta.sin(), + phi.cos() * theta.sin(), + theta.cos(), + ); + assert!(normal.is_normalized()); - let normal_abs = normal.abs(); - let (axis, max_comp, other_comps) = if normal_abs.x > normal_abs.y.max(normal_abs.z) { - (0, normal.x, normal.yz()) - } else if normal_abs.y > normal_abs.z { - (1, normal.y, normal.xz()) - } else { - (2, normal.z, normal.xy()) - }; + let normal_abs = normal.abs(); + let (axis, max_comp, other_comps) = if normal_abs.x > normal_abs.y.max(normal_abs.z) { + (0, normal.x, normal.yz()) + } else if normal_abs.y > normal_abs.z { + (1, normal.y, normal.xz()) + } else { + (2, normal.z, normal.xy()) + }; - let face = axis as usize * 2 + if max_comp < 0. { 1 } else { 0 }; - let face_texture = &faces[face]; - let face_size = uvec2(face_texture.width(), face_texture.height()); - let face_uv = other_comps / max_comp * vec2(1., -max_comp.signum()); - let face_uv = face_uv / 2. + 0.5; + let face = axis as usize * 2 + if max_comp < 0. { 1 } else { 0 }; + let face_texture = &faces[face]; + let face_size = uvec2(face_texture.width(), face_texture.height()); + let face_uv = other_comps / max_comp * vec2(1., -max_comp.signum()); + let face_uv = face_uv / 2. + 0.5; - let face_xy = (face_uv * face_size.as_vec2()) - .floor() - .as_uvec2() - .clamp(UVec2::MIN, face_size - UVec2::ONE); + let face_xy = (face_uv * face_size.as_vec2()) + .floor() + .as_uvec2() + .clamp(UVec2::MIN, face_size - UVec2::ONE); - out.0 = face_texture.get_pixel(face_xy.x, face_xy.y).0; - } + out.0 = face_texture.get_pixel(face_xy.x, face_xy.y).0; + }); output_image } |