mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
Add support for skybox transformation (#14267)
# Objective - Fixes https://github.com/bevyengine/bevy/issues/14036 ## Solution - Add a view space transformation for the skybox ## Testing - I have tested the newly added `transform` field using the `skybox` example. ``` diff --git a/examples/3d/skybox.rs b/examples/3d/skybox.rs index beaf5b268..d16cbe988 100644 --- a/examples/3d/skybox.rs +++ b/examples/3d/skybox.rs @@ -81,6 +81,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { Skybox { image: skybox_handle.clone(), brightness: 1000.0, + rotation: Quat::from_rotation_x(PI * -0.5), }, )); ``` <img width="1280" alt="image" src="https://github.com/bevyengine/bevy/assets/6300263/1230a608-58ea-492d-a811-90c54c3b43ef"> ## Migration Guide - Since we have added a new filed to the Skybox struct, users will need to include `..Default::default()` or some rotation value in their initialization code.
This commit is contained in:
parent
a79df7b124
commit
65aae92127
10 changed files with 36 additions and 1 deletions
|
@ -6,6 +6,7 @@ use bevy_ecs::{
|
|||
schedule::IntoSystemConfigs,
|
||||
system::{Commands, Query, Res, ResMut, Resource},
|
||||
};
|
||||
use bevy_math::{Mat4, Quat};
|
||||
use bevy_render::{
|
||||
camera::Exposure,
|
||||
extract_component::{
|
||||
|
@ -22,6 +23,7 @@ use bevy_render::{
|
|||
view::{ExtractedView, Msaa, ViewTarget, ViewUniform, ViewUniforms},
|
||||
Render, RenderApp, RenderSet,
|
||||
};
|
||||
use bevy_transform::components::Transform;
|
||||
use prepass::{SkyboxPrepassPipeline, SKYBOX_PREPASS_SHADER_HANDLE};
|
||||
|
||||
use crate::{core_3d::CORE_3D_DEPTH_FORMAT, prepass::PreviousViewUniforms};
|
||||
|
@ -90,6 +92,21 @@ pub struct Skybox {
|
|||
/// After applying this multiplier to the image samples, the resulting values should
|
||||
/// be in units of [cd/m^2](https://en.wikipedia.org/wiki/Candela_per_square_metre).
|
||||
pub brightness: f32,
|
||||
|
||||
/// View space rotation applied to the skybox cubemap.
|
||||
/// This is useful for users who require a different axis, such as the Z-axis, to serve
|
||||
/// as the vertical axis.
|
||||
pub rotation: Quat,
|
||||
}
|
||||
|
||||
impl Default for Skybox {
|
||||
fn default() -> Self {
|
||||
Skybox {
|
||||
image: Handle::default(),
|
||||
brightness: 0.0,
|
||||
rotation: Quat::IDENTITY,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ExtractComponent for Skybox {
|
||||
|
@ -106,6 +123,9 @@ impl ExtractComponent for Skybox {
|
|||
skybox.clone(),
|
||||
SkyboxUniforms {
|
||||
brightness: skybox.brightness * exposure,
|
||||
transform: Transform::from_rotation(skybox.rotation)
|
||||
.compute_matrix()
|
||||
.inverse(),
|
||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||
_wasm_padding_8b: 0,
|
||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||
|
@ -121,6 +141,7 @@ impl ExtractComponent for Skybox {
|
|||
#[derive(Component, ShaderType, Clone)]
|
||||
pub struct SkyboxUniforms {
|
||||
brightness: f32,
|
||||
transform: Mat4,
|
||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||
_wasm_padding_8b: u32,
|
||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
struct SkyboxUniforms {
|
||||
brightness: f32,
|
||||
transform: mat4x4<f32>,
|
||||
#ifdef SIXTEEN_BYTE_ALIGNMENT
|
||||
_wasm_padding_8b: u32,
|
||||
_wasm_padding_12b: u32,
|
||||
|
@ -29,7 +30,12 @@ fn coords_to_ray_direction(position: vec2<f32>, viewport: vec4<f32>) -> vec3<f32
|
|||
1.0,
|
||||
1.0,
|
||||
);
|
||||
let view_ray_direction = view_position_homogeneous.xyz / view_position_homogeneous.w;
|
||||
|
||||
// Transforming the view space ray direction by the skybox transform matrix, it is
|
||||
// equivalent to rotating the skybox itself.
|
||||
var view_ray_direction = view_position_homogeneous.xyz / view_position_homogeneous.w;
|
||||
view_ray_direction = (uniforms.transform * vec4(view_ray_direction, 1.0)).xyz;
|
||||
|
||||
// Transforming the view space ray direction by the view matrix, transforms the
|
||||
// direction to world space. Note that the w element is set to 0.0, as this is a
|
||||
// vector direction, not a position, That causes the matrix multiplication to ignore
|
||||
|
|
|
@ -240,6 +240,7 @@ fn add_skybox_and_environment_map(
|
|||
.insert(Skybox {
|
||||
brightness: 5000.0,
|
||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||
..Default::default()
|
||||
})
|
||||
.insert(EnvironmentMapLight {
|
||||
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
|
||||
|
|
|
@ -54,6 +54,7 @@ fn setup(
|
|||
Skybox {
|
||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||
brightness: bevy::pbr::light_consts::lux::DIRECT_SUNLIGHT,
|
||||
..Default::default()
|
||||
},
|
||||
));
|
||||
|
||||
|
|
|
@ -224,6 +224,7 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
|
|||
.insert(Skybox {
|
||||
brightness: 5000.0,
|
||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||
..Default::default()
|
||||
})
|
||||
.insert(EnvironmentMapLight {
|
||||
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
|
||||
|
|
|
@ -239,6 +239,7 @@ fn spawn_camera(commands: &mut Commands, assets: &ExampleAssets) {
|
|||
.insert(Skybox {
|
||||
image: assets.skybox.clone(),
|
||||
brightness: 150.0,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ fn add_environment_map_to_camera(
|
|||
.insert(Skybox {
|
||||
image: cubemaps.skybox.clone(),
|
||||
brightness: 5000.0,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
Skybox {
|
||||
image: skybox_handle.clone(),
|
||||
brightness: 1000.0,
|
||||
..Default::default()
|
||||
},
|
||||
));
|
||||
|
||||
|
|
|
@ -246,6 +246,7 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
|
|||
.insert(Skybox {
|
||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||
brightness: 5000.0,
|
||||
..Default::default()
|
||||
})
|
||||
.insert(ScreenSpaceReflectionsBundle::default())
|
||||
.insert(Fxaa::default());
|
||||
|
|
|
@ -52,6 +52,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
.insert(Skybox {
|
||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||
brightness: 1000.0,
|
||||
..Default::default()
|
||||
})
|
||||
.insert(VolumetricFogSettings {
|
||||
// This value is explicitly set to 0 since we have no environment map light
|
||||
|
|
Loading…
Reference in a new issue