diff --git a/examples/environment/src/main.rs b/examples/environment/src/main.rs index e24e5d91..fb006268 100644 --- a/examples/environment/src/main.rs +++ b/examples/environment/src/main.rs @@ -72,6 +72,7 @@ pub async fn run() { // main loop let mut color = [1.0; 4]; + let mut show_debug = false; window.render_loop(move |mut frame_input| { let mut panel_width = 0.0; gui.update( @@ -83,6 +84,7 @@ pub async fn run() { use three_d::egui::*; Panel::left("side_panel").show_inside(ui, |ui| { ui.heading("Debug Panel"); + ui.checkbox(&mut show_debug, "Show debug"); ui.label("Material"); ui.add(Slider::new(&mut model.material.metallic, 0.0..=1.0).text("Metallic")); @@ -186,6 +188,79 @@ pub async fn run() { .write(|| gui.render()) .unwrap(); + if show_debug { + let secondary_viewport = Viewport { + x: viewport.x, + y: viewport.y, + width: (200.0 * frame_input.device_pixel_ratio) as u32, + height: (100.0 * frame_input.device_pixel_ratio) as u32, + }; + camera.set_viewport(secondary_viewport); + frame_input.screen().apply_screen_effect( + &CopyEffect::default(), + &camera, + &[], + Some(ColorTexture::CubeMap { + texture: skybox.texture(), + sides: &[], + }), + None, + ); + + let secondary_viewport = Viewport { + x: viewport.x, + y: viewport.y + (100.0 * frame_input.device_pixel_ratio) as i32, + width: (200.0 * frame_input.device_pixel_ratio) as u32, + height: (100.0 * frame_input.device_pixel_ratio) as u32, + }; + camera.set_viewport(secondary_viewport); + frame_input.screen().apply_screen_effect( + &CopyEffect::default(), + &camera, + &[], + Some(ColorTexture::CubeMap { + texture: &light.environment.as_ref().unwrap().prefilter_map, + sides: &[], + }), + None, + ); + + let secondary_viewport = Viewport { + x: viewport.x, + y: viewport.y + (200.0 * frame_input.device_pixel_ratio) as i32, + width: (200.0 * frame_input.device_pixel_ratio) as u32, + height: (100.0 * frame_input.device_pixel_ratio) as u32, + }; + camera.set_viewport(secondary_viewport); + frame_input.screen().apply_screen_effect( + &CopyEffect::default(), + &camera, + &[], + Some(ColorTexture::CubeMap { + texture: &light.environment.as_ref().unwrap().irradiance_map, + sides: &[], + }), + None, + ); + + let secondary_viewport = Viewport { + x: viewport.x, + y: viewport.y + (300.0 * frame_input.device_pixel_ratio) as i32, + width: (200.0 * frame_input.device_pixel_ratio) as u32, + height: (200.0 * frame_input.device_pixel_ratio) as u32, + }; + camera.set_viewport(secondary_viewport); + frame_input.screen().apply_screen_effect( + &CopyEffect::default(), + &camera, + &[], + Some(ColorTexture::Single( + &light.environment.as_ref().unwrap().brdf_map, + )), + None, + ); + } + FrameOutput::default() }); } diff --git a/src/core/texture.rs b/src/core/texture.rs index c8c17c8f..2f9365b2 100644 --- a/src/core/texture.rs +++ b/src/core/texture.rs @@ -137,7 +137,21 @@ impl ColorTexture<'_> { return texture(colorMap, vec3(uv, colorLayers[index])); }" .to_owned(), - Self::CubeMap { .. } => todo!(), + // Equirectangular projection + // SOURCE: https://stackoverflow.com/a/57544913 + Self::CubeMap { .. } => " + #define PI 3.1415926 + uniform samplerCube cubeMap; + vec4 sample_color(vec2 uv) { + float phi=uv.s*PI*2; + float theta=(uv.t-0.5)*PI; + + vec3 dir = vec3(cos(phi)*cos(theta),sin(theta),sin(phi)*cos(theta)); + + return texture(cubeMap, dir); + } + " + .to_owned(), } } @@ -148,9 +162,7 @@ impl ColorTexture<'_> { match self { Self::Single { .. } => 1u16 << 3, Self::Array { .. } => 10u16 << 3, - Self::CubeMap { .. } => { - todo!() - } + Self::CubeMap { .. } => 100u16 << 3, } } @@ -169,7 +181,7 @@ impl ColorTexture<'_> { program.use_uniform_array("colorLayers", &la); program.use_texture_array("colorMap", texture); } - Self::CubeMap { .. } => todo!(), + Self::CubeMap { texture, .. } => program.use_texture_cube("cubeMap", texture), } } }