mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 12:43:34 +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,
|
schedule::IntoSystemConfigs,
|
||||||
system::{Commands, Query, Res, ResMut, Resource},
|
system::{Commands, Query, Res, ResMut, Resource},
|
||||||
};
|
};
|
||||||
|
use bevy_math::{Mat4, Quat};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
camera::Exposure,
|
camera::Exposure,
|
||||||
extract_component::{
|
extract_component::{
|
||||||
|
@ -22,6 +23,7 @@ use bevy_render::{
|
||||||
view::{ExtractedView, Msaa, ViewTarget, ViewUniform, ViewUniforms},
|
view::{ExtractedView, Msaa, ViewTarget, ViewUniform, ViewUniforms},
|
||||||
Render, RenderApp, RenderSet,
|
Render, RenderApp, RenderSet,
|
||||||
};
|
};
|
||||||
|
use bevy_transform::components::Transform;
|
||||||
use prepass::{SkyboxPrepassPipeline, SKYBOX_PREPASS_SHADER_HANDLE};
|
use prepass::{SkyboxPrepassPipeline, SKYBOX_PREPASS_SHADER_HANDLE};
|
||||||
|
|
||||||
use crate::{core_3d::CORE_3D_DEPTH_FORMAT, prepass::PreviousViewUniforms};
|
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
|
/// 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).
|
/// be in units of [cd/m^2](https://en.wikipedia.org/wiki/Candela_per_square_metre).
|
||||||
pub brightness: f32,
|
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 {
|
impl ExtractComponent for Skybox {
|
||||||
|
@ -106,6 +123,9 @@ impl ExtractComponent for Skybox {
|
||||||
skybox.clone(),
|
skybox.clone(),
|
||||||
SkyboxUniforms {
|
SkyboxUniforms {
|
||||||
brightness: skybox.brightness * exposure,
|
brightness: skybox.brightness * exposure,
|
||||||
|
transform: Transform::from_rotation(skybox.rotation)
|
||||||
|
.compute_matrix()
|
||||||
|
.inverse(),
|
||||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||||
_wasm_padding_8b: 0,
|
_wasm_padding_8b: 0,
|
||||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||||
|
@ -121,6 +141,7 @@ impl ExtractComponent for Skybox {
|
||||||
#[derive(Component, ShaderType, Clone)]
|
#[derive(Component, ShaderType, Clone)]
|
||||||
pub struct SkyboxUniforms {
|
pub struct SkyboxUniforms {
|
||||||
brightness: f32,
|
brightness: f32,
|
||||||
|
transform: Mat4,
|
||||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||||
_wasm_padding_8b: u32,
|
_wasm_padding_8b: u32,
|
||||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
struct SkyboxUniforms {
|
struct SkyboxUniforms {
|
||||||
brightness: f32,
|
brightness: f32,
|
||||||
|
transform: mat4x4<f32>,
|
||||||
#ifdef SIXTEEN_BYTE_ALIGNMENT
|
#ifdef SIXTEEN_BYTE_ALIGNMENT
|
||||||
_wasm_padding_8b: u32,
|
_wasm_padding_8b: u32,
|
||||||
_wasm_padding_12b: 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,
|
||||||
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
|
// 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
|
// 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
|
// vector direction, not a position, That causes the matrix multiplication to ignore
|
||||||
|
|
|
@ -240,6 +240,7 @@ fn add_skybox_and_environment_map(
|
||||||
.insert(Skybox {
|
.insert(Skybox {
|
||||||
brightness: 5000.0,
|
brightness: 5000.0,
|
||||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
.insert(EnvironmentMapLight {
|
.insert(EnvironmentMapLight {
|
||||||
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
|
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
|
||||||
|
|
|
@ -54,6 +54,7 @@ fn setup(
|
||||||
Skybox {
|
Skybox {
|
||||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||||
brightness: bevy::pbr::light_consts::lux::DIRECT_SUNLIGHT,
|
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 {
|
.insert(Skybox {
|
||||||
brightness: 5000.0,
|
brightness: 5000.0,
|
||||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
.insert(EnvironmentMapLight {
|
.insert(EnvironmentMapLight {
|
||||||
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
|
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 {
|
.insert(Skybox {
|
||||||
image: assets.skybox.clone(),
|
image: assets.skybox.clone(),
|
||||||
brightness: 150.0,
|
brightness: 150.0,
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,7 @@ fn add_environment_map_to_camera(
|
||||||
.insert(Skybox {
|
.insert(Skybox {
|
||||||
image: cubemaps.skybox.clone(),
|
image: cubemaps.skybox.clone(),
|
||||||
brightness: 5000.0,
|
brightness: 5000.0,
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
Skybox {
|
Skybox {
|
||||||
image: skybox_handle.clone(),
|
image: skybox_handle.clone(),
|
||||||
brightness: 1000.0,
|
brightness: 1000.0,
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,7 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
|
||||||
.insert(Skybox {
|
.insert(Skybox {
|
||||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||||
brightness: 5000.0,
|
brightness: 5000.0,
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
.insert(ScreenSpaceReflectionsBundle::default())
|
.insert(ScreenSpaceReflectionsBundle::default())
|
||||||
.insert(Fxaa::default());
|
.insert(Fxaa::default());
|
||||||
|
|
|
@ -52,6 +52,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
.insert(Skybox {
|
.insert(Skybox {
|
||||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||||
brightness: 1000.0,
|
brightness: 1000.0,
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
.insert(VolumetricFogSettings {
|
.insert(VolumetricFogSettings {
|
||||||
// This value is explicitly set to 0 since we have no environment map light
|
// This value is explicitly set to 0 since we have no environment map light
|
||||||
|
|
Loading…
Reference in a new issue