# 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>
149 lines
5.6 KiB
Rust
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));
|
|
}
|
|
}
|
|
}
|