bevy/examples/3d/scrolling_fog.rs

144 lines
4.8 KiB
Rust
Raw Normal View History

Allow fog density texture to be scrolled over time with an offset (#14868) # Objective - The goal of this PR is to make it possible to move the density texture of a `FogVolume` over time in order to create dynamic effects like fog moving in the wind. - You could theoretically move the `FogVolume` itself, but this is not ideal, because the `FogVolume` AABB would eventually leave the area. If you want an area to remain foggy while also creating the impression that the fog is moving in the wind, a scrolling density texture is a better solution. ## Solution - The PR adds a `density_texture_offset` field to the `FogVolume` component. This offset is in the UVW coordinates of the density texture, meaning that a value of `(0.5, 0.0, 0.0)` moves the 3d texture by half along the x-axis. - Values above 1.0 are wrapped, a 1.5 offset is the same as a 0.5 offset. This makes it so that the density texture wraps around on the other side, meaning that a repeating 3d noise texture can seamlessly scroll forever. It also makes it easy to move the density texture over time by simply increasing the offset every frame. ## Testing - A `scrolling_fog` example has been added to demonstrate the feature. It uses the offset to scroll a repeating 3d noise density texture to create the impression of fog moving in the wind. - The camera is looking at a pillar with the sun peaking behind it. This highlights the effect the changing density has on the volumetric lighting interactions. - Temporal anti-aliasing combined with the `jitter` option of `VolumetricFogSettings` is used to improve the quality of the effect. --- ## Showcase https://github.com/user-attachments/assets/3aa50ebd-771c-4c99-ab5d-255c0c3be1a8
2024-08-22 19:43:14 +00:00
//! Showcases a `FogVolume`'s density texture being scrolled over time to create
//! the effect of fog moving in the wind.
//!
//! The density texture is a repeating 3d noise texture and the `density_texture_offset`
//! is moved every frame to achieve this.
//!
Rename rendering components for improved consistency and clarity (#15035) # Objective The names of numerous rendering components in Bevy are inconsistent and a bit confusing. Relevant names include: - `AutoExposureSettings` - `AutoExposureSettingsUniform` - `BloomSettings` - `BloomUniform` (no `Settings`) - `BloomPrefilterSettings` - `ChromaticAberration` (no `Settings`) - `ContrastAdaptiveSharpeningSettings` - `DepthOfFieldSettings` - `DepthOfFieldUniform` (no `Settings`) - `FogSettings` - `SmaaSettings`, `Fxaa`, `TemporalAntiAliasSettings` (really inconsistent??) - `ScreenSpaceAmbientOcclusionSettings` - `ScreenSpaceReflectionsSettings` - `VolumetricFogSettings` Firstly, there's a lot of inconsistency between `Foo`/`FooSettings` and `FooUniform`/`FooSettingsUniform` and whether names are abbreviated or not. Secondly, the `Settings` post-fix seems unnecessary and a bit confusing semantically, since it makes it seem like the component is mostly just auxiliary configuration instead of the core *thing* that actually enables the feature. This will be an even bigger problem once bundles like `TemporalAntiAliasBundle` are deprecated in favor of required components, as users will expect a component named `TemporalAntiAlias` (or similar), not `TemporalAntiAliasSettings`. ## Solution Drop the `Settings` post-fix from the component names, and change some names to be more consistent. - `AutoExposure` - `AutoExposureUniform` - `Bloom` - `BloomUniform` - `BloomPrefilter` - `ChromaticAberration` - `ContrastAdaptiveSharpening` - `DepthOfField` - `DepthOfFieldUniform` - `DistanceFog` - `Smaa`, `Fxaa`, `TemporalAntiAliasing` (note: we might want to change to `Taa`, see "Discussion") - `ScreenSpaceAmbientOcclusion` - `ScreenSpaceReflections` - `VolumetricFog` I kept the old names as deprecated type aliases to make migration a bit less painful for users. We should remove them after the next release. (And let me know if I should just... not add them at all) I also added some very basic docs for a few types where they were missing, like on `Fxaa` and `DepthOfField`. ## Discussion - `TemporalAntiAliasing` is still inconsistent with `Smaa` and `Fxaa`. Consensus [on Discord](https://discord.com/channels/691052431525675048/743663924229963868/1280601167209955431) seemed to be that renaming to `Taa` would probably be fine, but I think it's a bit more controversial, and it would've required renaming a lot of related types like `TemporalAntiAliasNode`, `TemporalAntiAliasBundle`, and `TemporalAntiAliasPlugin`, so I think it's better to leave to a follow-up. - I think `Fog` should probably have a more specific name like `DistanceFog` considering it seems to be distinct from `VolumetricFog`. ~~This should probably be done in a follow-up though, so I just removed the `Settings` post-fix for now.~~ (done) --- ## Migration Guide Many rendering components have been renamed for improved consistency and clarity. - `AutoExposureSettings` → `AutoExposure` - `BloomSettings` → `Bloom` - `BloomPrefilterSettings` → `BloomPrefilter` - `ContrastAdaptiveSharpeningSettings` → `ContrastAdaptiveSharpening` - `DepthOfFieldSettings` → `DepthOfField` - `FogSettings` → `DistanceFog` - `SmaaSettings` → `Smaa` - `TemporalAntiAliasSettings` → `TemporalAntiAliasing` - `ScreenSpaceAmbientOcclusionSettings` → `ScreenSpaceAmbientOcclusion` - `ScreenSpaceReflectionsSettings` → `ScreenSpaceReflections` - `VolumetricFogSettings` → `VolumetricFog` --------- Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-09-10 01:11:46 +00:00
//! The example also utilizes the jitter option of `VolumetricFog` in tandem
Allow fog density texture to be scrolled over time with an offset (#14868) # Objective - The goal of this PR is to make it possible to move the density texture of a `FogVolume` over time in order to create dynamic effects like fog moving in the wind. - You could theoretically move the `FogVolume` itself, but this is not ideal, because the `FogVolume` AABB would eventually leave the area. If you want an area to remain foggy while also creating the impression that the fog is moving in the wind, a scrolling density texture is a better solution. ## Solution - The PR adds a `density_texture_offset` field to the `FogVolume` component. This offset is in the UVW coordinates of the density texture, meaning that a value of `(0.5, 0.0, 0.0)` moves the 3d texture by half along the x-axis. - Values above 1.0 are wrapped, a 1.5 offset is the same as a 0.5 offset. This makes it so that the density texture wraps around on the other side, meaning that a repeating 3d noise texture can seamlessly scroll forever. It also makes it easy to move the density texture over time by simply increasing the offset every frame. ## Testing - A `scrolling_fog` example has been added to demonstrate the feature. It uses the offset to scroll a repeating 3d noise density texture to create the impression of fog moving in the wind. - The camera is looking at a pillar with the sun peaking behind it. This highlights the effect the changing density has on the volumetric lighting interactions. - Temporal anti-aliasing combined with the `jitter` option of `VolumetricFogSettings` is used to improve the quality of the effect. --- ## Showcase https://github.com/user-attachments/assets/3aa50ebd-771c-4c99-ab5d-255c0c3be1a8
2024-08-22 19:43:14 +00:00
//! with temporal anti-aliasing to improve the visual quality of the effect.
//!
//! The camera is looking at a pillar with the sun peaking behind it. The light
//! interactions change based on the density of the fog.
use bevy::{
core_pipeline::{
bloom::Bloom,
experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin},
},
pbr::{DirectionalLightShadowMap, FogVolume, VolumetricFog, VolumetricLight},
prelude::*,
render::texture::{
ImageAddressMode, ImageFilterMode, ImageLoaderSettings, ImageSampler,
ImageSamplerDescriptor,
},
Fix fog density texture offset seam (#14900) # Objective - There is a flaw in the implementation of `FogVolume`'s `density_texture_offset` from #14868. Because of the way I am wrapping the UVW coordinates in the volumetric fog shader, a seam is visible when the 3d texture is wrapping around from one side to the other: ![density_texture_offset_seam](https://github.com/user-attachments/assets/89527ef2-5e1b-4b90-8e73-7a3e607697d4) ## Solution - This PR fixes the issue by removing the wrapping from the shader and instead leaving it to the user to configure the 3d noise texture to use `ImageAddressMode::Repeat` if they want it to repeat. Using `ImageAddressMode::Repeat` is the proper solution to avoid the obvious seam: ![density_texture_seam_fixed](https://github.com/user-attachments/assets/06e871a6-2db1-4501-b425-4141605f9b26) - The sampler cannot be implicitly configured to use `ImageAddressMode::Repeat` because that's not always desirable. For example, the `fog_volumes` example wouldn't work properly because the texture from the edges of the volume would overflow to the other sides, which would be bad in this instance (but it's good in the case of the `scrolling_fog` example). So leaving it to the user to decide on their own whether they want the density texture to repeat seems to be the best solution. ## Testing - The `scrolling_fog` example still looks the same, it was just changed to explicitly declare that the density texture should be repeating when loading the asset. The `fog_volumes` example is unaffected. <details> <summary>Minimal reproduction example on current main</summary> <pre> use bevy::core_pipeline::experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin}; use bevy::pbr::{FogVolume, VolumetricFogSettings, VolumetricLight}; use bevy::prelude::*;<br> fn main() { App::new() .add_plugins((DefaultPlugins, TemporalAntiAliasPlugin)) .add_systems(Startup, setup) .run(); }<br> fn setup(mut commands: Commands, assets: Res&lt;AssetServer&gt;) { commands.spawn(( Camera3dBundle { transform: Transform::from_xyz(3.5, -1.0, 0.4) .looking_at(Vec3::new(0.0, 0.0, 0.4), Vec3::Y), msaa: Msaa::Off, ..default() }, TemporalAntiAliasBundle::default(), VolumetricFogSettings { ambient_intensity: 0.0, jitter: 0.5, ..default() }, ));<br> commands.spawn(( DirectionalLightBundle { transform: Transform::from_xyz(-6.0, 5.0, -9.0) .looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), directional_light: DirectionalLight { illuminance: 32_000.0, shadows_enabled: true, ..default() }, ..default() }, VolumetricLight, ));<br> commands.spawn(( SpatialBundle { visibility: Visibility::Visible, transform: Transform::from_xyz(0.0, 0.0, 0.0).with_scale(Vec3::splat(3.0)), ..default() }, FogVolume { density_texture: Some(assets.load("volumes/fog_noise.ktx2")), density_texture_offset: Vec3::new(0.0, 0.0, 0.4), scattering: 1.0, ..default() }, )); } </pre> </details>
2024-08-24 00:56:39 +00:00
};
Allow fog density texture to be scrolled over time with an offset (#14868) # Objective - The goal of this PR is to make it possible to move the density texture of a `FogVolume` over time in order to create dynamic effects like fog moving in the wind. - You could theoretically move the `FogVolume` itself, but this is not ideal, because the `FogVolume` AABB would eventually leave the area. If you want an area to remain foggy while also creating the impression that the fog is moving in the wind, a scrolling density texture is a better solution. ## Solution - The PR adds a `density_texture_offset` field to the `FogVolume` component. This offset is in the UVW coordinates of the density texture, meaning that a value of `(0.5, 0.0, 0.0)` moves the 3d texture by half along the x-axis. - Values above 1.0 are wrapped, a 1.5 offset is the same as a 0.5 offset. This makes it so that the density texture wraps around on the other side, meaning that a repeating 3d noise texture can seamlessly scroll forever. It also makes it easy to move the density texture over time by simply increasing the offset every frame. ## Testing - A `scrolling_fog` example has been added to demonstrate the feature. It uses the offset to scroll a repeating 3d noise density texture to create the impression of fog moving in the wind. - The camera is looking at a pillar with the sun peaking behind it. This highlights the effect the changing density has on the volumetric lighting interactions. - Temporal anti-aliasing combined with the `jitter` option of `VolumetricFogSettings` is used to improve the quality of the effect. --- ## Showcase https://github.com/user-attachments/assets/3aa50ebd-771c-4c99-ab5d-255c0c3be1a8
2024-08-22 19:43:14 +00:00
/// Initializes the example.
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
title: "Bevy Scrolling Fog".into(),
..default()
}),
..default()
}))
.insert_resource(DirectionalLightShadowMap { size: 4096 })
.add_plugins(TemporalAntiAliasPlugin)
.add_systems(Startup, setup)
.add_systems(Update, scroll_fog)
.run();
}
/// Spawns all entities into the scene.
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
assets: Res<AssetServer>,
) {
Rename rendering components for improved consistency and clarity (#15035) # Objective The names of numerous rendering components in Bevy are inconsistent and a bit confusing. Relevant names include: - `AutoExposureSettings` - `AutoExposureSettingsUniform` - `BloomSettings` - `BloomUniform` (no `Settings`) - `BloomPrefilterSettings` - `ChromaticAberration` (no `Settings`) - `ContrastAdaptiveSharpeningSettings` - `DepthOfFieldSettings` - `DepthOfFieldUniform` (no `Settings`) - `FogSettings` - `SmaaSettings`, `Fxaa`, `TemporalAntiAliasSettings` (really inconsistent??) - `ScreenSpaceAmbientOcclusionSettings` - `ScreenSpaceReflectionsSettings` - `VolumetricFogSettings` Firstly, there's a lot of inconsistency between `Foo`/`FooSettings` and `FooUniform`/`FooSettingsUniform` and whether names are abbreviated or not. Secondly, the `Settings` post-fix seems unnecessary and a bit confusing semantically, since it makes it seem like the component is mostly just auxiliary configuration instead of the core *thing* that actually enables the feature. This will be an even bigger problem once bundles like `TemporalAntiAliasBundle` are deprecated in favor of required components, as users will expect a component named `TemporalAntiAlias` (or similar), not `TemporalAntiAliasSettings`. ## Solution Drop the `Settings` post-fix from the component names, and change some names to be more consistent. - `AutoExposure` - `AutoExposureUniform` - `Bloom` - `BloomUniform` - `BloomPrefilter` - `ChromaticAberration` - `ContrastAdaptiveSharpening` - `DepthOfField` - `DepthOfFieldUniform` - `DistanceFog` - `Smaa`, `Fxaa`, `TemporalAntiAliasing` (note: we might want to change to `Taa`, see "Discussion") - `ScreenSpaceAmbientOcclusion` - `ScreenSpaceReflections` - `VolumetricFog` I kept the old names as deprecated type aliases to make migration a bit less painful for users. We should remove them after the next release. (And let me know if I should just... not add them at all) I also added some very basic docs for a few types where they were missing, like on `Fxaa` and `DepthOfField`. ## Discussion - `TemporalAntiAliasing` is still inconsistent with `Smaa` and `Fxaa`. Consensus [on Discord](https://discord.com/channels/691052431525675048/743663924229963868/1280601167209955431) seemed to be that renaming to `Taa` would probably be fine, but I think it's a bit more controversial, and it would've required renaming a lot of related types like `TemporalAntiAliasNode`, `TemporalAntiAliasBundle`, and `TemporalAntiAliasPlugin`, so I think it's better to leave to a follow-up. - I think `Fog` should probably have a more specific name like `DistanceFog` considering it seems to be distinct from `VolumetricFog`. ~~This should probably be done in a follow-up though, so I just removed the `Settings` post-fix for now.~~ (done) --- ## Migration Guide Many rendering components have been renamed for improved consistency and clarity. - `AutoExposureSettings` → `AutoExposure` - `BloomSettings` → `Bloom` - `BloomPrefilterSettings` → `BloomPrefilter` - `ContrastAdaptiveSharpeningSettings` → `ContrastAdaptiveSharpening` - `DepthOfFieldSettings` → `DepthOfField` - `FogSettings` → `DistanceFog` - `SmaaSettings` → `Smaa` - `TemporalAntiAliasSettings` → `TemporalAntiAliasing` - `ScreenSpaceAmbientOcclusionSettings` → `ScreenSpaceAmbientOcclusion` - `ScreenSpaceReflectionsSettings` → `ScreenSpaceReflections` - `VolumetricFogSettings` → `VolumetricFog` --------- Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-09-10 01:11:46 +00:00
// Spawn camera with temporal anti-aliasing and a VolumetricFog configuration.
Allow fog density texture to be scrolled over time with an offset (#14868) # Objective - The goal of this PR is to make it possible to move the density texture of a `FogVolume` over time in order to create dynamic effects like fog moving in the wind. - You could theoretically move the `FogVolume` itself, but this is not ideal, because the `FogVolume` AABB would eventually leave the area. If you want an area to remain foggy while also creating the impression that the fog is moving in the wind, a scrolling density texture is a better solution. ## Solution - The PR adds a `density_texture_offset` field to the `FogVolume` component. This offset is in the UVW coordinates of the density texture, meaning that a value of `(0.5, 0.0, 0.0)` moves the 3d texture by half along the x-axis. - Values above 1.0 are wrapped, a 1.5 offset is the same as a 0.5 offset. This makes it so that the density texture wraps around on the other side, meaning that a repeating 3d noise texture can seamlessly scroll forever. It also makes it easy to move the density texture over time by simply increasing the offset every frame. ## Testing - A `scrolling_fog` example has been added to demonstrate the feature. It uses the offset to scroll a repeating 3d noise density texture to create the impression of fog moving in the wind. - The camera is looking at a pillar with the sun peaking behind it. This highlights the effect the changing density has on the volumetric lighting interactions. - Temporal anti-aliasing combined with the `jitter` option of `VolumetricFogSettings` is used to improve the quality of the effect. --- ## Showcase https://github.com/user-attachments/assets/3aa50ebd-771c-4c99-ab5d-255c0c3be1a8
2024-08-22 19:43:14 +00:00
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(0.0, 2.0, 0.0)
.looking_at(Vec3::new(-5.0, 3.5, -6.0), Vec3::Y),
camera: Camera {
hdr: true,
..default()
},
msaa: Msaa::Off,
..default()
},
TemporalAntiAliasBundle::default(),
Rename rendering components for improved consistency and clarity (#15035) # Objective The names of numerous rendering components in Bevy are inconsistent and a bit confusing. Relevant names include: - `AutoExposureSettings` - `AutoExposureSettingsUniform` - `BloomSettings` - `BloomUniform` (no `Settings`) - `BloomPrefilterSettings` - `ChromaticAberration` (no `Settings`) - `ContrastAdaptiveSharpeningSettings` - `DepthOfFieldSettings` - `DepthOfFieldUniform` (no `Settings`) - `FogSettings` - `SmaaSettings`, `Fxaa`, `TemporalAntiAliasSettings` (really inconsistent??) - `ScreenSpaceAmbientOcclusionSettings` - `ScreenSpaceReflectionsSettings` - `VolumetricFogSettings` Firstly, there's a lot of inconsistency between `Foo`/`FooSettings` and `FooUniform`/`FooSettingsUniform` and whether names are abbreviated or not. Secondly, the `Settings` post-fix seems unnecessary and a bit confusing semantically, since it makes it seem like the component is mostly just auxiliary configuration instead of the core *thing* that actually enables the feature. This will be an even bigger problem once bundles like `TemporalAntiAliasBundle` are deprecated in favor of required components, as users will expect a component named `TemporalAntiAlias` (or similar), not `TemporalAntiAliasSettings`. ## Solution Drop the `Settings` post-fix from the component names, and change some names to be more consistent. - `AutoExposure` - `AutoExposureUniform` - `Bloom` - `BloomUniform` - `BloomPrefilter` - `ChromaticAberration` - `ContrastAdaptiveSharpening` - `DepthOfField` - `DepthOfFieldUniform` - `DistanceFog` - `Smaa`, `Fxaa`, `TemporalAntiAliasing` (note: we might want to change to `Taa`, see "Discussion") - `ScreenSpaceAmbientOcclusion` - `ScreenSpaceReflections` - `VolumetricFog` I kept the old names as deprecated type aliases to make migration a bit less painful for users. We should remove them after the next release. (And let me know if I should just... not add them at all) I also added some very basic docs for a few types where they were missing, like on `Fxaa` and `DepthOfField`. ## Discussion - `TemporalAntiAliasing` is still inconsistent with `Smaa` and `Fxaa`. Consensus [on Discord](https://discord.com/channels/691052431525675048/743663924229963868/1280601167209955431) seemed to be that renaming to `Taa` would probably be fine, but I think it's a bit more controversial, and it would've required renaming a lot of related types like `TemporalAntiAliasNode`, `TemporalAntiAliasBundle`, and `TemporalAntiAliasPlugin`, so I think it's better to leave to a follow-up. - I think `Fog` should probably have a more specific name like `DistanceFog` considering it seems to be distinct from `VolumetricFog`. ~~This should probably be done in a follow-up though, so I just removed the `Settings` post-fix for now.~~ (done) --- ## Migration Guide Many rendering components have been renamed for improved consistency and clarity. - `AutoExposureSettings` → `AutoExposure` - `BloomSettings` → `Bloom` - `BloomPrefilterSettings` → `BloomPrefilter` - `ContrastAdaptiveSharpeningSettings` → `ContrastAdaptiveSharpening` - `DepthOfFieldSettings` → `DepthOfField` - `FogSettings` → `DistanceFog` - `SmaaSettings` → `Smaa` - `TemporalAntiAliasSettings` → `TemporalAntiAliasing` - `ScreenSpaceAmbientOcclusionSettings` → `ScreenSpaceAmbientOcclusion` - `ScreenSpaceReflectionsSettings` → `ScreenSpaceReflections` - `VolumetricFogSettings` → `VolumetricFog` --------- Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-09-10 01:11:46 +00:00
Bloom::default(),
VolumetricFog {
Allow fog density texture to be scrolled over time with an offset (#14868) # Objective - The goal of this PR is to make it possible to move the density texture of a `FogVolume` over time in order to create dynamic effects like fog moving in the wind. - You could theoretically move the `FogVolume` itself, but this is not ideal, because the `FogVolume` AABB would eventually leave the area. If you want an area to remain foggy while also creating the impression that the fog is moving in the wind, a scrolling density texture is a better solution. ## Solution - The PR adds a `density_texture_offset` field to the `FogVolume` component. This offset is in the UVW coordinates of the density texture, meaning that a value of `(0.5, 0.0, 0.0)` moves the 3d texture by half along the x-axis. - Values above 1.0 are wrapped, a 1.5 offset is the same as a 0.5 offset. This makes it so that the density texture wraps around on the other side, meaning that a repeating 3d noise texture can seamlessly scroll forever. It also makes it easy to move the density texture over time by simply increasing the offset every frame. ## Testing - A `scrolling_fog` example has been added to demonstrate the feature. It uses the offset to scroll a repeating 3d noise density texture to create the impression of fog moving in the wind. - The camera is looking at a pillar with the sun peaking behind it. This highlights the effect the changing density has on the volumetric lighting interactions. - Temporal anti-aliasing combined with the `jitter` option of `VolumetricFogSettings` is used to improve the quality of the effect. --- ## Showcase https://github.com/user-attachments/assets/3aa50ebd-771c-4c99-ab5d-255c0c3be1a8
2024-08-22 19:43:14 +00:00
ambient_intensity: 0.0,
jitter: 0.5,
..default()
},
));
// Spawn a directional light shining at the camera with the VolumetricLight component.
commands.spawn((
DirectionalLightBundle {
transform: Transform::from_xyz(-5.0, 5.0, -7.0)
.looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y),
directional_light: DirectionalLight {
shadows_enabled: true,
..default()
},
..default()
},
VolumetricLight,
));
// Spawn ground mesh.
commands.spawn(PbrBundle {
transform: Transform::from_xyz(0.0, -0.5, 0.0),
mesh: meshes.add(Cuboid::new(64.0, 1.0, 64.0)),
material: materials.add(StandardMaterial {
base_color: Color::BLACK,
perceptual_roughness: 1.0,
..default()
}),
..default()
});
// Spawn pillar standing between the camera and the sun.
commands.spawn(PbrBundle {
transform: Transform::from_xyz(-10.0, 4.5, -11.0),
mesh: meshes.add(Cuboid::new(2.0, 9.0, 2.0)),
material: materials.add(Color::BLACK),
..default()
});
Fix fog density texture offset seam (#14900) # Objective - There is a flaw in the implementation of `FogVolume`'s `density_texture_offset` from #14868. Because of the way I am wrapping the UVW coordinates in the volumetric fog shader, a seam is visible when the 3d texture is wrapping around from one side to the other: ![density_texture_offset_seam](https://github.com/user-attachments/assets/89527ef2-5e1b-4b90-8e73-7a3e607697d4) ## Solution - This PR fixes the issue by removing the wrapping from the shader and instead leaving it to the user to configure the 3d noise texture to use `ImageAddressMode::Repeat` if they want it to repeat. Using `ImageAddressMode::Repeat` is the proper solution to avoid the obvious seam: ![density_texture_seam_fixed](https://github.com/user-attachments/assets/06e871a6-2db1-4501-b425-4141605f9b26) - The sampler cannot be implicitly configured to use `ImageAddressMode::Repeat` because that's not always desirable. For example, the `fog_volumes` example wouldn't work properly because the texture from the edges of the volume would overflow to the other sides, which would be bad in this instance (but it's good in the case of the `scrolling_fog` example). So leaving it to the user to decide on their own whether they want the density texture to repeat seems to be the best solution. ## Testing - The `scrolling_fog` example still looks the same, it was just changed to explicitly declare that the density texture should be repeating when loading the asset. The `fog_volumes` example is unaffected. <details> <summary>Minimal reproduction example on current main</summary> <pre> use bevy::core_pipeline::experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin}; use bevy::pbr::{FogVolume, VolumetricFogSettings, VolumetricLight}; use bevy::prelude::*;<br> fn main() { App::new() .add_plugins((DefaultPlugins, TemporalAntiAliasPlugin)) .add_systems(Startup, setup) .run(); }<br> fn setup(mut commands: Commands, assets: Res&lt;AssetServer&gt;) { commands.spawn(( Camera3dBundle { transform: Transform::from_xyz(3.5, -1.0, 0.4) .looking_at(Vec3::new(0.0, 0.0, 0.4), Vec3::Y), msaa: Msaa::Off, ..default() }, TemporalAntiAliasBundle::default(), VolumetricFogSettings { ambient_intensity: 0.0, jitter: 0.5, ..default() }, ));<br> commands.spawn(( DirectionalLightBundle { transform: Transform::from_xyz(-6.0, 5.0, -9.0) .looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), directional_light: DirectionalLight { illuminance: 32_000.0, shadows_enabled: true, ..default() }, ..default() }, VolumetricLight, ));<br> commands.spawn(( SpatialBundle { visibility: Visibility::Visible, transform: Transform::from_xyz(0.0, 0.0, 0.0).with_scale(Vec3::splat(3.0)), ..default() }, FogVolume { density_texture: Some(assets.load("volumes/fog_noise.ktx2")), density_texture_offset: Vec3::new(0.0, 0.0, 0.4), scattering: 1.0, ..default() }, )); } </pre> </details>
2024-08-24 00:56:39 +00:00
// Load a repeating 3d noise texture. Make sure to set ImageAddressMode to Repeat
// so that the texture wraps around as the density texture offset is moved along.
// Also set ImageFilterMode to Linear so that the fog isn't pixelated.
let noise_texture = assets.load_with_settings("volumes/fog_noise.ktx2", |settings: &mut _| {
*settings = ImageLoaderSettings {
sampler: ImageSampler::Descriptor(ImageSamplerDescriptor {
address_mode_u: ImageAddressMode::Repeat,
address_mode_v: ImageAddressMode::Repeat,
address_mode_w: ImageAddressMode::Repeat,
mag_filter: ImageFilterMode::Linear,
min_filter: ImageFilterMode::Linear,
mipmap_filter: ImageFilterMode::Linear,
..default()
}),
..default()
}
});
// Spawn a FogVolume and use the repeating noise texture as its density texture.
Allow fog density texture to be scrolled over time with an offset (#14868) # Objective - The goal of this PR is to make it possible to move the density texture of a `FogVolume` over time in order to create dynamic effects like fog moving in the wind. - You could theoretically move the `FogVolume` itself, but this is not ideal, because the `FogVolume` AABB would eventually leave the area. If you want an area to remain foggy while also creating the impression that the fog is moving in the wind, a scrolling density texture is a better solution. ## Solution - The PR adds a `density_texture_offset` field to the `FogVolume` component. This offset is in the UVW coordinates of the density texture, meaning that a value of `(0.5, 0.0, 0.0)` moves the 3d texture by half along the x-axis. - Values above 1.0 are wrapped, a 1.5 offset is the same as a 0.5 offset. This makes it so that the density texture wraps around on the other side, meaning that a repeating 3d noise texture can seamlessly scroll forever. It also makes it easy to move the density texture over time by simply increasing the offset every frame. ## Testing - A `scrolling_fog` example has been added to demonstrate the feature. It uses the offset to scroll a repeating 3d noise density texture to create the impression of fog moving in the wind. - The camera is looking at a pillar with the sun peaking behind it. This highlights the effect the changing density has on the volumetric lighting interactions. - Temporal anti-aliasing combined with the `jitter` option of `VolumetricFogSettings` is used to improve the quality of the effect. --- ## Showcase https://github.com/user-attachments/assets/3aa50ebd-771c-4c99-ab5d-255c0c3be1a8
2024-08-22 19:43:14 +00:00
commands.spawn((
SpatialBundle {
visibility: Visibility::Visible,
transform: Transform::from_xyz(0.0, 32.0, 0.0).with_scale(Vec3::splat(64.0)),
..default()
},
FogVolume {
Fix fog density texture offset seam (#14900) # Objective - There is a flaw in the implementation of `FogVolume`'s `density_texture_offset` from #14868. Because of the way I am wrapping the UVW coordinates in the volumetric fog shader, a seam is visible when the 3d texture is wrapping around from one side to the other: ![density_texture_offset_seam](https://github.com/user-attachments/assets/89527ef2-5e1b-4b90-8e73-7a3e607697d4) ## Solution - This PR fixes the issue by removing the wrapping from the shader and instead leaving it to the user to configure the 3d noise texture to use `ImageAddressMode::Repeat` if they want it to repeat. Using `ImageAddressMode::Repeat` is the proper solution to avoid the obvious seam: ![density_texture_seam_fixed](https://github.com/user-attachments/assets/06e871a6-2db1-4501-b425-4141605f9b26) - The sampler cannot be implicitly configured to use `ImageAddressMode::Repeat` because that's not always desirable. For example, the `fog_volumes` example wouldn't work properly because the texture from the edges of the volume would overflow to the other sides, which would be bad in this instance (but it's good in the case of the `scrolling_fog` example). So leaving it to the user to decide on their own whether they want the density texture to repeat seems to be the best solution. ## Testing - The `scrolling_fog` example still looks the same, it was just changed to explicitly declare that the density texture should be repeating when loading the asset. The `fog_volumes` example is unaffected. <details> <summary>Minimal reproduction example on current main</summary> <pre> use bevy::core_pipeline::experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin}; use bevy::pbr::{FogVolume, VolumetricFogSettings, VolumetricLight}; use bevy::prelude::*;<br> fn main() { App::new() .add_plugins((DefaultPlugins, TemporalAntiAliasPlugin)) .add_systems(Startup, setup) .run(); }<br> fn setup(mut commands: Commands, assets: Res&lt;AssetServer&gt;) { commands.spawn(( Camera3dBundle { transform: Transform::from_xyz(3.5, -1.0, 0.4) .looking_at(Vec3::new(0.0, 0.0, 0.4), Vec3::Y), msaa: Msaa::Off, ..default() }, TemporalAntiAliasBundle::default(), VolumetricFogSettings { ambient_intensity: 0.0, jitter: 0.5, ..default() }, ));<br> commands.spawn(( DirectionalLightBundle { transform: Transform::from_xyz(-6.0, 5.0, -9.0) .looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), directional_light: DirectionalLight { illuminance: 32_000.0, shadows_enabled: true, ..default() }, ..default() }, VolumetricLight, ));<br> commands.spawn(( SpatialBundle { visibility: Visibility::Visible, transform: Transform::from_xyz(0.0, 0.0, 0.0).with_scale(Vec3::splat(3.0)), ..default() }, FogVolume { density_texture: Some(assets.load("volumes/fog_noise.ktx2")), density_texture_offset: Vec3::new(0.0, 0.0, 0.4), scattering: 1.0, ..default() }, )); } </pre> </details>
2024-08-24 00:56:39 +00:00
density_texture: Some(noise_texture),
Allow fog density texture to be scrolled over time with an offset (#14868) # Objective - The goal of this PR is to make it possible to move the density texture of a `FogVolume` over time in order to create dynamic effects like fog moving in the wind. - You could theoretically move the `FogVolume` itself, but this is not ideal, because the `FogVolume` AABB would eventually leave the area. If you want an area to remain foggy while also creating the impression that the fog is moving in the wind, a scrolling density texture is a better solution. ## Solution - The PR adds a `density_texture_offset` field to the `FogVolume` component. This offset is in the UVW coordinates of the density texture, meaning that a value of `(0.5, 0.0, 0.0)` moves the 3d texture by half along the x-axis. - Values above 1.0 are wrapped, a 1.5 offset is the same as a 0.5 offset. This makes it so that the density texture wraps around on the other side, meaning that a repeating 3d noise texture can seamlessly scroll forever. It also makes it easy to move the density texture over time by simply increasing the offset every frame. ## Testing - A `scrolling_fog` example has been added to demonstrate the feature. It uses the offset to scroll a repeating 3d noise density texture to create the impression of fog moving in the wind. - The camera is looking at a pillar with the sun peaking behind it. This highlights the effect the changing density has on the volumetric lighting interactions. - Temporal anti-aliasing combined with the `jitter` option of `VolumetricFogSettings` is used to improve the quality of the effect. --- ## Showcase https://github.com/user-attachments/assets/3aa50ebd-771c-4c99-ab5d-255c0c3be1a8
2024-08-22 19:43:14 +00:00
density_factor: 0.05,
..default()
},
));
}
/// Moves fog density texture offset every frame.
fn scroll_fog(time: Res<Time>, mut query: Query<&mut FogVolume>) {
for mut fog_volume in query.iter_mut() {
fog_volume.density_texture_offset += Vec3::new(0.0, 0.0, 0.04) * time.delta_seconds();
}
}