bevy/crates/bevy_pbr/src/render/fog.rs
Joona Aalto afbbbd7335
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

149 lines
5.6 KiB
Rust

use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, Handle};
use bevy_color::{ColorToComponents, LinearRgba};
use bevy_ecs::prelude::*;
use bevy_math::{Vec3, Vec4};
use bevy_render::{
extract_component::ExtractComponentPlugin,
render_resource::{DynamicUniformBuffer, Shader, ShaderType},
renderer::{RenderDevice, RenderQueue},
view::ExtractedView,
Render, RenderApp, RenderSet,
};
use crate::{DistanceFog, FogFalloff};
/// The GPU-side representation of the fog configuration that's sent as a uniform to the shader
#[derive(Copy, Clone, ShaderType, Default, Debug)]
pub struct GpuFog {
/// Fog color
base_color: Vec4,
/// The color used for the fog where the view direction aligns with directional lights
directional_light_color: Vec4,
/// Allocated differently depending on fog mode.
/// See `mesh_view_types.wgsl` for a detailed explanation
be: Vec3,
/// The exponent applied to the directional light alignment calculation
directional_light_exponent: f32,
/// Allocated differently depending on fog mode.
/// See `mesh_view_types.wgsl` for a detailed explanation
bi: Vec3,
/// Unsigned int representation of the active fog falloff mode
mode: u32,
}
// Important: These must be kept in sync with `mesh_view_types.wgsl`
const GPU_FOG_MODE_OFF: u32 = 0;
const GPU_FOG_MODE_LINEAR: u32 = 1;
const GPU_FOG_MODE_EXPONENTIAL: u32 = 2;
const GPU_FOG_MODE_EXPONENTIAL_SQUARED: u32 = 3;
const GPU_FOG_MODE_ATMOSPHERIC: u32 = 4;
/// Metadata for fog
#[derive(Default, Resource)]
pub struct FogMeta {
pub gpu_fogs: DynamicUniformBuffer<GpuFog>,
}
/// Prepares fog metadata and writes the fog-related uniform buffers to the GPU
pub fn prepare_fog(
mut commands: Commands,
render_device: Res<RenderDevice>,
render_queue: Res<RenderQueue>,
mut fog_meta: ResMut<FogMeta>,
views: Query<(Entity, Option<&DistanceFog>), With<ExtractedView>>,
) {
let views_iter = views.iter();
let view_count = views_iter.len();
let Some(mut writer) = fog_meta
.gpu_fogs
.get_writer(view_count, &render_device, &render_queue)
else {
return;
};
for (entity, fog) in views_iter {
let gpu_fog = if let Some(fog) = fog {
match &fog.falloff {
FogFalloff::Linear { start, end } => GpuFog {
mode: GPU_FOG_MODE_LINEAR,
base_color: LinearRgba::from(fog.color).to_vec4(),
directional_light_color: LinearRgba::from(fog.directional_light_color)
.to_vec4(),
directional_light_exponent: fog.directional_light_exponent,
be: Vec3::new(*start, *end, 0.0),
..Default::default()
},
FogFalloff::Exponential { density } => GpuFog {
mode: GPU_FOG_MODE_EXPONENTIAL,
base_color: LinearRgba::from(fog.color).to_vec4(),
directional_light_color: LinearRgba::from(fog.directional_light_color)
.to_vec4(),
directional_light_exponent: fog.directional_light_exponent,
be: Vec3::new(*density, 0.0, 0.0),
..Default::default()
},
FogFalloff::ExponentialSquared { density } => GpuFog {
mode: GPU_FOG_MODE_EXPONENTIAL_SQUARED,
base_color: LinearRgba::from(fog.color).to_vec4(),
directional_light_color: LinearRgba::from(fog.directional_light_color)
.to_vec4(),
directional_light_exponent: fog.directional_light_exponent,
be: Vec3::new(*density, 0.0, 0.0),
..Default::default()
},
FogFalloff::Atmospheric {
extinction,
inscattering,
} => GpuFog {
mode: GPU_FOG_MODE_ATMOSPHERIC,
base_color: LinearRgba::from(fog.color).to_vec4(),
directional_light_color: LinearRgba::from(fog.directional_light_color)
.to_vec4(),
directional_light_exponent: fog.directional_light_exponent,
be: *extinction,
bi: *inscattering,
},
}
} else {
// If no fog is added to a camera, by default it's off
GpuFog {
mode: GPU_FOG_MODE_OFF,
..Default::default()
}
};
// This is later read by `SetMeshViewBindGroup<I>`
commands.entity(entity).insert(ViewFogUniformOffset {
offset: writer.write(&gpu_fog),
});
}
}
/// Inserted on each `Entity` with an `ExtractedView` to keep track of its offset
/// in the `gpu_fogs` `DynamicUniformBuffer` within `FogMeta`
#[derive(Component)]
pub struct ViewFogUniformOffset {
pub offset: u32,
}
/// Handle for the fog WGSL Shader internal asset
pub const FOG_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(4913569193382610166);
/// A plugin that consolidates fog extraction, preparation and related resources/assets
pub struct FogPlugin;
impl Plugin for FogPlugin {
fn build(&self, app: &mut App) {
load_internal_asset!(app, FOG_SHADER_HANDLE, "fog.wgsl", Shader::from_wgsl);
app.register_type::<DistanceFog>();
app.add_plugins(ExtractComponentPlugin::<DistanceFog>::default());
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.init_resource::<FogMeta>()
.add_systems(Render, prepare_fog.in_set(RenderSet::PrepareResources));
}
}
}