mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
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>
This commit is contained in:
parent
74ccab947d
commit
afbbbd7335
49 changed files with 449 additions and 411 deletions
|
@ -6,8 +6,8 @@ use bevy_render::{
|
|||
};
|
||||
use bevy_utils::{Entry, HashMap};
|
||||
|
||||
use super::pipeline::AutoExposureSettingsUniform;
|
||||
use super::AutoExposureSettings;
|
||||
use super::pipeline::AutoExposureUniform;
|
||||
use super::AutoExposure;
|
||||
|
||||
#[derive(Resource, Default)]
|
||||
pub(super) struct AutoExposureBuffers {
|
||||
|
@ -16,19 +16,19 @@ pub(super) struct AutoExposureBuffers {
|
|||
|
||||
pub(super) struct AutoExposureBuffer {
|
||||
pub(super) state: StorageBuffer<f32>,
|
||||
pub(super) settings: UniformBuffer<AutoExposureSettingsUniform>,
|
||||
pub(super) settings: UniformBuffer<AutoExposureUniform>,
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
pub(super) struct ExtractedStateBuffers {
|
||||
changed: Vec<(Entity, AutoExposureSettings)>,
|
||||
changed: Vec<(Entity, AutoExposure)>,
|
||||
removed: Vec<Entity>,
|
||||
}
|
||||
|
||||
pub(super) fn extract_buffers(
|
||||
mut commands: Commands,
|
||||
changed: Extract<Query<(Entity, &AutoExposureSettings), Changed<AutoExposureSettings>>>,
|
||||
mut removed: Extract<RemovedComponents<AutoExposureSettings>>,
|
||||
changed: Extract<Query<(Entity, &AutoExposure), Changed<AutoExposure>>>,
|
||||
mut removed: Extract<RemovedComponents<AutoExposure>>,
|
||||
) {
|
||||
commands.insert_resource(ExtractedStateBuffers {
|
||||
changed: changed
|
||||
|
@ -50,7 +50,7 @@ pub(super) fn prepare_buffers(
|
|||
let (low_percent, high_percent) = settings.filter.into_inner();
|
||||
let initial_state = 0.0f32.clamp(min_log_lum, max_log_lum);
|
||||
|
||||
let settings = AutoExposureSettingsUniform {
|
||||
let settings = AutoExposureUniform {
|
||||
min_log_lum,
|
||||
inv_log_lum_range: 1.0 / (max_log_lum - min_log_lum),
|
||||
log_lum_range: max_log_lum - min_log_lum,
|
||||
|
|
|
@ -26,14 +26,15 @@ use node::AutoExposureNode;
|
|||
use pipeline::{
|
||||
AutoExposurePass, AutoExposurePipeline, ViewAutoExposurePipeline, METERING_SHADER_HANDLE,
|
||||
};
|
||||
pub use settings::AutoExposureSettings;
|
||||
#[allow(deprecated)]
|
||||
pub use settings::{AutoExposure, AutoExposureSettings};
|
||||
|
||||
use crate::auto_exposure::compensation_curve::GpuAutoExposureCompensationCurve;
|
||||
use crate::core_3d::graph::{Core3d, Node3d};
|
||||
|
||||
/// Plugin for the auto exposure feature.
|
||||
///
|
||||
/// See [`AutoExposureSettings`] for more details.
|
||||
/// See [`AutoExposure`] for more details.
|
||||
pub struct AutoExposurePlugin;
|
||||
|
||||
#[derive(Resource)]
|
||||
|
@ -58,8 +59,8 @@ impl Plugin for AutoExposurePlugin {
|
|||
.resource_mut::<Assets<AutoExposureCompensationCurve>>()
|
||||
.insert(&Handle::default(), AutoExposureCompensationCurve::default());
|
||||
|
||||
app.register_type::<AutoExposureSettings>();
|
||||
app.add_plugins(ExtractComponentPlugin::<AutoExposureSettings>::default());
|
||||
app.register_type::<AutoExposure>();
|
||||
app.add_plugins(ExtractComponentPlugin::<AutoExposure>::default());
|
||||
|
||||
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
|
||||
return;
|
||||
|
@ -113,9 +114,9 @@ fn queue_view_auto_exposure_pipelines(
|
|||
pipeline_cache: Res<PipelineCache>,
|
||||
mut compute_pipelines: ResMut<SpecializedComputePipelines<AutoExposurePipeline>>,
|
||||
pipeline: Res<AutoExposurePipeline>,
|
||||
view_targets: Query<(Entity, &AutoExposureSettings)>,
|
||||
view_targets: Query<(Entity, &AutoExposure)>,
|
||||
) {
|
||||
for (entity, settings) in view_targets.iter() {
|
||||
for (entity, auto_exposure) in view_targets.iter() {
|
||||
let histogram_pipeline =
|
||||
compute_pipelines.specialize(&pipeline_cache, &pipeline, AutoExposurePass::Histogram);
|
||||
let average_pipeline =
|
||||
|
@ -124,8 +125,8 @@ fn queue_view_auto_exposure_pipelines(
|
|||
commands.entity(entity).insert(ViewAutoExposurePipeline {
|
||||
histogram_pipeline,
|
||||
mean_luminance_pipeline: average_pipeline,
|
||||
compensation_curve: settings.compensation_curve.clone(),
|
||||
metering_mask: settings.metering_mask.clone(),
|
||||
compensation_curve: auto_exposure.compensation_curve.clone(),
|
||||
metering_mask: auto_exposure.metering_mask.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ pub struct ViewAutoExposurePipeline {
|
|||
}
|
||||
|
||||
#[derive(ShaderType, Clone, Copy)]
|
||||
pub struct AutoExposureSettingsUniform {
|
||||
pub struct AutoExposureUniform {
|
||||
pub(super) min_log_lum: f32,
|
||||
pub(super) inv_log_lum_range: f32,
|
||||
pub(super) log_lum_range: f32,
|
||||
|
@ -59,7 +59,7 @@ impl FromWorld for AutoExposurePipeline {
|
|||
ShaderStages::COMPUTE,
|
||||
(
|
||||
uniform_buffer::<GlobalsUniform>(false),
|
||||
uniform_buffer::<AutoExposureSettingsUniform>(false),
|
||||
uniform_buffer::<AutoExposureUniform>(false),
|
||||
texture_2d(TextureSampleType::Float { filterable: false }),
|
||||
texture_2d(TextureSampleType::Float { filterable: false }),
|
||||
texture_1d(TextureSampleType::Float { filterable: false }),
|
||||
|
|
|
@ -25,7 +25,7 @@ use bevy_utils::default;
|
|||
///
|
||||
#[derive(Component, Clone, Reflect, ExtractComponent)]
|
||||
#[reflect(Component)]
|
||||
pub struct AutoExposureSettings {
|
||||
pub struct AutoExposure {
|
||||
/// The range of exposure values for the histogram.
|
||||
///
|
||||
/// Pixel values below this range will be ignored, and pixel values above this range will be
|
||||
|
@ -88,7 +88,10 @@ pub struct AutoExposureSettings {
|
|||
pub compensation_curve: Handle<AutoExposureCompensationCurve>,
|
||||
}
|
||||
|
||||
impl Default for AutoExposureSettings {
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `AutoExposure`")]
|
||||
pub type AutoExposureSettings = AutoExposure;
|
||||
|
||||
impl Default for AutoExposure {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
range: -8.0..=8.0,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::{BloomSettings, BLOOM_SHADER_HANDLE, BLOOM_TEXTURE_FORMAT};
|
||||
use super::{Bloom, BLOOM_SHADER_HANDLE, BLOOM_TEXTURE_FORMAT};
|
||||
use crate::fullscreen_vertex_shader::fullscreen_shader_vertex_state;
|
||||
use bevy_ecs::{
|
||||
prelude::{Component, Entity},
|
||||
|
@ -33,7 +33,7 @@ pub struct BloomDownsamplingPipelineKeys {
|
|||
first_downsample: bool,
|
||||
}
|
||||
|
||||
/// The uniform struct extracted from [`BloomSettings`] attached to a Camera.
|
||||
/// The uniform struct extracted from [`Bloom`] attached to a Camera.
|
||||
/// Will be available for use in the Bloom shader.
|
||||
#[derive(Component, ShaderType, Clone)]
|
||||
pub struct BloomUniforms {
|
||||
|
@ -136,10 +136,10 @@ pub fn prepare_downsampling_pipeline(
|
|||
pipeline_cache: Res<PipelineCache>,
|
||||
mut pipelines: ResMut<SpecializedRenderPipelines<BloomDownsamplingPipeline>>,
|
||||
pipeline: Res<BloomDownsamplingPipeline>,
|
||||
views: Query<(Entity, &BloomSettings)>,
|
||||
views: Query<(Entity, &Bloom)>,
|
||||
) {
|
||||
for (entity, settings) in &views {
|
||||
let prefilter = settings.prefilter_settings.threshold > 0.0;
|
||||
for (entity, bloom) in &views {
|
||||
let prefilter = bloom.prefilter.threshold > 0.0;
|
||||
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
|
|
|
@ -3,7 +3,10 @@ mod settings;
|
|||
mod upsampling_pipeline;
|
||||
|
||||
use bevy_color::{Gray, LinearRgba};
|
||||
pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings};
|
||||
#[allow(deprecated)]
|
||||
pub use settings::{
|
||||
Bloom, BloomCompositeMode, BloomPrefilter, BloomPrefilterSettings, BloomSettings,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
core_2d::graph::{Core2d, Node2d},
|
||||
|
@ -44,11 +47,11 @@ impl Plugin for BloomPlugin {
|
|||
fn build(&self, app: &mut App) {
|
||||
load_internal_asset!(app, BLOOM_SHADER_HANDLE, "bloom.wgsl", Shader::from_wgsl);
|
||||
|
||||
app.register_type::<BloomSettings>();
|
||||
app.register_type::<BloomPrefilterSettings>();
|
||||
app.register_type::<Bloom>();
|
||||
app.register_type::<BloomPrefilter>();
|
||||
app.register_type::<BloomCompositeMode>();
|
||||
app.add_plugins((
|
||||
ExtractComponentPlugin::<BloomSettings>::default(),
|
||||
ExtractComponentPlugin::<Bloom>::default(),
|
||||
UniformComponentPlugin::<BloomUniforms>::default(),
|
||||
));
|
||||
|
||||
|
@ -100,7 +103,7 @@ impl ViewNode for BloomNode {
|
|||
&'static BloomTexture,
|
||||
&'static BloomBindGroups,
|
||||
&'static DynamicUniformIndex<BloomUniforms>,
|
||||
&'static BloomSettings,
|
||||
&'static Bloom,
|
||||
&'static UpsamplingPipelineIds,
|
||||
&'static BloomDownsamplingPipelineIds,
|
||||
);
|
||||
|
@ -324,18 +327,18 @@ fn prepare_bloom_textures(
|
|||
mut commands: Commands,
|
||||
mut texture_cache: ResMut<TextureCache>,
|
||||
render_device: Res<RenderDevice>,
|
||||
views: Query<(Entity, &ExtractedCamera, &BloomSettings)>,
|
||||
views: Query<(Entity, &ExtractedCamera, &Bloom)>,
|
||||
) {
|
||||
for (entity, camera, settings) in &views {
|
||||
for (entity, camera, bloom) in &views {
|
||||
if let Some(UVec2 {
|
||||
x: width,
|
||||
y: height,
|
||||
}) = camera.physical_viewport_size
|
||||
{
|
||||
// How many times we can halve the resolution minus one so we don't go unnecessarily low
|
||||
let mip_count = settings.max_mip_dimension.ilog2().max(2) - 1;
|
||||
let mip_count = bloom.max_mip_dimension.ilog2().max(2) - 1;
|
||||
let mip_height_ratio = if height != 0 {
|
||||
settings.max_mip_dimension as f32 / height as f32
|
||||
bloom.max_mip_dimension as f32 / height as f32
|
||||
} else {
|
||||
0.
|
||||
};
|
||||
|
@ -457,19 +460,18 @@ fn prepare_bloom_bind_groups(
|
|||
/// * `max_mip` - the index of the lowest frequency pyramid level.
|
||||
///
|
||||
/// This function can be visually previewed for all values of *mip* (normalized) with tweakable
|
||||
/// [`BloomSettings`] parameters on [Desmos graphing calculator](https://www.desmos.com/calculator/ncc8xbhzzl).
|
||||
fn compute_blend_factor(bloom_settings: &BloomSettings, mip: f32, max_mip: f32) -> f32 {
|
||||
/// [`Bloom`] parameters on [Desmos graphing calculator](https://www.desmos.com/calculator/ncc8xbhzzl).
|
||||
fn compute_blend_factor(bloom: &Bloom, mip: f32, max_mip: f32) -> f32 {
|
||||
let mut lf_boost = (1.0
|
||||
- (1.0 - (mip / max_mip)).powf(1.0 / (1.0 - bloom_settings.low_frequency_boost_curvature)))
|
||||
* bloom_settings.low_frequency_boost;
|
||||
- (1.0 - (mip / max_mip)).powf(1.0 / (1.0 - bloom.low_frequency_boost_curvature)))
|
||||
* bloom.low_frequency_boost;
|
||||
let high_pass_lq = 1.0
|
||||
- (((mip / max_mip) - bloom_settings.high_pass_frequency)
|
||||
/ bloom_settings.high_pass_frequency)
|
||||
- (((mip / max_mip) - bloom.high_pass_frequency) / bloom.high_pass_frequency)
|
||||
.clamp(0.0, 1.0);
|
||||
lf_boost *= match bloom_settings.composite_mode {
|
||||
BloomCompositeMode::EnergyConserving => 1.0 - bloom_settings.intensity,
|
||||
lf_boost *= match bloom.composite_mode {
|
||||
BloomCompositeMode::EnergyConserving => 1.0 - bloom.intensity,
|
||||
BloomCompositeMode::Additive => 1.0,
|
||||
};
|
||||
|
||||
(bloom_settings.intensity + lf_boost) * high_pass_lq
|
||||
(bloom.intensity + lf_boost) * high_pass_lq
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ use bevy_render::{extract_component::ExtractComponent, prelude::Camera};
|
|||
/// used in Bevy as well as a visualization of the curve's respective scattering profile.
|
||||
#[derive(Component, Reflect, Clone)]
|
||||
#[reflect(Component, Default)]
|
||||
pub struct BloomSettings {
|
||||
pub struct Bloom {
|
||||
/// Controls the baseline of how much the image is scattered (default: 0.15).
|
||||
///
|
||||
/// This parameter should be used only to control the strength of the bloom
|
||||
|
@ -90,15 +90,21 @@ pub struct BloomSettings {
|
|||
/// * 1.0 - maximum scattering angle is 90 degrees
|
||||
pub high_pass_frequency: f32,
|
||||
|
||||
pub prefilter_settings: BloomPrefilterSettings,
|
||||
/// Controls the threshold filter used for extracting the brightest regions from the input image
|
||||
/// before blurring them and compositing back onto the original image.
|
||||
///
|
||||
/// Changing these settings creates a physically inaccurate image and makes it easy to make
|
||||
/// the final result look worse. However, they can be useful when emulating the 1990s-2000s game look.
|
||||
/// See [`BloomPrefilter`] for more information.
|
||||
pub prefilter: BloomPrefilter,
|
||||
|
||||
/// Controls whether bloom textures
|
||||
/// are blended between or added to each other. Useful
|
||||
/// if image brightening is desired and a must-change
|
||||
/// if `prefilter_settings` are used.
|
||||
/// if `prefilter` is used.
|
||||
///
|
||||
/// # Recommendation
|
||||
/// Set to [`BloomCompositeMode::Additive`] if `prefilter_settings` are
|
||||
/// Set to [`BloomCompositeMode::Additive`] if `prefilter` is
|
||||
/// configured in a non-energy-conserving way,
|
||||
/// otherwise set to [`BloomCompositeMode::EnergyConserving`].
|
||||
pub composite_mode: BloomCompositeMode,
|
||||
|
@ -112,7 +118,10 @@ pub struct BloomSettings {
|
|||
pub uv_offset: f32,
|
||||
}
|
||||
|
||||
impl BloomSettings {
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `Bloom`")]
|
||||
pub type BloomSettings = Bloom;
|
||||
|
||||
impl Bloom {
|
||||
const DEFAULT_MAX_MIP_DIMENSION: u32 = 512;
|
||||
const DEFAULT_UV_OFFSET: f32 = 0.004;
|
||||
|
||||
|
@ -124,7 +133,7 @@ impl BloomSettings {
|
|||
low_frequency_boost: 0.7,
|
||||
low_frequency_boost_curvature: 0.95,
|
||||
high_pass_frequency: 1.0,
|
||||
prefilter_settings: BloomPrefilterSettings {
|
||||
prefilter: BloomPrefilter {
|
||||
threshold: 0.0,
|
||||
threshold_softness: 0.0,
|
||||
},
|
||||
|
@ -139,7 +148,7 @@ impl BloomSettings {
|
|||
low_frequency_boost: 0.7,
|
||||
low_frequency_boost_curvature: 0.95,
|
||||
high_pass_frequency: 1.0,
|
||||
prefilter_settings: BloomPrefilterSettings {
|
||||
prefilter: BloomPrefilter {
|
||||
threshold: 0.6,
|
||||
threshold_softness: 0.2,
|
||||
},
|
||||
|
@ -154,7 +163,7 @@ impl BloomSettings {
|
|||
low_frequency_boost: 0.0,
|
||||
low_frequency_boost_curvature: 0.0,
|
||||
high_pass_frequency: 1.0 / 3.0,
|
||||
prefilter_settings: BloomPrefilterSettings {
|
||||
prefilter: BloomPrefilter {
|
||||
threshold: 0.0,
|
||||
threshold_softness: 0.0,
|
||||
},
|
||||
|
@ -164,7 +173,7 @@ impl BloomSettings {
|
|||
};
|
||||
}
|
||||
|
||||
impl Default for BloomSettings {
|
||||
impl Default for Bloom {
|
||||
fn default() -> Self {
|
||||
Self::NATURAL
|
||||
}
|
||||
|
@ -179,7 +188,7 @@ impl Default for BloomSettings {
|
|||
/// * Changing these settings makes it easy to make the final result look worse
|
||||
/// * Non-default prefilter settings should be used in conjunction with [`BloomCompositeMode::Additive`]
|
||||
#[derive(Default, Clone, Reflect)]
|
||||
pub struct BloomPrefilterSettings {
|
||||
pub struct BloomPrefilter {
|
||||
/// Baseline of the quadratic threshold curve (default: 0.0).
|
||||
///
|
||||
/// RGB values under the threshold curve will not contribute to the effect.
|
||||
|
@ -194,19 +203,22 @@ pub struct BloomPrefilterSettings {
|
|||
pub threshold_softness: f32,
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `BloomPrefilter`")]
|
||||
pub type BloomPrefilterSettings = BloomPrefilter;
|
||||
|
||||
#[derive(Debug, Clone, Reflect, PartialEq, Eq, Hash, Copy)]
|
||||
pub enum BloomCompositeMode {
|
||||
EnergyConserving,
|
||||
Additive,
|
||||
}
|
||||
|
||||
impl ExtractComponent for BloomSettings {
|
||||
impl ExtractComponent for Bloom {
|
||||
type QueryData = (&'static Self, &'static Camera);
|
||||
|
||||
type QueryFilter = ();
|
||||
type Out = (Self, BloomUniforms);
|
||||
|
||||
fn extract_component((settings, camera): QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
|
||||
fn extract_component((bloom, camera): QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
|
||||
match (
|
||||
camera.physical_viewport_rect(),
|
||||
camera.physical_viewport_size(),
|
||||
|
@ -215,8 +227,8 @@ impl ExtractComponent for BloomSettings {
|
|||
camera.hdr,
|
||||
) {
|
||||
(Some(URect { min: origin, .. }), Some(size), Some(target_size), true, true) => {
|
||||
let threshold = settings.prefilter_settings.threshold;
|
||||
let threshold_softness = settings.prefilter_settings.threshold_softness;
|
||||
let threshold = bloom.prefilter.threshold;
|
||||
let threshold_softness = bloom.prefilter.threshold_softness;
|
||||
let knee = threshold * threshold_softness.clamp(0.0, 1.0);
|
||||
|
||||
let uniform = BloomUniforms {
|
||||
|
@ -232,10 +244,10 @@ impl ExtractComponent for BloomSettings {
|
|||
aspect: AspectRatio::try_from_pixels(size.x, size.y)
|
||||
.expect("Valid screen size values for Bloom settings")
|
||||
.ratio(),
|
||||
uv_offset: settings.uv_offset,
|
||||
uv_offset: bloom.uv_offset,
|
||||
};
|
||||
|
||||
Some((settings.clone(), uniform))
|
||||
Some((bloom.clone(), uniform))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{
|
||||
downsampling_pipeline::BloomUniforms, BloomCompositeMode, BloomSettings, BLOOM_SHADER_HANDLE,
|
||||
downsampling_pipeline::BloomUniforms, Bloom, BloomCompositeMode, BLOOM_SHADER_HANDLE,
|
||||
BLOOM_TEXTURE_FORMAT,
|
||||
};
|
||||
use crate::fullscreen_vertex_shader::fullscreen_shader_vertex_state;
|
||||
|
@ -133,14 +133,14 @@ pub fn prepare_upsampling_pipeline(
|
|||
pipeline_cache: Res<PipelineCache>,
|
||||
mut pipelines: ResMut<SpecializedRenderPipelines<BloomUpsamplingPipeline>>,
|
||||
pipeline: Res<BloomUpsamplingPipeline>,
|
||||
views: Query<(Entity, &BloomSettings)>,
|
||||
views: Query<(Entity, &Bloom)>,
|
||||
) {
|
||||
for (entity, settings) in &views {
|
||||
for (entity, bloom) in &views {
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&pipeline,
|
||||
BloomUpsamplingPipelineKeys {
|
||||
composite_mode: settings.composite_mode,
|
||||
composite_mode: bloom.composite_mode,
|
||||
final_pipeline: false,
|
||||
},
|
||||
);
|
||||
|
@ -149,7 +149,7 @@ pub fn prepare_upsampling_pipeline(
|
|||
&pipeline_cache,
|
||||
&pipeline,
|
||||
BloomUpsamplingPipelineKeys {
|
||||
composite_mode: settings.composite_mode,
|
||||
composite_mode: bloom.composite_mode,
|
||||
final_pipeline: true,
|
||||
},
|
||||
);
|
||||
|
|
|
@ -34,10 +34,10 @@ pub use node::CasNode;
|
|||
/// based on the local contrast. This can help avoid over-sharpening areas with high contrast
|
||||
/// and under-sharpening areas with low contrast.
|
||||
///
|
||||
/// To use this, add the [`ContrastAdaptiveSharpeningSettings`] component to a 2D or 3D camera.
|
||||
/// To use this, add the [`ContrastAdaptiveSharpening`] component to a 2D or 3D camera.
|
||||
#[derive(Component, Reflect, Clone)]
|
||||
#[reflect(Component)]
|
||||
pub struct ContrastAdaptiveSharpeningSettings {
|
||||
pub struct ContrastAdaptiveSharpening {
|
||||
/// Enable or disable sharpening.
|
||||
pub enabled: bool,
|
||||
/// Adjusts sharpening strength. Higher values increase the amount of sharpening.
|
||||
|
@ -54,9 +54,12 @@ pub struct ContrastAdaptiveSharpeningSettings {
|
|||
pub denoise: bool,
|
||||
}
|
||||
|
||||
impl Default for ContrastAdaptiveSharpeningSettings {
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `ContrastAdaptiveSharpening`")]
|
||||
pub type ContrastAdaptiveSharpeningSettings = ContrastAdaptiveSharpening;
|
||||
|
||||
impl Default for ContrastAdaptiveSharpening {
|
||||
fn default() -> Self {
|
||||
ContrastAdaptiveSharpeningSettings {
|
||||
ContrastAdaptiveSharpening {
|
||||
enabled: true,
|
||||
sharpening_strength: 0.6,
|
||||
denoise: false,
|
||||
|
@ -68,7 +71,7 @@ impl Default for ContrastAdaptiveSharpeningSettings {
|
|||
#[reflect(Component)]
|
||||
pub struct DenoiseCas(bool);
|
||||
|
||||
/// The uniform struct extracted from [`ContrastAdaptiveSharpeningSettings`] attached to a [`Camera`].
|
||||
/// The uniform struct extracted from [`ContrastAdaptiveSharpening`] attached to a [`Camera`].
|
||||
/// Will be available for use in the CAS shader.
|
||||
#[doc(hidden)]
|
||||
#[derive(Component, ShaderType, Clone)]
|
||||
|
@ -76,7 +79,7 @@ pub struct CasUniform {
|
|||
sharpness: f32,
|
||||
}
|
||||
|
||||
impl ExtractComponent for ContrastAdaptiveSharpeningSettings {
|
||||
impl ExtractComponent for ContrastAdaptiveSharpening {
|
||||
type QueryData = &'static Self;
|
||||
type QueryFilter = With<Camera>;
|
||||
type Out = (DenoiseCas, CasUniform);
|
||||
|
@ -110,9 +113,9 @@ impl Plugin for CasPlugin {
|
|||
Shader::from_wgsl
|
||||
);
|
||||
|
||||
app.register_type::<ContrastAdaptiveSharpeningSettings>();
|
||||
app.register_type::<ContrastAdaptiveSharpening>();
|
||||
app.add_plugins((
|
||||
ExtractComponentPlugin::<ContrastAdaptiveSharpeningSettings>::default(),
|
||||
ExtractComponentPlugin::<ContrastAdaptiveSharpening>::default(),
|
||||
UniformComponentPlugin::<CasUniform>::default(),
|
||||
));
|
||||
|
||||
|
@ -241,12 +244,12 @@ fn prepare_cas_pipelines(
|
|||
sharpening_pipeline: Res<CasPipeline>,
|
||||
views: Query<(Entity, &ExtractedView, &DenoiseCas), With<CasUniform>>,
|
||||
) {
|
||||
for (entity, view, cas_settings) in &views {
|
||||
for (entity, view, cas) in &views {
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&sharpening_pipeline,
|
||||
CasPipelineKey {
|
||||
denoise: cas_settings.0,
|
||||
denoise: cas.0,
|
||||
texture_format: if view.hdr {
|
||||
ViewTarget::TEXTURE_FORMAT_HDR
|
||||
} else {
|
||||
|
|
|
@ -52,7 +52,7 @@ struct DepthOfFieldParams {
|
|||
max_circle_of_confusion_diameter: f32,
|
||||
|
||||
/// The depth value that we clamp distant objects to. See the comment in
|
||||
/// [`DepthOfFieldSettings`] for more information.
|
||||
/// [`DepthOfField`] for more information.
|
||||
max_depth: f32,
|
||||
|
||||
/// Padding.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
//! [depth of field], and this term is used more generally in computer graphics
|
||||
//! to refer to the effect that simulates focus of lenses.
|
||||
//!
|
||||
//! Attaching [`DepthOfFieldSettings`] to a camera causes Bevy to simulate the
|
||||
//! Attaching [`DepthOfField`] to a camera causes Bevy to simulate the
|
||||
//! focus of a camera lens. Generally, Bevy's implementation of depth of field
|
||||
//! is optimized for speed instead of physical accuracy. Nevertheless, the depth
|
||||
//! of field effect in Bevy is based on physical parameters.
|
||||
|
@ -68,10 +68,13 @@ const DOF_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(203186118073921
|
|||
/// A plugin that adds support for the depth of field effect to Bevy.
|
||||
pub struct DepthOfFieldPlugin;
|
||||
|
||||
/// Depth of field settings.
|
||||
/// A component that enables a [depth of field] postprocessing effect when attached to a [`Camera3d`],
|
||||
/// simulating the focus of a camera lens.
|
||||
///
|
||||
/// [depth of field]: https://en.wikipedia.org/wiki/Depth_of_field
|
||||
#[derive(Component, Clone, Copy, Reflect)]
|
||||
#[reflect(Component, Default)]
|
||||
pub struct DepthOfFieldSettings {
|
||||
pub struct DepthOfField {
|
||||
/// The appearance of the effect.
|
||||
pub mode: DepthOfFieldMode,
|
||||
|
||||
|
@ -112,6 +115,9 @@ pub struct DepthOfFieldSettings {
|
|||
pub max_depth: f32,
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `DepthOfField`")]
|
||||
pub type DepthOfFieldSettings = DepthOfField;
|
||||
|
||||
/// Controls the appearance of the effect.
|
||||
#[derive(Clone, Copy, Default, PartialEq, Debug, Reflect)]
|
||||
#[reflect(Default, PartialEq)]
|
||||
|
@ -156,11 +162,11 @@ pub struct DepthOfFieldUniform {
|
|||
coc_scale_factor: f32,
|
||||
|
||||
/// The maximum circle of confusion diameter in pixels. See the comment in
|
||||
/// [`DepthOfFieldSettings`] for more information.
|
||||
/// [`DepthOfField`] for more information.
|
||||
max_circle_of_confusion_diameter: f32,
|
||||
|
||||
/// The depth value that we clamp distant objects to. See the comment in
|
||||
/// [`DepthOfFieldSettings`] for more information.
|
||||
/// [`DepthOfField`] for more information.
|
||||
max_depth: f32,
|
||||
|
||||
/// Padding.
|
||||
|
@ -199,7 +205,7 @@ impl Plugin for DepthOfFieldPlugin {
|
|||
fn build(&self, app: &mut App) {
|
||||
load_internal_asset!(app, DOF_SHADER_HANDLE, "dof.wgsl", Shader::from_wgsl);
|
||||
|
||||
app.register_type::<DepthOfFieldSettings>();
|
||||
app.register_type::<DepthOfField>();
|
||||
app.register_type::<DepthOfFieldMode>();
|
||||
app.add_plugins(UniformComponentPlugin::<DepthOfFieldUniform>::default());
|
||||
|
||||
|
@ -339,7 +345,7 @@ impl ViewNode for DepthOfFieldNode {
|
|||
view_depth_texture,
|
||||
view_pipelines,
|
||||
view_bind_group_layouts,
|
||||
dof_settings_uniform_index,
|
||||
depth_of_field_uniform_index,
|
||||
auxiliary_dof_texture,
|
||||
): QueryItem<'w, Self::ViewQuery>,
|
||||
world: &'w World,
|
||||
|
@ -440,7 +446,11 @@ impl ViewNode for DepthOfFieldNode {
|
|||
// Set the per-view bind group.
|
||||
render_pass.set_bind_group(0, &view_bind_group, &[view_uniform_offset.offset]);
|
||||
// Set the global bind group shared among all invocations of the shader.
|
||||
render_pass.set_bind_group(1, global_bind_group, &[dof_settings_uniform_index.index()]);
|
||||
render_pass.set_bind_group(
|
||||
1,
|
||||
global_bind_group,
|
||||
&[depth_of_field_uniform_index.index()],
|
||||
);
|
||||
// Render the full-screen pass.
|
||||
render_pass.draw(0..3, 0..1);
|
||||
}
|
||||
|
@ -449,7 +459,7 @@ impl ViewNode for DepthOfFieldNode {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for DepthOfFieldSettings {
|
||||
impl Default for DepthOfField {
|
||||
fn default() -> Self {
|
||||
let physical_camera_default = PhysicalCameraParameters::default();
|
||||
Self {
|
||||
|
@ -463,8 +473,8 @@ impl Default for DepthOfFieldSettings {
|
|||
}
|
||||
}
|
||||
|
||||
impl DepthOfFieldSettings {
|
||||
/// Initializes [`DepthOfFieldSettings`] from a set of
|
||||
impl DepthOfField {
|
||||
/// Initializes [`DepthOfField`] from a set of
|
||||
/// [`PhysicalCameraParameters`].
|
||||
///
|
||||
/// By passing the same [`PhysicalCameraParameters`] object to this function
|
||||
|
@ -472,10 +482,10 @@ impl DepthOfFieldSettings {
|
|||
/// results for both the exposure and depth of field effects can be
|
||||
/// obtained.
|
||||
///
|
||||
/// All fields of the returned [`DepthOfFieldSettings`] other than
|
||||
/// All fields of the returned [`DepthOfField`] other than
|
||||
/// `focal_length` and `aperture_f_stops` are set to their default values.
|
||||
pub fn from_physical_camera(camera: &PhysicalCameraParameters) -> DepthOfFieldSettings {
|
||||
DepthOfFieldSettings {
|
||||
pub fn from_physical_camera(camera: &PhysicalCameraParameters) -> DepthOfField {
|
||||
DepthOfField {
|
||||
sensor_height: camera.sensor_height,
|
||||
aperture_f_stops: camera.aperture_f_stops,
|
||||
..default()
|
||||
|
@ -521,10 +531,10 @@ impl FromWorld for DepthOfFieldGlobalBindGroupLayout {
|
|||
/// specific to each view.
|
||||
pub fn prepare_depth_of_field_view_bind_group_layouts(
|
||||
mut commands: Commands,
|
||||
view_targets: Query<(Entity, &DepthOfFieldSettings, &Msaa)>,
|
||||
view_targets: Query<(Entity, &DepthOfField, &Msaa)>,
|
||||
render_device: Res<RenderDevice>,
|
||||
) {
|
||||
for (view, dof_settings, msaa) in view_targets.iter() {
|
||||
for (view, depth_of_field, msaa) in view_targets.iter() {
|
||||
// Create the bind group layout for the passes that take one input.
|
||||
let single_input = render_device.create_bind_group_layout(
|
||||
Some("depth of field bind group layout (single input)"),
|
||||
|
@ -544,7 +554,7 @@ pub fn prepare_depth_of_field_view_bind_group_layouts(
|
|||
|
||||
// If needed, create the bind group layout for the second bokeh pass,
|
||||
// which takes two inputs. We only need to do this if bokeh is in use.
|
||||
let dual_input = match dof_settings.mode {
|
||||
let dual_input = match depth_of_field.mode {
|
||||
DepthOfFieldMode::Gaussian => None,
|
||||
DepthOfFieldMode::Bokeh => Some(render_device.create_bind_group_layout(
|
||||
Some("depth of field bind group layout (dual input)"),
|
||||
|
@ -581,7 +591,7 @@ pub fn prepare_depth_of_field_view_bind_group_layouts(
|
|||
/// need to set the appropriate flag to tell Bevy to make samplable depth
|
||||
/// buffers.
|
||||
pub fn configure_depth_of_field_view_targets(
|
||||
mut view_targets: Query<&mut Camera3d, With<DepthOfFieldSettings>>,
|
||||
mut view_targets: Query<&mut Camera3d, With<DepthOfField>>,
|
||||
) {
|
||||
for mut camera_3d in view_targets.iter_mut() {
|
||||
let mut depth_texture_usages = TextureUsages::from(camera_3d.depth_texture_usages);
|
||||
|
@ -595,10 +605,10 @@ pub fn configure_depth_of_field_view_targets(
|
|||
pub fn prepare_depth_of_field_global_bind_group(
|
||||
global_bind_group_layout: Res<DepthOfFieldGlobalBindGroupLayout>,
|
||||
mut dof_bind_group: ResMut<DepthOfFieldGlobalBindGroup>,
|
||||
dof_settings_uniforms: Res<ComponentUniforms<DepthOfFieldUniform>>,
|
||||
depth_of_field_uniforms: Res<ComponentUniforms<DepthOfFieldUniform>>,
|
||||
render_device: Res<RenderDevice>,
|
||||
) {
|
||||
let Some(dof_settings_uniforms) = dof_settings_uniforms.binding() else {
|
||||
let Some(depth_of_field_uniforms) = depth_of_field_uniforms.binding() else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -606,7 +616,7 @@ pub fn prepare_depth_of_field_global_bind_group(
|
|||
Some("depth of field global bind group"),
|
||||
&global_bind_group_layout.layout,
|
||||
&BindGroupEntries::sequential((
|
||||
dof_settings_uniforms, // `dof_params`
|
||||
depth_of_field_uniforms, // `dof_params`
|
||||
&global_bind_group_layout.color_texture_sampler, // `color_texture_sampler`
|
||||
)),
|
||||
));
|
||||
|
@ -618,11 +628,11 @@ pub fn prepare_auxiliary_depth_of_field_textures(
|
|||
mut commands: Commands,
|
||||
render_device: Res<RenderDevice>,
|
||||
mut texture_cache: ResMut<TextureCache>,
|
||||
mut view_targets: Query<(Entity, &ViewTarget, &DepthOfFieldSettings)>,
|
||||
mut view_targets: Query<(Entity, &ViewTarget, &DepthOfField)>,
|
||||
) {
|
||||
for (entity, view_target, dof_settings) in view_targets.iter_mut() {
|
||||
for (entity, view_target, depth_of_field) in view_targets.iter_mut() {
|
||||
// An auxiliary texture is only needed for bokeh.
|
||||
if dof_settings.mode != DepthOfFieldMode::Bokeh {
|
||||
if depth_of_field.mode != DepthOfFieldMode::Bokeh {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -655,12 +665,12 @@ pub fn prepare_depth_of_field_pipelines(
|
|||
view_targets: Query<(
|
||||
Entity,
|
||||
&ExtractedView,
|
||||
&DepthOfFieldSettings,
|
||||
&DepthOfField,
|
||||
&ViewDepthOfFieldBindGroupLayouts,
|
||||
&Msaa,
|
||||
)>,
|
||||
) {
|
||||
for (entity, view, dof_settings, view_bind_group_layouts, msaa) in view_targets.iter() {
|
||||
for (entity, view, depth_of_field, view_bind_group_layouts, msaa) in view_targets.iter() {
|
||||
let dof_pipeline = DepthOfFieldPipeline {
|
||||
view_bind_group_layouts: view_bind_group_layouts.clone(),
|
||||
global_bind_group_layout: global_bind_group_layout.layout.clone(),
|
||||
|
@ -670,7 +680,7 @@ pub fn prepare_depth_of_field_pipelines(
|
|||
let (hdr, multisample) = (view.hdr, *msaa != Msaa::Off);
|
||||
|
||||
// Go ahead and specialize the pipelines.
|
||||
match dof_settings.mode {
|
||||
match depth_of_field.mode {
|
||||
DepthOfFieldMode::Gaussian => {
|
||||
commands
|
||||
.entity(entity)
|
||||
|
@ -795,10 +805,10 @@ impl SpecializedRenderPipeline for DepthOfFieldPipeline {
|
|||
}
|
||||
}
|
||||
|
||||
/// Extracts all [`DepthOfFieldSettings`] components into the render world.
|
||||
/// Extracts all [`DepthOfField`] components into the render world.
|
||||
fn extract_depth_of_field_settings(
|
||||
mut commands: Commands,
|
||||
mut query: Extract<Query<(Entity, &DepthOfFieldSettings, &Projection)>>,
|
||||
mut query: Extract<Query<(Entity, &DepthOfField, &Projection)>>,
|
||||
) {
|
||||
if !DEPTH_TEXTURE_SAMPLING_SUPPORTED {
|
||||
info_once!(
|
||||
|
@ -807,25 +817,25 @@ fn extract_depth_of_field_settings(
|
|||
return;
|
||||
}
|
||||
|
||||
for (entity, dof_settings, projection) in query.iter_mut() {
|
||||
for (entity, depth_of_field, projection) in query.iter_mut() {
|
||||
// Depth of field is nonsensical without a perspective projection.
|
||||
let Projection::Perspective(ref perspective_projection) = *projection else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let focal_length =
|
||||
calculate_focal_length(dof_settings.sensor_height, perspective_projection.fov);
|
||||
calculate_focal_length(depth_of_field.sensor_height, perspective_projection.fov);
|
||||
|
||||
// Convert `DepthOfFieldSettings` to `DepthOfFieldUniform`.
|
||||
// Convert `DepthOfField` to `DepthOfFieldUniform`.
|
||||
commands.get_or_spawn(entity).insert((
|
||||
*dof_settings,
|
||||
*depth_of_field,
|
||||
DepthOfFieldUniform {
|
||||
focal_distance: dof_settings.focal_distance,
|
||||
focal_distance: depth_of_field.focal_distance,
|
||||
focal_length,
|
||||
coc_scale_factor: focal_length * focal_length
|
||||
/ (dof_settings.sensor_height * dof_settings.aperture_f_stops),
|
||||
max_circle_of_confusion_diameter: dof_settings.max_circle_of_confusion_diameter,
|
||||
max_depth: dof_settings.max_depth,
|
||||
/ (depth_of_field.sensor_height * depth_of_field.aperture_f_stops),
|
||||
max_circle_of_confusion_diameter: depth_of_field.max_circle_of_confusion_diameter,
|
||||
max_depth: depth_of_field.max_depth,
|
||||
pad_a: 0,
|
||||
pad_b: 0,
|
||||
pad_c: 0,
|
||||
|
|
|
@ -49,9 +49,12 @@ impl Sensitivity {
|
|||
}
|
||||
}
|
||||
|
||||
/// A component for enabling Fast Approximate Anti-Aliasing (FXAA)
|
||||
/// for a [`bevy_render::camera::Camera`].
|
||||
#[derive(Reflect, Component, Clone, ExtractComponent)]
|
||||
#[reflect(Component, Default)]
|
||||
#[extract_component_filter(With<Camera>)]
|
||||
#[doc(alias = "FastApproximateAntiAliasing")]
|
||||
pub struct Fxaa {
|
||||
/// Enable render passes for FXAA.
|
||||
pub enabled: bool,
|
||||
|
@ -60,7 +63,7 @@ pub struct Fxaa {
|
|||
/// Use higher sensitivity for a slower, smoother, result.
|
||||
/// [`Ultra`](`Sensitivity::Ultra`) and [`Extreme`](`Sensitivity::Extreme`)
|
||||
/// settings can result in significant smearing and loss of detail.
|
||||
|
||||
///
|
||||
/// The minimum amount of local contrast required to apply algorithm.
|
||||
pub edge_threshold: Sensitivity,
|
||||
|
||||
|
|
|
@ -34,9 +34,10 @@ pub use skybox::Skybox;
|
|||
/// Expect bugs, missing features, compatibility issues, low performance, and/or future breaking changes.
|
||||
pub mod experimental {
|
||||
pub mod taa {
|
||||
#[allow(deprecated)]
|
||||
pub use crate::taa::{
|
||||
TemporalAntiAliasBundle, TemporalAntiAliasNode, TemporalAntiAliasPlugin,
|
||||
TemporalAntiAliasSettings,
|
||||
TemporalAntiAliasSettings, TemporalAntiAliasing,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,10 +33,10 @@ impl ViewNode for MotionBlurNode {
|
|||
&self,
|
||||
_graph: &mut RenderGraphContext,
|
||||
render_context: &mut RenderContext,
|
||||
(view_target, pipeline_id, prepass_textures, settings, msaa): QueryItem<Self::ViewQuery>,
|
||||
(view_target, pipeline_id, prepass_textures, motion_blur, msaa): QueryItem<Self::ViewQuery>,
|
||||
world: &World,
|
||||
) -> Result<(), NodeRunError> {
|
||||
if settings.samples == 0 || settings.shutter_angle <= 0.0 {
|
||||
if motion_blur.samples == 0 || motion_blur.shutter_angle <= 0.0 {
|
||||
return Ok(()); // We can skip running motion blur in these cases.
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
//! which have made SMAA less popular when advanced photorealistic rendering
|
||||
//! features are used in recent years.
|
||||
//!
|
||||
//! To use SMAA, add [`SmaaSettings`] to a [`bevy_render::camera::Camera`]. In a
|
||||
//! To use SMAA, add [`Smaa`] to a [`bevy_render::camera::Camera`]. In a
|
||||
//! pinch, you can simply use the default settings (via the [`Default`] trait)
|
||||
//! for a high-quality, high-performance appearance. When using SMAA, you will
|
||||
//! likely want set [`bevy_render::view::Msaa`] to [`bevy_render::view::Msaa::Off`]
|
||||
|
@ -95,17 +95,21 @@ const SMAA_SEARCH_LUT_TEXTURE_HANDLE: Handle<Image> = Handle::weak_from_u128(318
|
|||
/// Adds support for subpixel morphological antialiasing, or SMAA.
|
||||
pub struct SmaaPlugin;
|
||||
|
||||
/// Add this component to a [`bevy_render::camera::Camera`] to enable subpixel
|
||||
/// morphological antialiasing (SMAA).
|
||||
/// A component for enabling Subpixel Morphological Anti-Aliasing (SMAA)
|
||||
/// for a [`bevy_render::camera::Camera`].
|
||||
#[derive(Clone, Copy, Default, Component, Reflect, ExtractComponent)]
|
||||
#[reflect(Component, Default)]
|
||||
pub struct SmaaSettings {
|
||||
#[doc(alias = "SubpixelMorphologicalAntiAliasing")]
|
||||
pub struct Smaa {
|
||||
/// A predefined set of SMAA parameters: i.e. a quality level.
|
||||
///
|
||||
/// Generally, you can leave this at its default level.
|
||||
pub preset: SmaaPreset,
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `Smaa`")]
|
||||
pub type SmaaSettings = Smaa;
|
||||
|
||||
/// A preset quality level for SMAA.
|
||||
///
|
||||
/// Higher values are slower but result in a higher-quality image.
|
||||
|
@ -339,8 +343,8 @@ impl Plugin for SmaaPlugin {
|
|||
.resource_mut::<bevy_asset::Assets<Image>>()
|
||||
.insert(SMAA_SEARCH_LUT_TEXTURE_HANDLE.id(), lut_placeholder());
|
||||
|
||||
app.add_plugins(ExtractComponentPlugin::<SmaaSettings>::default())
|
||||
.register_type::<SmaaSettings>();
|
||||
app.add_plugins(ExtractComponentPlugin::<Smaa>::default())
|
||||
.register_type::<Smaa>();
|
||||
|
||||
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
|
||||
return;
|
||||
|
@ -614,13 +618,13 @@ fn prepare_smaa_pipelines(
|
|||
pipeline_cache: Res<PipelineCache>,
|
||||
mut specialized_render_pipelines: ResMut<SmaaSpecializedRenderPipelines>,
|
||||
smaa_pipelines: Res<SmaaPipelines>,
|
||||
view_targets: Query<(Entity, &ExtractedView, &SmaaSettings)>,
|
||||
view_targets: Query<(Entity, &ExtractedView, &Smaa)>,
|
||||
) {
|
||||
for (entity, view, settings) in &view_targets {
|
||||
for (entity, view, smaa) in &view_targets {
|
||||
let edge_detection_pipeline_id = specialized_render_pipelines.edge_detection.specialize(
|
||||
&pipeline_cache,
|
||||
&smaa_pipelines.edge_detection,
|
||||
settings.preset,
|
||||
smaa.preset,
|
||||
);
|
||||
|
||||
let blending_weight_calculation_pipeline_id = specialized_render_pipelines
|
||||
|
@ -628,7 +632,7 @@ fn prepare_smaa_pipelines(
|
|||
.specialize(
|
||||
&pipeline_cache,
|
||||
&smaa_pipelines.blending_weight_calculation,
|
||||
settings.preset,
|
||||
smaa.preset,
|
||||
);
|
||||
|
||||
let neighborhood_blending_pipeline_id = specialized_render_pipelines
|
||||
|
@ -642,7 +646,7 @@ fn prepare_smaa_pipelines(
|
|||
} else {
|
||||
TextureFormat::bevy_default()
|
||||
},
|
||||
preset: settings.preset,
|
||||
preset: smaa.preset,
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -660,7 +664,7 @@ fn prepare_smaa_uniforms(
|
|||
mut commands: Commands,
|
||||
render_device: Res<RenderDevice>,
|
||||
render_queue: Res<RenderQueue>,
|
||||
view_targets: Query<(Entity, &ExtractedView), With<SmaaSettings>>,
|
||||
view_targets: Query<(Entity, &ExtractedView), With<Smaa>>,
|
||||
mut smaa_info_buffer: ResMut<SmaaInfoUniformBuffer>,
|
||||
) {
|
||||
smaa_info_buffer.clear();
|
||||
|
@ -691,7 +695,7 @@ fn prepare_smaa_textures(
|
|||
mut commands: Commands,
|
||||
render_device: Res<RenderDevice>,
|
||||
mut texture_cache: ResMut<TextureCache>,
|
||||
view_targets: Query<(Entity, &ExtractedCamera), (With<ExtractedView>, With<SmaaSettings>)>,
|
||||
view_targets: Query<(Entity, &ExtractedCamera), (With<ExtractedView>, With<Smaa>)>,
|
||||
) {
|
||||
for (entity, camera) in &view_targets {
|
||||
let Some(texture_size) = camera.physical_target_size else {
|
||||
|
@ -765,7 +769,7 @@ fn prepare_smaa_bind_groups(
|
|||
render_device: Res<RenderDevice>,
|
||||
smaa_pipelines: Res<SmaaPipelines>,
|
||||
images: Res<RenderAssets<GpuImage>>,
|
||||
view_targets: Query<(Entity, &SmaaTextures), (With<ExtractedView>, With<SmaaSettings>)>,
|
||||
view_targets: Query<(Entity, &SmaaTextures), (With<ExtractedView>, With<Smaa>)>,
|
||||
) {
|
||||
// Fetch the two lookup textures. These are bundled in this library.
|
||||
let (Some(search_texture), Some(area_texture)) = (
|
||||
|
|
|
@ -40,14 +40,14 @@ const TAA_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(656865235226276
|
|||
|
||||
/// Plugin for temporal anti-aliasing.
|
||||
///
|
||||
/// See [`TemporalAntiAliasSettings`] for more details.
|
||||
/// See [`TemporalAntiAliasing`] for more details.
|
||||
pub struct TemporalAntiAliasPlugin;
|
||||
|
||||
impl Plugin for TemporalAntiAliasPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
load_internal_asset!(app, TAA_SHADER_HANDLE, "taa.wgsl", Shader::from_wgsl);
|
||||
|
||||
app.register_type::<TemporalAntiAliasSettings>();
|
||||
app.register_type::<TemporalAntiAliasing>();
|
||||
|
||||
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
|
||||
return;
|
||||
|
@ -88,7 +88,7 @@ impl Plugin for TemporalAntiAliasPlugin {
|
|||
/// Bundle to apply temporal anti-aliasing.
|
||||
#[derive(Bundle, Default, Clone)]
|
||||
pub struct TemporalAntiAliasBundle {
|
||||
pub settings: TemporalAntiAliasSettings,
|
||||
pub settings: TemporalAntiAliasing,
|
||||
pub jitter: TemporalJitter,
|
||||
pub depth_prepass: DepthPrepass,
|
||||
pub motion_vector_prepass: MotionVectorPrepass,
|
||||
|
@ -136,7 +136,8 @@ pub struct TemporalAntiAliasBundle {
|
|||
///
|
||||
/// If no [`MipBias`] component is attached to the camera, TAA will add a MipBias(-1.0) component.
|
||||
#[derive(Component, Reflect, Clone)]
|
||||
pub struct TemporalAntiAliasSettings {
|
||||
#[doc(alias = "Taa")]
|
||||
pub struct TemporalAntiAliasing {
|
||||
/// Set to true to delete the saved temporal history (past frames).
|
||||
///
|
||||
/// Useful for preventing ghosting when the history is no longer
|
||||
|
@ -147,7 +148,10 @@ pub struct TemporalAntiAliasSettings {
|
|||
pub reset: bool,
|
||||
}
|
||||
|
||||
impl Default for TemporalAntiAliasSettings {
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `TemporalAntiAliasing`")]
|
||||
pub type TemporalAntiAliasSettings = TemporalAntiAliasing;
|
||||
|
||||
impl Default for TemporalAntiAliasing {
|
||||
fn default() -> Self {
|
||||
Self { reset: true }
|
||||
}
|
||||
|
@ -347,7 +351,7 @@ impl SpecializedRenderPipeline for TaaPipeline {
|
|||
|
||||
fn extract_taa_settings(mut commands: Commands, mut main_world: ResMut<MainWorld>) {
|
||||
let mut cameras_3d = main_world
|
||||
.query_filtered::<(Entity, &Camera, &Projection, &mut TemporalAntiAliasSettings), (
|
||||
.query_filtered::<(Entity, &Camera, &Projection, &mut TemporalAntiAliasing), (
|
||||
With<Camera3d>,
|
||||
With<TemporalJitter>,
|
||||
With<DepthPrepass>,
|
||||
|
@ -367,10 +371,7 @@ fn extract_taa_settings(mut commands: Commands, mut main_world: ResMut<MainWorld
|
|||
|
||||
fn prepare_taa_jitter_and_mip_bias(
|
||||
frame_count: Res<FrameCount>,
|
||||
mut query: Query<
|
||||
(Entity, &mut TemporalJitter, Option<&MipBias>),
|
||||
With<TemporalAntiAliasSettings>,
|
||||
>,
|
||||
mut query: Query<(Entity, &mut TemporalJitter, Option<&MipBias>), With<TemporalAntiAliasing>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
// Halton sequence (2, 3) - 0.5, skipping i = 0
|
||||
|
@ -407,7 +408,7 @@ fn prepare_taa_history_textures(
|
|||
mut texture_cache: ResMut<TextureCache>,
|
||||
render_device: Res<RenderDevice>,
|
||||
frame_count: Res<FrameCount>,
|
||||
views: Query<(Entity, &ExtractedCamera, &ExtractedView), With<TemporalAntiAliasSettings>>,
|
||||
views: Query<(Entity, &ExtractedCamera, &ExtractedView), With<TemporalAntiAliasing>>,
|
||||
) {
|
||||
for (entity, camera, view) in &views {
|
||||
if let Some(physical_target_size) = camera.physical_target_size {
|
||||
|
@ -461,7 +462,7 @@ fn prepare_taa_pipelines(
|
|||
pipeline_cache: Res<PipelineCache>,
|
||||
mut pipelines: ResMut<SpecializedRenderPipelines<TaaPipeline>>,
|
||||
pipeline: Res<TaaPipeline>,
|
||||
views: Query<(Entity, &ExtractedView, &TemporalAntiAliasSettings)>,
|
||||
views: Query<(Entity, &ExtractedView, &TemporalAntiAliasing)>,
|
||||
) {
|
||||
for (entity, view, taa_settings) in &views {
|
||||
let mut pipeline_key = TaaPipelineKey {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
graph::NodePbr, irradiance_volume::IrradianceVolume, prelude::EnvironmentMapLight,
|
||||
MeshPipeline, MeshViewBindGroup, RenderViewLightProbes, ScreenSpaceAmbientOcclusionSettings,
|
||||
MeshPipeline, MeshViewBindGroup, RenderViewLightProbes, ScreenSpaceAmbientOcclusion,
|
||||
ScreenSpaceReflectionsUniform, ViewEnvironmentMapUniformOffset, ViewLightProbesUniformOffset,
|
||||
ViewScreenSpaceReflectionsUniformOffset,
|
||||
};
|
||||
|
@ -434,7 +434,7 @@ pub fn prepare_deferred_lighting_pipelines(
|
|||
Option<&DebandDither>,
|
||||
Option<&ShadowFilteringMethod>,
|
||||
(
|
||||
Has<ScreenSpaceAmbientOcclusionSettings>,
|
||||
Has<ScreenSpaceAmbientOcclusion>,
|
||||
Has<ScreenSpaceReflectionsUniform>,
|
||||
),
|
||||
(
|
||||
|
|
|
@ -34,7 +34,7 @@ use bevy_render::{extract_component::ExtractComponent, prelude::Camera};
|
|||
/// # ..Default::default()
|
||||
/// },
|
||||
/// // Add fog to the same entity
|
||||
/// FogSettings {
|
||||
/// DistanceFog {
|
||||
/// color: Color::WHITE,
|
||||
/// falloff: FogFalloff::Exponential { density: 1e-3 },
|
||||
/// ..Default::default()
|
||||
|
@ -51,7 +51,7 @@ use bevy_render::{extract_component::ExtractComponent, prelude::Camera};
|
|||
#[derive(Debug, Clone, Component, Reflect, ExtractComponent)]
|
||||
#[extract_component_filter(With<Camera>)]
|
||||
#[reflect(Component, Default)]
|
||||
pub struct FogSettings {
|
||||
pub struct DistanceFog {
|
||||
/// The color of the fog effect.
|
||||
///
|
||||
/// **Tip:** The alpha channel of the color can be used to “modulate” the fog effect without
|
||||
|
@ -73,6 +73,9 @@ pub struct FogSettings {
|
|||
pub falloff: FogFalloff,
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `DistanceFog`")]
|
||||
pub type FogSettings = DistanceFog;
|
||||
|
||||
/// Allows switching between different fog falloff modes, and configuring their parameters.
|
||||
///
|
||||
/// ## Convenience Methods
|
||||
|
@ -149,7 +152,7 @@ pub enum FogFalloff {
|
|||
/// scale. Typically, for scenes with objects in the scale of thousands of units, you might want density values
|
||||
/// in the ballpark of `0.001`. Conversely, for really small scale scenes you might want really high values of
|
||||
/// density;
|
||||
/// - Combine the `density` parameter with the [`FogSettings`] `color`'s alpha channel for easier artistic control.
|
||||
/// - Combine the `density` parameter with the [`DistanceFog`] `color`'s alpha channel for easier artistic control.
|
||||
///
|
||||
/// ## Formula
|
||||
///
|
||||
|
@ -197,7 +200,7 @@ pub enum FogFalloff {
|
|||
///
|
||||
/// - Use the [`FogFalloff::from_visibility_squared()`] convenience method to create an exponential squared falloff
|
||||
/// with the proper density for a desired visibility distance in world units;
|
||||
/// - Combine the `density` parameter with the [`FogSettings`] `color`'s alpha channel for easier artistic control.
|
||||
/// - Combine the `density` parameter with the [`DistanceFog`] `color`'s alpha channel for easier artistic control.
|
||||
///
|
||||
/// ## Formula
|
||||
///
|
||||
|
@ -244,7 +247,7 @@ pub enum FogFalloff {
|
|||
/// - Use the [`FogFalloff::from_visibility_colors()`] or [`FogFalloff::from_visibility_color()`] convenience methods
|
||||
/// to create an atmospheric falloff with the proper densities for a desired visibility distance in world units and
|
||||
/// extinction and inscattering colors;
|
||||
/// - Combine the atmospheric fog parameters with the [`FogSettings`] `color`'s alpha channel for easier artistic control.
|
||||
/// - Combine the atmospheric fog parameters with the [`DistanceFog`] `color`'s alpha channel for easier artistic control.
|
||||
///
|
||||
/// ## Formula
|
||||
///
|
||||
|
@ -463,9 +466,9 @@ impl FogFalloff {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for FogSettings {
|
||||
impl Default for DistanceFog {
|
||||
fn default() -> Self {
|
||||
FogSettings {
|
||||
DistanceFog {
|
||||
color: Color::WHITE,
|
||||
falloff: FogFalloff::Linear {
|
||||
start: 0.0,
|
||||
|
|
|
@ -57,8 +57,10 @@ pub use prepass::*;
|
|||
pub use render::*;
|
||||
pub use ssao::*;
|
||||
pub use ssr::*;
|
||||
#[allow(deprecated)]
|
||||
pub use volumetric_fog::{
|
||||
FogVolume, FogVolumeBundle, VolumetricFogPlugin, VolumetricFogSettings, VolumetricLight,
|
||||
FogVolume, FogVolumeBundle, VolumetricFog, VolumetricFogPlugin, VolumetricFogSettings,
|
||||
VolumetricLight,
|
||||
};
|
||||
|
||||
/// The PBR prelude.
|
||||
|
@ -71,7 +73,7 @@ pub mod prelude {
|
|||
DirectionalLightBundle, MaterialMeshBundle, PbrBundle, PointLightBundle,
|
||||
SpotLightBundle,
|
||||
},
|
||||
fog::{FogFalloff, FogSettings},
|
||||
fog::{DistanceFog, FogFalloff},
|
||||
light::{light_consts, AmbientLight, DirectionalLight, PointLight, SpotLight},
|
||||
light_probe::{
|
||||
environment_map::{EnvironmentMapLight, ReflectionProbeBundle},
|
||||
|
@ -303,7 +305,7 @@ impl Plugin for PbrPlugin {
|
|||
.register_type::<PointLight>()
|
||||
.register_type::<PointLightShadowMap>()
|
||||
.register_type::<SpotLight>()
|
||||
.register_type::<FogSettings>()
|
||||
.register_type::<DistanceFog>()
|
||||
.register_type::<ShadowFilteringMethod>()
|
||||
.init_resource::<AmbientLight>()
|
||||
.init_resource::<GlobalVisibleClusterableObjects>()
|
||||
|
|
|
@ -486,7 +486,7 @@ pub enum ShadowFilteringMethod {
|
|||
/// A randomized filter that varies over time, good when TAA is in use.
|
||||
///
|
||||
/// Good quality when used with
|
||||
/// [`TemporalAntiAliasSettings`](bevy_core_pipeline::experimental::taa::TemporalAntiAliasSettings)
|
||||
/// [`TemporalAntiAliasing`](bevy_core_pipeline::experimental::taa::TemporalAntiAliasing)
|
||||
/// and good performance.
|
||||
///
|
||||
/// For directional and spot lights, this uses a [method by Jorge Jimenez for
|
||||
|
|
|
@ -553,7 +553,7 @@ pub fn queue_material_meshes<M: Material>(
|
|||
Option<&Tonemapping>,
|
||||
Option<&DebandDither>,
|
||||
Option<&ShadowFilteringMethod>,
|
||||
Has<ScreenSpaceAmbientOcclusionSettings>,
|
||||
Has<ScreenSpaceAmbientOcclusion>,
|
||||
(
|
||||
Has<NormalPrepass>,
|
||||
Has<DepthPrepass>,
|
||||
|
|
|
@ -45,7 +45,7 @@ pub fn prepare_material_meshlet_meshes_main_opaque_pass<M: Material>(
|
|||
Option<&Tonemapping>,
|
||||
Option<&DebandDither>,
|
||||
Option<&ShadowFilteringMethod>,
|
||||
Has<ScreenSpaceAmbientOcclusionSettings>,
|
||||
Has<ScreenSpaceAmbientOcclusion>,
|
||||
(
|
||||
Has<NormalPrepass>,
|
||||
Has<DepthPrepass>,
|
||||
|
|
|
@ -11,7 +11,7 @@ use bevy_render::{
|
|||
Render, RenderApp, RenderSet,
|
||||
};
|
||||
|
||||
use crate::{FogFalloff, FogSettings};
|
||||
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)]
|
||||
|
@ -51,7 +51,7 @@ pub fn prepare_fog(
|
|||
render_device: Res<RenderDevice>,
|
||||
render_queue: Res<RenderQueue>,
|
||||
mut fog_meta: ResMut<FogMeta>,
|
||||
views: Query<(Entity, Option<&FogSettings>), With<ExtractedView>>,
|
||||
views: Query<(Entity, Option<&DistanceFog>), With<ExtractedView>>,
|
||||
) {
|
||||
let views_iter = views.iter();
|
||||
let view_count = views_iter.len();
|
||||
|
@ -136,8 +136,8 @@ 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::<FogSettings>();
|
||||
app.add_plugins(ExtractComponentPlugin::<FogSettings>::default());
|
||||
app.register_type::<DistanceFog>();
|
||||
app.add_plugins(ExtractComponentPlugin::<DistanceFog>::default());
|
||||
|
||||
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||
render_app
|
||||
|
|
|
@ -139,7 +139,7 @@ struct LightProbes {
|
|||
// Settings for screen space reflections.
|
||||
//
|
||||
// For more information on these settings, see the documentation for
|
||||
// `bevy_pbr::ssr::ScreenSpaceReflectionsSettings`.
|
||||
// `bevy_pbr::ssr::ScreenSpaceReflections`.
|
||||
struct ScreenSpaceReflectionsSettings {
|
||||
perceptual_roughness_threshold: f32,
|
||||
thickness: f32,
|
||||
|
|
|
@ -68,7 +68,7 @@ impl Plugin for ScreenSpaceAmbientOcclusionPlugin {
|
|||
Shader::from_wgsl
|
||||
);
|
||||
|
||||
app.register_type::<ScreenSpaceAmbientOcclusionSettings>();
|
||||
app.register_type::<ScreenSpaceAmbientOcclusion>();
|
||||
}
|
||||
|
||||
fn finish(&self, app: &mut App) {
|
||||
|
@ -129,7 +129,7 @@ impl Plugin for ScreenSpaceAmbientOcclusionPlugin {
|
|||
/// Bundle to apply screen space ambient occlusion.
|
||||
#[derive(Bundle, Default, Clone)]
|
||||
pub struct ScreenSpaceAmbientOcclusionBundle {
|
||||
pub settings: ScreenSpaceAmbientOcclusionSettings,
|
||||
pub settings: ScreenSpaceAmbientOcclusion,
|
||||
pub depth_prepass: DepthPrepass,
|
||||
pub normal_prepass: NormalPrepass,
|
||||
}
|
||||
|
@ -149,16 +149,20 @@ pub struct ScreenSpaceAmbientOcclusionBundle {
|
|||
/// and add the [`DepthPrepass`] and [`NormalPrepass`] components to your camera.
|
||||
///
|
||||
/// It strongly recommended that you use SSAO in conjunction with
|
||||
/// TAA ([`bevy_core_pipeline::experimental::taa::TemporalAntiAliasSettings`]).
|
||||
/// TAA ([`bevy_core_pipeline::experimental::taa::TemporalAntiAliasing`]).
|
||||
/// Doing so greatly reduces SSAO noise.
|
||||
///
|
||||
/// SSAO is not supported on `WebGL2`, and is not currently supported on `WebGPU` or `DirectX12`.
|
||||
#[derive(Component, ExtractComponent, Reflect, PartialEq, Eq, Hash, Clone, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
pub struct ScreenSpaceAmbientOcclusionSettings {
|
||||
#[doc(alias = "Ssao")]
|
||||
pub struct ScreenSpaceAmbientOcclusion {
|
||||
pub quality_level: ScreenSpaceAmbientOcclusionQualityLevel,
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `ScreenSpaceAmbientOcclusion`")]
|
||||
pub type ScreenSpaceAmbientOcclusionSettings = ScreenSpaceAmbientOcclusion;
|
||||
|
||||
#[derive(Reflect, PartialEq, Eq, Hash, Clone, Copy, Default, Debug)]
|
||||
pub enum ScreenSpaceAmbientOcclusionQualityLevel {
|
||||
Low,
|
||||
|
@ -444,7 +448,7 @@ impl FromWorld for SsaoPipelines {
|
|||
|
||||
#[derive(PartialEq, Eq, Hash, Clone)]
|
||||
struct SsaoPipelineKey {
|
||||
ssao_settings: ScreenSpaceAmbientOcclusionSettings,
|
||||
ssao_settings: ScreenSpaceAmbientOcclusion,
|
||||
temporal_jitter: bool,
|
||||
}
|
||||
|
||||
|
@ -484,7 +488,7 @@ fn extract_ssao_settings(
|
|||
mut commands: Commands,
|
||||
cameras: Extract<
|
||||
Query<
|
||||
(Entity, &Camera, &ScreenSpaceAmbientOcclusionSettings, &Msaa),
|
||||
(Entity, &Camera, &ScreenSpaceAmbientOcclusion, &Msaa),
|
||||
(With<Camera3d>, With<DepthPrepass>, With<NormalPrepass>),
|
||||
>,
|
||||
>,
|
||||
|
@ -516,7 +520,7 @@ fn prepare_ssao_textures(
|
|||
mut commands: Commands,
|
||||
mut texture_cache: ResMut<TextureCache>,
|
||||
render_device: Res<RenderDevice>,
|
||||
views: Query<(Entity, &ExtractedCamera), With<ScreenSpaceAmbientOcclusionSettings>>,
|
||||
views: Query<(Entity, &ExtractedCamera), With<ScreenSpaceAmbientOcclusion>>,
|
||||
) {
|
||||
for (entity, camera) in &views {
|
||||
let Some(physical_viewport_size) = camera.physical_viewport_size else {
|
||||
|
@ -603,11 +607,7 @@ fn prepare_ssao_pipelines(
|
|||
pipeline_cache: Res<PipelineCache>,
|
||||
mut pipelines: ResMut<SpecializedComputePipelines<SsaoPipelines>>,
|
||||
pipeline: Res<SsaoPipelines>,
|
||||
views: Query<(
|
||||
Entity,
|
||||
&ScreenSpaceAmbientOcclusionSettings,
|
||||
Has<TemporalJitter>,
|
||||
)>,
|
||||
views: Query<(Entity, &ScreenSpaceAmbientOcclusion, Has<TemporalJitter>)>,
|
||||
) {
|
||||
for (entity, ssao_settings, temporal_jitter) in &views {
|
||||
let pipeline_id = pipelines.specialize(
|
||||
|
|
|
@ -60,7 +60,7 @@ pub struct ScreenSpaceReflectionsPlugin;
|
|||
#[derive(Bundle, Default)]
|
||||
pub struct ScreenSpaceReflectionsBundle {
|
||||
/// The component that enables SSR.
|
||||
pub settings: ScreenSpaceReflectionsSettings,
|
||||
pub settings: ScreenSpaceReflections,
|
||||
/// The depth prepass, needed for SSR.
|
||||
pub depth_prepass: DepthPrepass,
|
||||
/// The deferred prepass, needed for SSR.
|
||||
|
@ -92,7 +92,8 @@ pub struct ScreenSpaceReflectionsBundle {
|
|||
/// which is required for screen-space raymarching.
|
||||
#[derive(Clone, Copy, Component, Reflect)]
|
||||
#[reflect(Component, Default)]
|
||||
pub struct ScreenSpaceReflectionsSettings {
|
||||
#[doc(alias = "Ssr")]
|
||||
pub struct ScreenSpaceReflections {
|
||||
/// The maximum PBR roughness level that will enable screen space
|
||||
/// reflections.
|
||||
pub perceptual_roughness_threshold: f32,
|
||||
|
@ -133,10 +134,13 @@ pub struct ScreenSpaceReflectionsSettings {
|
|||
pub use_secant: bool,
|
||||
}
|
||||
|
||||
/// A version of [`ScreenSpaceReflectionsSettings`] for upload to the GPU.
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `ScreenSpaceReflections`")]
|
||||
pub type ScreenSpaceReflectionsSettings = ScreenSpaceReflections;
|
||||
|
||||
/// A version of [`ScreenSpaceReflections`] for upload to the GPU.
|
||||
///
|
||||
/// For more information on these fields, see the corresponding documentation in
|
||||
/// [`ScreenSpaceReflectionsSettings`].
|
||||
/// [`ScreenSpaceReflections`].
|
||||
#[derive(Clone, Copy, Component, ShaderType)]
|
||||
pub struct ScreenSpaceReflectionsUniform {
|
||||
perceptual_roughness_threshold: f32,
|
||||
|
@ -195,8 +199,8 @@ impl Plugin for ScreenSpaceReflectionsPlugin {
|
|||
Shader::from_wgsl
|
||||
);
|
||||
|
||||
app.register_type::<ScreenSpaceReflectionsSettings>()
|
||||
.add_plugins(ExtractComponentPlugin::<ScreenSpaceReflectionsSettings>::default());
|
||||
app.register_type::<ScreenSpaceReflections>()
|
||||
.add_plugins(ExtractComponentPlugin::<ScreenSpaceReflections>::default());
|
||||
|
||||
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
|
||||
return;
|
||||
|
@ -234,7 +238,7 @@ impl Plugin for ScreenSpaceReflectionsPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for ScreenSpaceReflectionsSettings {
|
||||
impl Default for ScreenSpaceReflections {
|
||||
// Reasonable default values.
|
||||
//
|
||||
// These are from
|
||||
|
@ -485,8 +489,8 @@ pub fn prepare_ssr_settings(
|
|||
}
|
||||
}
|
||||
|
||||
impl ExtractComponent for ScreenSpaceReflectionsSettings {
|
||||
type QueryData = Read<ScreenSpaceReflectionsSettings>;
|
||||
impl ExtractComponent for ScreenSpaceReflections {
|
||||
type QueryData = Read<ScreenSpaceReflections>;
|
||||
|
||||
type QueryFilter = ();
|
||||
|
||||
|
@ -553,8 +557,8 @@ impl SpecializedRenderPipeline for ScreenSpaceReflectionsPipeline {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<ScreenSpaceReflectionsSettings> for ScreenSpaceReflectionsUniform {
|
||||
fn from(settings: ScreenSpaceReflectionsSettings) -> Self {
|
||||
impl From<ScreenSpaceReflections> for ScreenSpaceReflectionsUniform {
|
||||
fn from(settings: ScreenSpaceReflections) -> Self {
|
||||
Self {
|
||||
perceptual_roughness_threshold: settings.perceptual_roughness_threshold,
|
||||
thickness: settings.thickness,
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
//! for light beams from directional lights to shine through, creating what is
|
||||
//! known as *light shafts* or *god rays*.
|
||||
//!
|
||||
//! To add volumetric fog to a scene, add [`VolumetricFogSettings`] to the
|
||||
//! To add volumetric fog to a scene, add [`VolumetricFog`] to the
|
||||
//! camera, and add [`VolumetricLight`] to directional lights that you wish to
|
||||
//! be volumetric. [`VolumetricFogSettings`] feature numerous settings that
|
||||
//! be volumetric. [`VolumetricFog`] feature numerous settings that
|
||||
//! allow you to define the accuracy of the simulation, as well as the look of
|
||||
//! the fog. Currently, only interaction with directional lights that have
|
||||
//! shadow maps is supported. Note that the overhead of the effect scales
|
||||
|
@ -79,7 +79,7 @@ pub struct VolumetricLight;
|
|||
/// rays.
|
||||
#[derive(Clone, Copy, Component, Debug, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct VolumetricFogSettings {
|
||||
pub struct VolumetricFog {
|
||||
/// Color of the ambient light.
|
||||
///
|
||||
/// This is separate from Bevy's [`AmbientLight`](crate::light::AmbientLight) because an
|
||||
|
@ -115,6 +115,9 @@ pub struct VolumetricFogSettings {
|
|||
pub step_count: u32,
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.15.0", note = "Renamed to `VolumetricFog`")]
|
||||
pub type VolumetricFogSettings = VolumetricFog;
|
||||
|
||||
/// A convenient [`Bundle`] that contains all components necessary to generate a
|
||||
/// fog volume.
|
||||
#[derive(Bundle, Clone, Debug, Default)]
|
||||
|
@ -218,7 +221,7 @@ impl Plugin for VolumetricFogPlugin {
|
|||
meshes.insert(&PLANE_MESH, Plane3d::new(Vec3::Z, Vec2::ONE).mesh().into());
|
||||
meshes.insert(&CUBE_MESH, Cuboid::new(1.0, 1.0, 1.0).mesh().into());
|
||||
|
||||
app.register_type::<VolumetricFogSettings>()
|
||||
app.register_type::<VolumetricFog>()
|
||||
.register_type::<VolumetricLight>();
|
||||
|
||||
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
|
||||
|
@ -261,7 +264,7 @@ impl Plugin for VolumetricFogPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for VolumetricFogSettings {
|
||||
impl Default for VolumetricFog {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
step_count: 64,
|
||||
|
|
|
@ -47,7 +47,7 @@ use bitflags::bitflags;
|
|||
use crate::{
|
||||
FogVolume, MeshPipelineViewLayoutKey, MeshPipelineViewLayouts, MeshViewBindGroup,
|
||||
ViewEnvironmentMapUniformOffset, ViewFogUniformOffset, ViewLightProbesUniformOffset,
|
||||
ViewLightsUniformOffset, ViewScreenSpaceReflectionsUniformOffset, VolumetricFogSettings,
|
||||
ViewLightsUniformOffset, ViewScreenSpaceReflectionsUniformOffset, VolumetricFog,
|
||||
VolumetricLight,
|
||||
};
|
||||
|
||||
|
@ -152,7 +152,7 @@ pub struct VolumetricFogPipelineKey {
|
|||
flags: VolumetricFogPipelineKeyFlags,
|
||||
}
|
||||
|
||||
/// The same as [`VolumetricFogSettings`] and [`FogVolume`], but formatted for
|
||||
/// The same as [`VolumetricFog`] and [`FogVolume`], but formatted for
|
||||
/// the GPU.
|
||||
///
|
||||
/// See the documentation of those structures for more information on these
|
||||
|
@ -266,11 +266,11 @@ impl FromWorld for VolumetricFogPipeline {
|
|||
}
|
||||
}
|
||||
|
||||
/// Extracts [`VolumetricFogSettings`], [`FogVolume`], and [`VolumetricLight`]s
|
||||
/// Extracts [`VolumetricFog`], [`FogVolume`], and [`VolumetricLight`]s
|
||||
/// from the main world to the render world.
|
||||
pub fn extract_volumetric_fog(
|
||||
mut commands: Commands,
|
||||
view_targets: Extract<Query<(Entity, &VolumetricFogSettings)>>,
|
||||
view_targets: Extract<Query<(Entity, &VolumetricFog)>>,
|
||||
fog_volumes: Extract<Query<(Entity, &FogVolume, &GlobalTransform)>>,
|
||||
volumetric_lights: Extract<Query<(Entity, &VolumetricLight)>>,
|
||||
) {
|
||||
|
@ -278,10 +278,8 @@ pub fn extract_volumetric_fog(
|
|||
return;
|
||||
}
|
||||
|
||||
for (entity, volumetric_fog_settings) in view_targets.iter() {
|
||||
commands
|
||||
.get_or_spawn(entity)
|
||||
.insert(*volumetric_fog_settings);
|
||||
for (entity, volumetric_fog) in view_targets.iter() {
|
||||
commands.get_or_spawn(entity).insert(*volumetric_fog);
|
||||
}
|
||||
|
||||
for (entity, fog_volume, fog_transform) in fog_volumes.iter() {
|
||||
|
@ -606,7 +604,7 @@ pub fn prepare_volumetric_fog_pipelines(
|
|||
Has<MotionVectorPrepass>,
|
||||
Has<DeferredPrepass>,
|
||||
),
|
||||
With<VolumetricFogSettings>,
|
||||
With<VolumetricFog>,
|
||||
>,
|
||||
meshes: Res<RenderAssets<RenderMesh>>,
|
||||
) {
|
||||
|
@ -666,11 +664,11 @@ pub fn prepare_volumetric_fog_pipelines(
|
|||
}
|
||||
}
|
||||
|
||||
/// A system that converts [`VolumetricFogSettings`] into [`VolumetricFogUniform`]s.
|
||||
/// A system that converts [`VolumetricFog`] into [`VolumetricFogUniform`]s.
|
||||
pub fn prepare_volumetric_fog_uniforms(
|
||||
mut commands: Commands,
|
||||
mut volumetric_lighting_uniform_buffer: ResMut<VolumetricFogUniformBuffer>,
|
||||
view_targets: Query<(Entity, &ExtractedView, &VolumetricFogSettings)>,
|
||||
view_targets: Query<(Entity, &ExtractedView, &VolumetricFog)>,
|
||||
fog_volumes: Query<(Entity, &FogVolume, &GlobalTransform)>,
|
||||
render_device: Res<RenderDevice>,
|
||||
render_queue: Res<RenderQueue>,
|
||||
|
@ -690,7 +688,7 @@ pub fn prepare_volumetric_fog_uniforms(
|
|||
local_from_world_matrices.push(fog_transform.compute_matrix().inverse());
|
||||
}
|
||||
|
||||
for (view_entity, extracted_view, volumetric_fog_settings) in view_targets.iter() {
|
||||
for (view_entity, extracted_view, volumetric_fog) in view_targets.iter() {
|
||||
let world_from_view = extracted_view.world_from_view.compute_matrix();
|
||||
|
||||
let mut view_fog_volumes = vec![];
|
||||
|
@ -721,9 +719,9 @@ pub fn prepare_volumetric_fog_uniforms(
|
|||
far_planes: get_far_planes(&view_from_local),
|
||||
fog_color: fog_volume.fog_color.to_linear().to_vec3(),
|
||||
light_tint: fog_volume.light_tint.to_linear().to_vec3(),
|
||||
ambient_color: volumetric_fog_settings.ambient_color.to_linear().to_vec3(),
|
||||
ambient_intensity: volumetric_fog_settings.ambient_intensity,
|
||||
step_count: volumetric_fog_settings.step_count,
|
||||
ambient_color: volumetric_fog.ambient_color.to_linear().to_vec3(),
|
||||
ambient_intensity: volumetric_fog.ambient_intensity,
|
||||
step_count: volumetric_fog.step_count,
|
||||
bounding_radius,
|
||||
absorption: fog_volume.absorption,
|
||||
scattering: fog_volume.scattering,
|
||||
|
@ -731,7 +729,7 @@ pub fn prepare_volumetric_fog_uniforms(
|
|||
density_texture_offset: fog_volume.density_texture_offset,
|
||||
scattering_asymmetry: fog_volume.scattering_asymmetry,
|
||||
light_intensity: fog_volume.light_intensity,
|
||||
jitter_strength: volumetric_fog_settings.jitter,
|
||||
jitter_strength: volumetric_fog.jitter,
|
||||
});
|
||||
|
||||
view_fog_volumes.push(ViewFogVolume {
|
||||
|
@ -753,7 +751,7 @@ pub fn prepare_volumetric_fog_uniforms(
|
|||
/// default.
|
||||
pub fn prepare_view_depth_textures_for_volumetric_fog(
|
||||
mut view_targets: Query<&mut Camera3d>,
|
||||
fog_volumes: Query<&VolumetricFogSettings>,
|
||||
fog_volumes: Query<&VolumetricFog>,
|
||||
) {
|
||||
if fog_volumes.is_empty() {
|
||||
return;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
position_view_to_world
|
||||
}
|
||||
|
||||
// The GPU version of [`VolumetricFogSettings`]. See the comments in
|
||||
// The GPU version of [`VolumetricFog`]. See the comments in
|
||||
// `volumetric_fog/mod.rs` for descriptions of the fields here.
|
||||
struct VolumetricFog {
|
||||
clip_from_local: mat4x4<f32>,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use bevy::{
|
||||
core_pipeline::{
|
||||
bloom::{BloomCompositeMode, BloomSettings},
|
||||
bloom::{Bloom, BloomCompositeMode},
|
||||
tonemapping::Tonemapping,
|
||||
},
|
||||
prelude::*,
|
||||
|
@ -32,7 +32,7 @@ fn setup(
|
|||
tonemapping: Tonemapping::TonyMcMapface, // 2. Using a tonemapper that desaturates to white is recommended
|
||||
..default()
|
||||
},
|
||||
BloomSettings::default(), // 3. Enable bloom for the camera
|
||||
Bloom::default(), // 3. Enable bloom for the camera
|
||||
));
|
||||
|
||||
// Sprite
|
||||
|
@ -78,120 +78,113 @@ fn setup(
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
fn update_bloom_settings(
|
||||
mut camera: Query<(Entity, Option<&mut BloomSettings>), With<Camera>>,
|
||||
mut camera: Query<(Entity, Option<&mut Bloom>), With<Camera>>,
|
||||
mut text: Query<&mut Text>,
|
||||
mut commands: Commands,
|
||||
keycode: Res<ButtonInput<KeyCode>>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let bloom_settings = camera.single_mut();
|
||||
let bloom = camera.single_mut();
|
||||
let mut text = text.single_mut();
|
||||
let text = &mut text.sections[0].value;
|
||||
|
||||
match bloom_settings {
|
||||
(entity, Some(mut bloom_settings)) => {
|
||||
*text = "BloomSettings (Toggle: Space)\n".to_string();
|
||||
text.push_str(&format!("(Q/A) Intensity: {}\n", bloom_settings.intensity));
|
||||
match bloom {
|
||||
(entity, Some(mut bloom)) => {
|
||||
*text = "Bloom (Toggle: Space)\n".to_string();
|
||||
text.push_str(&format!("(Q/A) Intensity: {}\n", bloom.intensity));
|
||||
text.push_str(&format!(
|
||||
"(W/S) Low-frequency boost: {}\n",
|
||||
bloom_settings.low_frequency_boost
|
||||
bloom.low_frequency_boost
|
||||
));
|
||||
text.push_str(&format!(
|
||||
"(E/D) Low-frequency boost curvature: {}\n",
|
||||
bloom_settings.low_frequency_boost_curvature
|
||||
bloom.low_frequency_boost_curvature
|
||||
));
|
||||
text.push_str(&format!(
|
||||
"(R/F) High-pass frequency: {}\n",
|
||||
bloom_settings.high_pass_frequency
|
||||
bloom.high_pass_frequency
|
||||
));
|
||||
text.push_str(&format!(
|
||||
"(T/G) Mode: {}\n",
|
||||
match bloom_settings.composite_mode {
|
||||
match bloom.composite_mode {
|
||||
BloomCompositeMode::EnergyConserving => "Energy-conserving",
|
||||
BloomCompositeMode::Additive => "Additive",
|
||||
}
|
||||
));
|
||||
text.push_str(&format!(
|
||||
"(Y/H) Threshold: {}\n",
|
||||
bloom_settings.prefilter_settings.threshold
|
||||
));
|
||||
text.push_str(&format!("(Y/H) Threshold: {}\n", bloom.prefilter.threshold));
|
||||
text.push_str(&format!(
|
||||
"(U/J) Threshold softness: {}\n",
|
||||
bloom_settings.prefilter_settings.threshold_softness
|
||||
bloom.prefilter.threshold_softness
|
||||
));
|
||||
|
||||
if keycode.just_pressed(KeyCode::Space) {
|
||||
commands.entity(entity).remove::<BloomSettings>();
|
||||
commands.entity(entity).remove::<Bloom>();
|
||||
}
|
||||
|
||||
let dt = time.delta_seconds();
|
||||
|
||||
if keycode.pressed(KeyCode::KeyA) {
|
||||
bloom_settings.intensity -= dt / 10.0;
|
||||
bloom.intensity -= dt / 10.0;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyQ) {
|
||||
bloom_settings.intensity += dt / 10.0;
|
||||
bloom.intensity += dt / 10.0;
|
||||
}
|
||||
bloom_settings.intensity = bloom_settings.intensity.clamp(0.0, 1.0);
|
||||
bloom.intensity = bloom.intensity.clamp(0.0, 1.0);
|
||||
|
||||
if keycode.pressed(KeyCode::KeyS) {
|
||||
bloom_settings.low_frequency_boost -= dt / 10.0;
|
||||
bloom.low_frequency_boost -= dt / 10.0;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyW) {
|
||||
bloom_settings.low_frequency_boost += dt / 10.0;
|
||||
bloom.low_frequency_boost += dt / 10.0;
|
||||
}
|
||||
bloom_settings.low_frequency_boost = bloom_settings.low_frequency_boost.clamp(0.0, 1.0);
|
||||
bloom.low_frequency_boost = bloom.low_frequency_boost.clamp(0.0, 1.0);
|
||||
|
||||
if keycode.pressed(KeyCode::KeyD) {
|
||||
bloom_settings.low_frequency_boost_curvature -= dt / 10.0;
|
||||
bloom.low_frequency_boost_curvature -= dt / 10.0;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyE) {
|
||||
bloom_settings.low_frequency_boost_curvature += dt / 10.0;
|
||||
bloom.low_frequency_boost_curvature += dt / 10.0;
|
||||
}
|
||||
bloom_settings.low_frequency_boost_curvature =
|
||||
bloom_settings.low_frequency_boost_curvature.clamp(0.0, 1.0);
|
||||
bloom.low_frequency_boost_curvature =
|
||||
bloom.low_frequency_boost_curvature.clamp(0.0, 1.0);
|
||||
|
||||
if keycode.pressed(KeyCode::KeyF) {
|
||||
bloom_settings.high_pass_frequency -= dt / 10.0;
|
||||
bloom.high_pass_frequency -= dt / 10.0;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyR) {
|
||||
bloom_settings.high_pass_frequency += dt / 10.0;
|
||||
bloom.high_pass_frequency += dt / 10.0;
|
||||
}
|
||||
bloom_settings.high_pass_frequency = bloom_settings.high_pass_frequency.clamp(0.0, 1.0);
|
||||
bloom.high_pass_frequency = bloom.high_pass_frequency.clamp(0.0, 1.0);
|
||||
|
||||
if keycode.pressed(KeyCode::KeyG) {
|
||||
bloom_settings.composite_mode = BloomCompositeMode::Additive;
|
||||
bloom.composite_mode = BloomCompositeMode::Additive;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyT) {
|
||||
bloom_settings.composite_mode = BloomCompositeMode::EnergyConserving;
|
||||
bloom.composite_mode = BloomCompositeMode::EnergyConserving;
|
||||
}
|
||||
|
||||
if keycode.pressed(KeyCode::KeyH) {
|
||||
bloom_settings.prefilter_settings.threshold -= dt;
|
||||
bloom.prefilter.threshold -= dt;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyY) {
|
||||
bloom_settings.prefilter_settings.threshold += dt;
|
||||
bloom.prefilter.threshold += dt;
|
||||
}
|
||||
bloom_settings.prefilter_settings.threshold =
|
||||
bloom_settings.prefilter_settings.threshold.max(0.0);
|
||||
bloom.prefilter.threshold = bloom.prefilter.threshold.max(0.0);
|
||||
|
||||
if keycode.pressed(KeyCode::KeyJ) {
|
||||
bloom_settings.prefilter_settings.threshold_softness -= dt / 10.0;
|
||||
bloom.prefilter.threshold_softness -= dt / 10.0;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyU) {
|
||||
bloom_settings.prefilter_settings.threshold_softness += dt / 10.0;
|
||||
bloom.prefilter.threshold_softness += dt / 10.0;
|
||||
}
|
||||
bloom_settings.prefilter_settings.threshold_softness = bloom_settings
|
||||
.prefilter_settings
|
||||
.threshold_softness
|
||||
.clamp(0.0, 1.0);
|
||||
bloom.prefilter.threshold_softness = bloom.prefilter.threshold_softness.clamp(0.0, 1.0);
|
||||
}
|
||||
|
||||
(entity, None) => {
|
||||
*text = "Bloom: Off (Toggle: Space)".to_string();
|
||||
|
||||
if keycode.just_pressed(KeyCode::Space) {
|
||||
commands.entity(entity).insert(BloomSettings::default());
|
||||
commands.entity(entity).insert(Bloom::default());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@ use std::fmt::Write;
|
|||
|
||||
use bevy::{
|
||||
core_pipeline::{
|
||||
contrast_adaptive_sharpening::ContrastAdaptiveSharpeningSettings,
|
||||
contrast_adaptive_sharpening::ContrastAdaptiveSharpening,
|
||||
experimental::taa::{
|
||||
TemporalAntiAliasBundle, TemporalAntiAliasPlugin, TemporalAntiAliasSettings,
|
||||
TemporalAntiAliasBundle, TemporalAntiAliasPlugin, TemporalAntiAliasing,
|
||||
},
|
||||
fxaa::{Fxaa, Sensitivity},
|
||||
smaa::{SmaaPreset, SmaaSettings},
|
||||
smaa::{Smaa, SmaaPreset},
|
||||
},
|
||||
pbr::CascadeShadowConfigBuilder,
|
||||
prelude::*,
|
||||
|
@ -35,8 +35,8 @@ fn modify_aa(
|
|||
(
|
||||
Entity,
|
||||
Option<&mut Fxaa>,
|
||||
Option<&mut SmaaSettings>,
|
||||
Option<&TemporalAntiAliasSettings>,
|
||||
Option<&mut Smaa>,
|
||||
Option<&TemporalAntiAliasing>,
|
||||
&mut Msaa,
|
||||
),
|
||||
With<Camera>,
|
||||
|
@ -51,7 +51,7 @@ fn modify_aa(
|
|||
*msaa = Msaa::Off;
|
||||
camera = camera
|
||||
.remove::<Fxaa>()
|
||||
.remove::<SmaaSettings>()
|
||||
.remove::<Smaa>()
|
||||
.remove::<TemporalAntiAliasBundle>();
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ fn modify_aa(
|
|||
if keys.just_pressed(KeyCode::Digit2) && *msaa == Msaa::Off {
|
||||
camera = camera
|
||||
.remove::<Fxaa>()
|
||||
.remove::<SmaaSettings>()
|
||||
.remove::<Smaa>()
|
||||
.remove::<TemporalAntiAliasBundle>();
|
||||
|
||||
*msaa = Msaa::Sample4;
|
||||
|
@ -82,7 +82,7 @@ fn modify_aa(
|
|||
if keys.just_pressed(KeyCode::Digit3) && fxaa.is_none() {
|
||||
*msaa = Msaa::Off;
|
||||
camera = camera
|
||||
.remove::<SmaaSettings>()
|
||||
.remove::<Smaa>()
|
||||
.remove::<TemporalAntiAliasBundle>()
|
||||
.insert(Fxaa::default());
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ fn modify_aa(
|
|||
camera = camera
|
||||
.remove::<Fxaa>()
|
||||
.remove::<TemporalAntiAliasBundle>()
|
||||
.insert(SmaaSettings::default());
|
||||
.insert(Smaa::default());
|
||||
}
|
||||
|
||||
// SMAA Settings
|
||||
|
@ -141,14 +141,14 @@ fn modify_aa(
|
|||
*msaa = Msaa::Off;
|
||||
camera
|
||||
.remove::<Fxaa>()
|
||||
.remove::<SmaaSettings>()
|
||||
.remove::<Smaa>()
|
||||
.insert(TemporalAntiAliasBundle::default());
|
||||
}
|
||||
}
|
||||
|
||||
fn modify_sharpening(
|
||||
keys: Res<ButtonInput<KeyCode>>,
|
||||
mut query: Query<&mut ContrastAdaptiveSharpeningSettings>,
|
||||
mut query: Query<&mut ContrastAdaptiveSharpening>,
|
||||
) {
|
||||
for mut cas in &mut query {
|
||||
if keys.just_pressed(KeyCode::Digit0) {
|
||||
|
@ -174,16 +174,16 @@ fn update_ui(
|
|||
camera: Query<
|
||||
(
|
||||
Option<&Fxaa>,
|
||||
Option<&SmaaSettings>,
|
||||
Option<&TemporalAntiAliasSettings>,
|
||||
&ContrastAdaptiveSharpeningSettings,
|
||||
Option<&Smaa>,
|
||||
Option<&TemporalAntiAliasing>,
|
||||
&ContrastAdaptiveSharpening,
|
||||
&Msaa,
|
||||
),
|
||||
With<Camera>,
|
||||
>,
|
||||
mut ui: Query<&mut Text>,
|
||||
) {
|
||||
let (fxaa, smaa, taa, cas_settings, msaa) = camera.single();
|
||||
let (fxaa, smaa, taa, cas, msaa) = camera.single();
|
||||
|
||||
let mut ui = ui.single_mut();
|
||||
let ui = &mut ui.sections[0].value;
|
||||
|
@ -236,14 +236,11 @@ fn update_ui(
|
|||
}
|
||||
|
||||
ui.push_str("\n----------\n\n");
|
||||
draw_selectable_menu_item(ui, "Sharpening", '0', cas_settings.enabled);
|
||||
draw_selectable_menu_item(ui, "Sharpening", '0', cas.enabled);
|
||||
|
||||
if cas_settings.enabled {
|
||||
ui.push_str(&format!(
|
||||
"(-/+) Strength: {:.1}\n",
|
||||
cas_settings.sharpening_strength
|
||||
));
|
||||
draw_selectable_menu_item(ui, "Denoising", 'D', cas_settings.denoise);
|
||||
if cas.enabled {
|
||||
ui.push_str(&format!("(-/+) Strength: {:.1}\n", cas.sharpening_strength));
|
||||
draw_selectable_menu_item(ui, "Denoising", 'D', cas.denoise);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,7 +314,7 @@ fn setup(
|
|||
.looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
|
||||
..default()
|
||||
},
|
||||
ContrastAdaptiveSharpeningSettings {
|
||||
ContrastAdaptiveSharpening {
|
||||
enabled: false,
|
||||
..default()
|
||||
},
|
||||
|
@ -327,7 +324,7 @@ fn setup(
|
|||
intensity: 150.0,
|
||||
..default()
|
||||
},
|
||||
FogSettings {
|
||||
DistanceFog {
|
||||
color: Color::srgba_u8(43, 44, 47, 255),
|
||||
falloff: FogFalloff::Linear {
|
||||
start: 1.0,
|
||||
|
|
|
@ -30,7 +30,7 @@ fn setup_camera_fog(mut commands: Commands) {
|
|||
.looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y),
|
||||
..default()
|
||||
},
|
||||
FogSettings {
|
||||
DistanceFog {
|
||||
color: Color::srgba(0.35, 0.48, 0.66, 1.0),
|
||||
directional_light_color: Color::srgba(1.0, 0.95, 0.85, 0.5),
|
||||
directional_light_exponent: 30.0,
|
||||
|
@ -109,16 +109,16 @@ fn setup_instructions(mut commands: Commands) {
|
|||
);
|
||||
}
|
||||
|
||||
fn toggle_system(keycode: Res<ButtonInput<KeyCode>>, mut fog: Query<&mut FogSettings>) {
|
||||
let mut fog_settings = fog.single_mut();
|
||||
fn toggle_system(keycode: Res<ButtonInput<KeyCode>>, mut fog: Query<&mut DistanceFog>) {
|
||||
let mut fog = fog.single_mut();
|
||||
|
||||
if keycode.just_pressed(KeyCode::Space) {
|
||||
let a = fog_settings.color.alpha();
|
||||
fog_settings.color.set_alpha(1.0 - a);
|
||||
let a = fog.color.alpha();
|
||||
fog.color.set_alpha(1.0 - a);
|
||||
}
|
||||
|
||||
if keycode.just_pressed(KeyCode::KeyS) {
|
||||
let a = fog_settings.directional_light_color.alpha();
|
||||
fog_settings.directional_light_color.set_alpha(0.5 - a);
|
||||
let a = fog.directional_light_color.alpha();
|
||||
fog.directional_light_color.set_alpha(0.5 - a);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
use bevy::{
|
||||
core_pipeline::{
|
||||
auto_exposure::{AutoExposureCompensationCurve, AutoExposurePlugin, AutoExposureSettings},
|
||||
auto_exposure::{AutoExposure, AutoExposureCompensationCurve, AutoExposurePlugin},
|
||||
Skybox,
|
||||
},
|
||||
math::{cubic_splines::LinearSpline, primitives::Plane3d, vec2},
|
||||
|
@ -47,7 +47,7 @@ fn setup(
|
|||
transform: Transform::from_xyz(1.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
..default()
|
||||
},
|
||||
AutoExposureSettings {
|
||||
AutoExposure {
|
||||
metering_mask: metering_mask.clone(),
|
||||
..default()
|
||||
},
|
||||
|
@ -168,7 +168,7 @@ struct ExampleResources {
|
|||
}
|
||||
|
||||
fn example_control_system(
|
||||
mut camera: Query<(&mut Transform, &mut AutoExposureSettings), With<Camera3d>>,
|
||||
mut camera: Query<(&mut Transform, &mut AutoExposure), With<Camera3d>>,
|
||||
mut display: Query<&mut Text, With<ExampleDisplay>>,
|
||||
mut mask_image: Query<&mut Style, With<UiImage>>,
|
||||
time: Res<Time>,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use bevy::{
|
||||
color::palettes::basic::GRAY,
|
||||
core_pipeline::{
|
||||
bloom::{BloomCompositeMode, BloomSettings},
|
||||
bloom::{Bloom, BloomCompositeMode},
|
||||
tonemapping::Tonemapping,
|
||||
},
|
||||
prelude::*,
|
||||
|
@ -37,7 +37,7 @@ fn setup_scene(
|
|||
..default()
|
||||
},
|
||||
// 3. Enable bloom for the camera
|
||||
BloomSettings::NATURAL,
|
||||
Bloom::NATURAL,
|
||||
));
|
||||
|
||||
let material_emissive1 = materials.add(StandardMaterial {
|
||||
|
@ -101,120 +101,113 @@ fn setup_scene(
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
fn update_bloom_settings(
|
||||
mut camera: Query<(Entity, Option<&mut BloomSettings>), With<Camera>>,
|
||||
mut camera: Query<(Entity, Option<&mut Bloom>), With<Camera>>,
|
||||
mut text: Query<&mut Text>,
|
||||
mut commands: Commands,
|
||||
keycode: Res<ButtonInput<KeyCode>>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let bloom_settings = camera.single_mut();
|
||||
let bloom = camera.single_mut();
|
||||
let mut text = text.single_mut();
|
||||
let text = &mut text.sections[0].value;
|
||||
|
||||
match bloom_settings {
|
||||
(entity, Some(mut bloom_settings)) => {
|
||||
*text = "BloomSettings (Toggle: Space)\n".to_string();
|
||||
text.push_str(&format!("(Q/A) Intensity: {}\n", bloom_settings.intensity));
|
||||
match bloom {
|
||||
(entity, Some(mut bloom)) => {
|
||||
*text = "Bloom (Toggle: Space)\n".to_string();
|
||||
text.push_str(&format!("(Q/A) Intensity: {}\n", bloom.intensity));
|
||||
text.push_str(&format!(
|
||||
"(W/S) Low-frequency boost: {}\n",
|
||||
bloom_settings.low_frequency_boost
|
||||
bloom.low_frequency_boost
|
||||
));
|
||||
text.push_str(&format!(
|
||||
"(E/D) Low-frequency boost curvature: {}\n",
|
||||
bloom_settings.low_frequency_boost_curvature
|
||||
bloom.low_frequency_boost_curvature
|
||||
));
|
||||
text.push_str(&format!(
|
||||
"(R/F) High-pass frequency: {}\n",
|
||||
bloom_settings.high_pass_frequency
|
||||
bloom.high_pass_frequency
|
||||
));
|
||||
text.push_str(&format!(
|
||||
"(T/G) Mode: {}\n",
|
||||
match bloom_settings.composite_mode {
|
||||
match bloom.composite_mode {
|
||||
BloomCompositeMode::EnergyConserving => "Energy-conserving",
|
||||
BloomCompositeMode::Additive => "Additive",
|
||||
}
|
||||
));
|
||||
text.push_str(&format!(
|
||||
"(Y/H) Threshold: {}\n",
|
||||
bloom_settings.prefilter_settings.threshold
|
||||
));
|
||||
text.push_str(&format!("(Y/H) Threshold: {}\n", bloom.prefilter.threshold));
|
||||
text.push_str(&format!(
|
||||
"(U/J) Threshold softness: {}\n",
|
||||
bloom_settings.prefilter_settings.threshold_softness
|
||||
bloom.prefilter.threshold_softness
|
||||
));
|
||||
|
||||
if keycode.just_pressed(KeyCode::Space) {
|
||||
commands.entity(entity).remove::<BloomSettings>();
|
||||
commands.entity(entity).remove::<Bloom>();
|
||||
}
|
||||
|
||||
let dt = time.delta_seconds();
|
||||
|
||||
if keycode.pressed(KeyCode::KeyA) {
|
||||
bloom_settings.intensity -= dt / 10.0;
|
||||
bloom.intensity -= dt / 10.0;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyQ) {
|
||||
bloom_settings.intensity += dt / 10.0;
|
||||
bloom.intensity += dt / 10.0;
|
||||
}
|
||||
bloom_settings.intensity = bloom_settings.intensity.clamp(0.0, 1.0);
|
||||
bloom.intensity = bloom.intensity.clamp(0.0, 1.0);
|
||||
|
||||
if keycode.pressed(KeyCode::KeyS) {
|
||||
bloom_settings.low_frequency_boost -= dt / 10.0;
|
||||
bloom.low_frequency_boost -= dt / 10.0;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyW) {
|
||||
bloom_settings.low_frequency_boost += dt / 10.0;
|
||||
bloom.low_frequency_boost += dt / 10.0;
|
||||
}
|
||||
bloom_settings.low_frequency_boost = bloom_settings.low_frequency_boost.clamp(0.0, 1.0);
|
||||
bloom.low_frequency_boost = bloom.low_frequency_boost.clamp(0.0, 1.0);
|
||||
|
||||
if keycode.pressed(KeyCode::KeyD) {
|
||||
bloom_settings.low_frequency_boost_curvature -= dt / 10.0;
|
||||
bloom.low_frequency_boost_curvature -= dt / 10.0;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyE) {
|
||||
bloom_settings.low_frequency_boost_curvature += dt / 10.0;
|
||||
bloom.low_frequency_boost_curvature += dt / 10.0;
|
||||
}
|
||||
bloom_settings.low_frequency_boost_curvature =
|
||||
bloom_settings.low_frequency_boost_curvature.clamp(0.0, 1.0);
|
||||
bloom.low_frequency_boost_curvature =
|
||||
bloom.low_frequency_boost_curvature.clamp(0.0, 1.0);
|
||||
|
||||
if keycode.pressed(KeyCode::KeyF) {
|
||||
bloom_settings.high_pass_frequency -= dt / 10.0;
|
||||
bloom.high_pass_frequency -= dt / 10.0;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyR) {
|
||||
bloom_settings.high_pass_frequency += dt / 10.0;
|
||||
bloom.high_pass_frequency += dt / 10.0;
|
||||
}
|
||||
bloom_settings.high_pass_frequency = bloom_settings.high_pass_frequency.clamp(0.0, 1.0);
|
||||
bloom.high_pass_frequency = bloom.high_pass_frequency.clamp(0.0, 1.0);
|
||||
|
||||
if keycode.pressed(KeyCode::KeyG) {
|
||||
bloom_settings.composite_mode = BloomCompositeMode::Additive;
|
||||
bloom.composite_mode = BloomCompositeMode::Additive;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyT) {
|
||||
bloom_settings.composite_mode = BloomCompositeMode::EnergyConserving;
|
||||
bloom.composite_mode = BloomCompositeMode::EnergyConserving;
|
||||
}
|
||||
|
||||
if keycode.pressed(KeyCode::KeyH) {
|
||||
bloom_settings.prefilter_settings.threshold -= dt;
|
||||
bloom.prefilter.threshold -= dt;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyY) {
|
||||
bloom_settings.prefilter_settings.threshold += dt;
|
||||
bloom.prefilter.threshold += dt;
|
||||
}
|
||||
bloom_settings.prefilter_settings.threshold =
|
||||
bloom_settings.prefilter_settings.threshold.max(0.0);
|
||||
bloom.prefilter.threshold = bloom.prefilter.threshold.max(0.0);
|
||||
|
||||
if keycode.pressed(KeyCode::KeyJ) {
|
||||
bloom_settings.prefilter_settings.threshold_softness -= dt / 10.0;
|
||||
bloom.prefilter.threshold_softness -= dt / 10.0;
|
||||
}
|
||||
if keycode.pressed(KeyCode::KeyU) {
|
||||
bloom_settings.prefilter_settings.threshold_softness += dt / 10.0;
|
||||
bloom.prefilter.threshold_softness += dt / 10.0;
|
||||
}
|
||||
bloom_settings.prefilter_settings.threshold_softness = bloom_settings
|
||||
.prefilter_settings
|
||||
.threshold_softness
|
||||
.clamp(0.0, 1.0);
|
||||
bloom.prefilter.threshold_softness = bloom.prefilter.threshold_softness.clamp(0.0, 1.0);
|
||||
}
|
||||
|
||||
(entity, None) => {
|
||||
*text = "Bloom: Off (Toggle: Space)".to_string();
|
||||
|
||||
if keycode.just_pressed(KeyCode::Space) {
|
||||
commands.entity(entity).insert(BloomSettings::NATURAL);
|
||||
commands.entity(entity).insert(Bloom::NATURAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -362,7 +362,7 @@ fn add_camera(commands: &mut Commands, asset_server: &AssetServer, color_grading
|
|||
color_grading,
|
||||
..default()
|
||||
},
|
||||
FogSettings {
|
||||
DistanceFog {
|
||||
color: Color::srgb_u8(43, 44, 47),
|
||||
falloff: FogFalloff::Linear {
|
||||
start: 1.0,
|
||||
|
|
|
@ -45,7 +45,7 @@ fn setup(
|
|||
msaa: Msaa::Off,
|
||||
..default()
|
||||
},
|
||||
FogSettings {
|
||||
DistanceFog {
|
||||
color: Color::srgb_u8(43, 44, 47),
|
||||
falloff: FogFalloff::Linear {
|
||||
start: 1.0,
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
use bevy::{
|
||||
core_pipeline::{
|
||||
bloom::BloomSettings,
|
||||
dof::{self, DepthOfFieldMode, DepthOfFieldSettings},
|
||||
bloom::Bloom,
|
||||
dof::{self, DepthOfField, DepthOfFieldMode},
|
||||
tonemapping::Tonemapping,
|
||||
},
|
||||
pbr::Lightmap,
|
||||
|
@ -80,11 +80,11 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_settings: R
|
|||
tonemapping: Tonemapping::TonyMcMapface,
|
||||
..default()
|
||||
})
|
||||
.insert(BloomSettings::NATURAL);
|
||||
.insert(Bloom::NATURAL);
|
||||
|
||||
// Insert the depth of field settings.
|
||||
if let Some(dof_settings) = Option::<DepthOfFieldSettings>::from(*app_settings) {
|
||||
camera.insert(dof_settings);
|
||||
if let Some(depth_of_field) = Option::<DepthOfField>::from(*app_settings) {
|
||||
camera.insert(depth_of_field);
|
||||
}
|
||||
|
||||
// Spawn the scene.
|
||||
|
@ -174,14 +174,14 @@ fn update_dof_settings(
|
|||
view_targets: Query<Entity, With<Camera>>,
|
||||
app_settings: Res<AppSettings>,
|
||||
) {
|
||||
let dof_settings: Option<DepthOfFieldSettings> = (*app_settings).into();
|
||||
let depth_of_field: Option<DepthOfField> = (*app_settings).into();
|
||||
for view in view_targets.iter() {
|
||||
match dof_settings {
|
||||
match depth_of_field {
|
||||
None => {
|
||||
commands.entity(view).remove::<DepthOfFieldSettings>();
|
||||
commands.entity(view).remove::<DepthOfField>();
|
||||
}
|
||||
Some(dof_settings) => {
|
||||
commands.entity(view).insert(dof_settings);
|
||||
Some(depth_of_field) => {
|
||||
commands.entity(view).insert(depth_of_field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -227,9 +227,9 @@ fn create_text(app_settings: &AppSettings) -> Text {
|
|||
Text::from_section(app_settings.help_text(), TextStyle::default())
|
||||
}
|
||||
|
||||
impl From<AppSettings> for Option<DepthOfFieldSettings> {
|
||||
impl From<AppSettings> for Option<DepthOfField> {
|
||||
fn from(app_settings: AppSettings) -> Self {
|
||||
app_settings.mode.map(|mode| DepthOfFieldSettings {
|
||||
app_settings.mode.map(|mode| DepthOfField {
|
||||
mode,
|
||||
focal_distance: app_settings.focal_distance,
|
||||
aperture_f_stops: app_settings.aperture_f_stops,
|
||||
|
|
|
@ -34,7 +34,7 @@ fn main() {
|
|||
fn setup_camera_fog(mut commands: Commands) {
|
||||
commands.spawn((
|
||||
Camera3dBundle::default(),
|
||||
FogSettings {
|
||||
DistanceFog {
|
||||
color: Color::srgb(0.25, 0.25, 0.25),
|
||||
falloff: FogFalloff::Linear {
|
||||
start: 5.0,
|
||||
|
@ -134,7 +134,7 @@ fn setup_instructions(mut commands: Commands) {
|
|||
}
|
||||
|
||||
fn update_system(
|
||||
mut camera: Query<(&mut FogSettings, &mut Transform)>,
|
||||
mut camera: Query<(&mut DistanceFog, &mut Transform)>,
|
||||
mut text: Query<&mut Text>,
|
||||
time: Res<Time>,
|
||||
keycode: Res<ButtonInput<KeyCode>>,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
use bevy::{
|
||||
math::vec3,
|
||||
pbr::{FogVolume, VolumetricFogSettings, VolumetricLight},
|
||||
pbr::{FogVolume, VolumetricFog, VolumetricLight},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
|
@ -70,7 +70,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
},
|
||||
..default()
|
||||
})
|
||||
.insert(VolumetricFogSettings {
|
||||
.insert(VolumetricFog {
|
||||
// Make this relatively high in order to increase the fog quality.
|
||||
step_count: 64,
|
||||
// Disable ambient light.
|
||||
|
|
|
@ -271,31 +271,31 @@ fn setup_ui(mut commands: Commands) {
|
|||
}
|
||||
|
||||
fn keyboard_inputs(
|
||||
mut settings: Query<&mut MotionBlur>,
|
||||
mut motion_blur: Query<&mut MotionBlur>,
|
||||
presses: Res<ButtonInput<KeyCode>>,
|
||||
mut text: Query<&mut Text>,
|
||||
mut camera: ResMut<CameraMode>,
|
||||
) {
|
||||
let mut settings = settings.single_mut();
|
||||
let mut motion_blur = motion_blur.single_mut();
|
||||
if presses.just_pressed(KeyCode::Digit1) {
|
||||
settings.shutter_angle -= 0.25;
|
||||
motion_blur.shutter_angle -= 0.25;
|
||||
} else if presses.just_pressed(KeyCode::Digit2) {
|
||||
settings.shutter_angle += 0.25;
|
||||
motion_blur.shutter_angle += 0.25;
|
||||
} else if presses.just_pressed(KeyCode::Digit3) {
|
||||
settings.samples = settings.samples.saturating_sub(1);
|
||||
motion_blur.samples = motion_blur.samples.saturating_sub(1);
|
||||
} else if presses.just_pressed(KeyCode::Digit4) {
|
||||
settings.samples += 1;
|
||||
motion_blur.samples += 1;
|
||||
} else if presses.just_pressed(KeyCode::Space) {
|
||||
*camera = match *camera {
|
||||
CameraMode::Track => CameraMode::Chase,
|
||||
CameraMode::Chase => CameraMode::Track,
|
||||
};
|
||||
}
|
||||
settings.shutter_angle = settings.shutter_angle.clamp(0.0, 1.0);
|
||||
settings.samples = settings.samples.clamp(0, 64);
|
||||
motion_blur.shutter_angle = motion_blur.shutter_angle.clamp(0.0, 1.0);
|
||||
motion_blur.samples = motion_blur.samples.clamp(0, 64);
|
||||
let mut text = text.single_mut();
|
||||
text.sections[0].value = format!("Shutter angle: {:.2}\n", settings.shutter_angle);
|
||||
text.sections[1].value = format!("Samples: {:.5}\n", settings.samples);
|
||||
text.sections[0].value = format!("Shutter angle: {:.2}\n", motion_blur.shutter_angle);
|
||||
text.sections[1].value = format!("Samples: {:.5}\n", motion_blur.samples);
|
||||
}
|
||||
|
||||
/// Parametric function for a looping race track. `offset` will return the point offset
|
||||
|
|
|
@ -68,7 +68,7 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
|
|||
.looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
|
||||
..default()
|
||||
},
|
||||
FogSettings {
|
||||
DistanceFog {
|
||||
color: Color::srgb_u8(43, 44, 47),
|
||||
falloff: FogFalloff::Linear {
|
||||
start: 1.0,
|
||||
|
@ -188,7 +188,7 @@ fn handle_keyboard_input(mut app_settings: ResMut<AppSettings>, input: Res<Butto
|
|||
|
||||
/// Updates the [`ChromaticAberration`] settings per the [`AppSettings`].
|
||||
fn update_chromatic_aberration_settings(
|
||||
mut chromatic_aberration_settings: Query<&mut ChromaticAberration>,
|
||||
mut chromatic_aberration: Query<&mut ChromaticAberration>,
|
||||
app_settings: Res<AppSettings>,
|
||||
) {
|
||||
let intensity = app_settings.chromatic_aberration_intensity;
|
||||
|
@ -202,9 +202,9 @@ fn update_chromatic_aberration_settings(
|
|||
.clamp(8.0, 64.0)
|
||||
.round() as u32;
|
||||
|
||||
for mut chromatic_aberration_settings in &mut chromatic_aberration_settings {
|
||||
chromatic_aberration_settings.intensity = intensity;
|
||||
chromatic_aberration_settings.max_samples = max_samples;
|
||||
for mut chromatic_aberration in &mut chromatic_aberration {
|
||||
chromatic_aberration.intensity = intensity;
|
||||
chromatic_aberration.max_samples = max_samples;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
//! The density texture is a repeating 3d noise texture and the `density_texture_offset`
|
||||
//! is moved every frame to achieve this.
|
||||
//!
|
||||
//! The example also utilizes the jitter option of `VolumetricFogSettings` in tandem
|
||||
//! The example also utilizes the jitter option of `VolumetricFog` in tandem
|
||||
//! 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::BloomSettings;
|
||||
use bevy::core_pipeline::bloom::Bloom;
|
||||
use bevy::core_pipeline::experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin};
|
||||
use bevy::pbr::{DirectionalLightShadowMap, FogVolume, VolumetricFogSettings, VolumetricLight};
|
||||
use bevy::pbr::{DirectionalLightShadowMap, FogVolume, VolumetricFog, VolumetricLight};
|
||||
use bevy::prelude::*;
|
||||
use bevy_render::texture::{
|
||||
ImageAddressMode, ImageFilterMode, ImageLoaderSettings, ImageSampler, ImageSamplerDescriptor,
|
||||
|
@ -42,7 +42,7 @@ fn setup(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
assets: Res<AssetServer>,
|
||||
) {
|
||||
// Spawn camera with temporal anti-aliasing and a VolumetricFogSettings configuration.
|
||||
// Spawn camera with temporal anti-aliasing and a VolumetricFog configuration.
|
||||
commands.spawn((
|
||||
Camera3dBundle {
|
||||
transform: Transform::from_xyz(0.0, 2.0, 0.0)
|
||||
|
@ -55,8 +55,8 @@ fn setup(
|
|||
..default()
|
||||
},
|
||||
TemporalAntiAliasBundle::default(),
|
||||
BloomSettings::default(),
|
||||
VolumetricFogSettings {
|
||||
Bloom::default(),
|
||||
VolumetricFog {
|
||||
ambient_intensity: 0.0,
|
||||
jitter: 0.5,
|
||||
..default()
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
use bevy::{
|
||||
core_pipeline::experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin},
|
||||
pbr::{
|
||||
ScreenSpaceAmbientOcclusionBundle, ScreenSpaceAmbientOcclusionQualityLevel,
|
||||
ScreenSpaceAmbientOcclusionSettings,
|
||||
ScreenSpaceAmbientOcclusion, ScreenSpaceAmbientOcclusionBundle,
|
||||
ScreenSpaceAmbientOcclusionQualityLevel,
|
||||
},
|
||||
prelude::*,
|
||||
render::camera::TemporalJitter,
|
||||
|
@ -107,7 +107,7 @@ fn update(
|
|||
camera: Query<
|
||||
(
|
||||
Entity,
|
||||
Option<&ScreenSpaceAmbientOcclusionSettings>,
|
||||
Option<&ScreenSpaceAmbientOcclusion>,
|
||||
Option<&TemporalJitter>,
|
||||
),
|
||||
With<Camera>,
|
||||
|
@ -121,36 +121,36 @@ fn update(
|
|||
let mut sphere = sphere.single_mut();
|
||||
sphere.translation.y = (time.elapsed_seconds() / 1.7).sin() * 0.7;
|
||||
|
||||
let (camera_entity, ssao_settings, temporal_jitter) = camera.single();
|
||||
let (camera_entity, ssao, temporal_jitter) = camera.single();
|
||||
|
||||
let mut commands = commands
|
||||
.entity(camera_entity)
|
||||
.insert_if(
|
||||
ScreenSpaceAmbientOcclusionSettings {
|
||||
ScreenSpaceAmbientOcclusion {
|
||||
quality_level: ScreenSpaceAmbientOcclusionQualityLevel::Low,
|
||||
},
|
||||
|| keycode.just_pressed(KeyCode::Digit2),
|
||||
)
|
||||
.insert_if(
|
||||
ScreenSpaceAmbientOcclusionSettings {
|
||||
ScreenSpaceAmbientOcclusion {
|
||||
quality_level: ScreenSpaceAmbientOcclusionQualityLevel::Medium,
|
||||
},
|
||||
|| keycode.just_pressed(KeyCode::Digit3),
|
||||
)
|
||||
.insert_if(
|
||||
ScreenSpaceAmbientOcclusionSettings {
|
||||
ScreenSpaceAmbientOcclusion {
|
||||
quality_level: ScreenSpaceAmbientOcclusionQualityLevel::High,
|
||||
},
|
||||
|| keycode.just_pressed(KeyCode::Digit4),
|
||||
)
|
||||
.insert_if(
|
||||
ScreenSpaceAmbientOcclusionSettings {
|
||||
ScreenSpaceAmbientOcclusion {
|
||||
quality_level: ScreenSpaceAmbientOcclusionQualityLevel::Ultra,
|
||||
},
|
||||
|| keycode.just_pressed(KeyCode::Digit5),
|
||||
);
|
||||
if keycode.just_pressed(KeyCode::Digit1) {
|
||||
commands = commands.remove::<ScreenSpaceAmbientOcclusionSettings>();
|
||||
commands = commands.remove::<ScreenSpaceAmbientOcclusion>();
|
||||
}
|
||||
if keycode.just_pressed(KeyCode::Space) {
|
||||
if temporal_jitter.is_some() {
|
||||
|
@ -164,7 +164,7 @@ fn update(
|
|||
let text = &mut text.sections[0].value;
|
||||
text.clear();
|
||||
|
||||
let (o, l, m, h, u) = match ssao_settings.map(|s| s.quality_level) {
|
||||
let (o, l, m, h, u) = match ssao.map(|s| s.quality_level) {
|
||||
None => ("*", "", "", "", ""),
|
||||
Some(ScreenSpaceAmbientOcclusionQualityLevel::Low) => ("", "*", "", "", ""),
|
||||
Some(ScreenSpaceAmbientOcclusionQualityLevel::Medium) => ("", "", "*", "", ""),
|
||||
|
|
|
@ -8,8 +8,8 @@ use bevy::{
|
|||
input::mouse::MouseWheel,
|
||||
math::{vec3, vec4},
|
||||
pbr::{
|
||||
DefaultOpaqueRendererMethod, ExtendedMaterial, MaterialExtension,
|
||||
ScreenSpaceReflectionsBundle, ScreenSpaceReflectionsSettings,
|
||||
DefaultOpaqueRendererMethod, ExtendedMaterial, MaterialExtension, ScreenSpaceReflections,
|
||||
ScreenSpaceReflectionsBundle,
|
||||
},
|
||||
prelude::*,
|
||||
render::{
|
||||
|
@ -388,11 +388,9 @@ fn adjust_app_settings(
|
|||
if app_settings.ssr_on {
|
||||
commands
|
||||
.entity(camera)
|
||||
.insert(ScreenSpaceReflectionsSettings::default());
|
||||
.insert(ScreenSpaceReflections::default());
|
||||
} else {
|
||||
commands
|
||||
.entity(camera)
|
||||
.remove::<ScreenSpaceReflectionsSettings>();
|
||||
commands.entity(camera).remove::<ScreenSpaceReflections>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ fn setup(
|
|||
transform: camera_transform.0,
|
||||
..default()
|
||||
},
|
||||
FogSettings {
|
||||
DistanceFog {
|
||||
color: Color::srgb_u8(43, 44, 47),
|
||||
falloff: FogFalloff::Linear {
|
||||
start: 1.0,
|
||||
|
@ -434,8 +434,8 @@ fn update_ui(
|
|||
return;
|
||||
}
|
||||
|
||||
let (method, color_grading) = settings.single();
|
||||
let method = *method;
|
||||
let (tonemapping, color_grading) = settings.single();
|
||||
let tonemapping = *tonemapping;
|
||||
|
||||
let mut text = String::with_capacity(old_text.len());
|
||||
|
||||
|
@ -458,11 +458,15 @@ fn update_ui(
|
|||
text.push_str("\n\nTonemapping Method:\n");
|
||||
text.push_str(&format!(
|
||||
"(1) {} Disabled\n",
|
||||
if method == Tonemapping::None { ">" } else { "" }
|
||||
if tonemapping == Tonemapping::None {
|
||||
">"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
));
|
||||
text.push_str(&format!(
|
||||
"(2) {} Reinhard\n",
|
||||
if method == Tonemapping::Reinhard {
|
||||
if tonemapping == Tonemapping::Reinhard {
|
||||
"> "
|
||||
} else {
|
||||
""
|
||||
|
@ -470,7 +474,7 @@ fn update_ui(
|
|||
));
|
||||
text.push_str(&format!(
|
||||
"(3) {} Reinhard Luminance\n",
|
||||
if method == Tonemapping::ReinhardLuminance {
|
||||
if tonemapping == Tonemapping::ReinhardLuminance {
|
||||
">"
|
||||
} else {
|
||||
""
|
||||
|
@ -478,7 +482,7 @@ fn update_ui(
|
|||
));
|
||||
text.push_str(&format!(
|
||||
"(4) {} ACES Fitted\n",
|
||||
if method == Tonemapping::AcesFitted {
|
||||
if tonemapping == Tonemapping::AcesFitted {
|
||||
">"
|
||||
} else {
|
||||
""
|
||||
|
@ -486,11 +490,15 @@ fn update_ui(
|
|||
));
|
||||
text.push_str(&format!(
|
||||
"(5) {} AgX\n",
|
||||
if method == Tonemapping::AgX { ">" } else { "" }
|
||||
if tonemapping == Tonemapping::AgX {
|
||||
">"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
));
|
||||
text.push_str(&format!(
|
||||
"(6) {} SomewhatBoringDisplayTransform\n",
|
||||
if method == Tonemapping::SomewhatBoringDisplayTransform {
|
||||
if tonemapping == Tonemapping::SomewhatBoringDisplayTransform {
|
||||
">"
|
||||
} else {
|
||||
""
|
||||
|
@ -498,7 +506,7 @@ fn update_ui(
|
|||
));
|
||||
text.push_str(&format!(
|
||||
"(7) {} TonyMcMapface\n",
|
||||
if method == Tonemapping::TonyMcMapface {
|
||||
if tonemapping == Tonemapping::TonyMcMapface {
|
||||
">"
|
||||
} else {
|
||||
""
|
||||
|
@ -506,7 +514,7 @@ fn update_ui(
|
|||
));
|
||||
text.push_str(&format!(
|
||||
"(8) {} Blender Filmic\n",
|
||||
if method == Tonemapping::BlenderFilmic {
|
||||
if tonemapping == Tonemapping::BlenderFilmic {
|
||||
">"
|
||||
} else {
|
||||
""
|
||||
|
|
|
@ -23,7 +23,7 @@ use std::f32::consts::PI;
|
|||
use bevy::{
|
||||
color::palettes::css::*,
|
||||
core_pipeline::{
|
||||
bloom::BloomSettings, core_3d::ScreenSpaceTransmissionQuality, prepass::DepthPrepass,
|
||||
bloom::Bloom, core_3d::ScreenSpaceTransmissionQuality, prepass::DepthPrepass,
|
||||
tonemapping::Tonemapping,
|
||||
},
|
||||
pbr::{NotShadowCaster, PointLightShadowMap, TransmittedShadowReceiver},
|
||||
|
@ -36,7 +36,7 @@ use bevy::{
|
|||
|
||||
#[cfg(not(all(feature = "webgl2", target_arch = "wasm32")))]
|
||||
use bevy::core_pipeline::experimental::taa::{
|
||||
TemporalAntiAliasBundle, TemporalAntiAliasPlugin, TemporalAntiAliasSettings,
|
||||
TemporalAntiAliasBundle, TemporalAntiAliasPlugin, TemporalAntiAliasing,
|
||||
};
|
||||
use rand::random;
|
||||
|
||||
|
@ -363,7 +363,7 @@ fn setup(
|
|||
specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||
..default()
|
||||
},
|
||||
BloomSettings::default(),
|
||||
Bloom::default(),
|
||||
));
|
||||
|
||||
// Controls Text
|
||||
|
@ -521,14 +521,13 @@ fn example_control_system(
|
|||
#[cfg(not(all(feature = "webgl2", target_arch = "wasm32")))]
|
||||
if input.just_pressed(KeyCode::KeyT) {
|
||||
if temporal_jitter.is_none() {
|
||||
commands.entity(camera_entity).insert((
|
||||
TemporalJitter::default(),
|
||||
TemporalAntiAliasSettings::default(),
|
||||
));
|
||||
commands
|
||||
.entity(camera_entity)
|
||||
.insert((TemporalJitter::default(), TemporalAntiAliasing::default()));
|
||||
} else {
|
||||
commands
|
||||
.entity(camera_entity)
|
||||
.remove::<(TemporalJitter, TemporalAntiAliasSettings)>();
|
||||
.remove::<(TemporalJitter, TemporalAntiAliasing)>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//! Demonstrates volumetric fog and lighting (light shafts or god rays).
|
||||
|
||||
use bevy::{
|
||||
core_pipeline::{bloom::BloomSettings, tonemapping::Tonemapping, Skybox},
|
||||
core_pipeline::{bloom::Bloom, tonemapping::Tonemapping, Skybox},
|
||||
math::vec3,
|
||||
pbr::{FogVolumeBundle, VolumetricFogSettings, VolumetricLight},
|
||||
pbr::{FogVolumeBundle, VolumetricFog, VolumetricLight},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
|
@ -48,13 +48,13 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
..default()
|
||||
})
|
||||
.insert(Tonemapping::TonyMcMapface)
|
||||
.insert(BloomSettings::default())
|
||||
.insert(Bloom::default())
|
||||
.insert(Skybox {
|
||||
image: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
|
||||
brightness: 1000.0,
|
||||
..default()
|
||||
})
|
||||
.insert(VolumetricFogSettings {
|
||||
.insert(VolumetricFog {
|
||||
// This value is explicitly set to 0 since we have no environment map light
|
||||
ambient_intensity: 0.0,
|
||||
..default()
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
//! | `A` | Move left |
|
||||
//! | `D` | Move right |
|
||||
|
||||
use bevy::core_pipeline::bloom::BloomSettings;
|
||||
use bevy::core_pipeline::bloom::Bloom;
|
||||
use bevy::math::vec3;
|
||||
use bevy::prelude::*;
|
||||
use bevy::sprite::{MaterialMesh2dBundle, Mesh2dHandle};
|
||||
|
@ -82,7 +82,7 @@ fn setup_camera(mut commands: Commands) {
|
|||
},
|
||||
..default()
|
||||
},
|
||||
BloomSettings::NATURAL,
|
||||
Bloom::NATURAL,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use std::f32::consts::PI;
|
||||
|
||||
use bevy::{
|
||||
core_pipeline::{bloom::BloomSettings, tonemapping::Tonemapping},
|
||||
core_pipeline::{bloom::Bloom, tonemapping::Tonemapping},
|
||||
input::mouse::{AccumulatedMouseMotion, AccumulatedMouseScroll, MouseButtonInput},
|
||||
math::prelude::*,
|
||||
prelude::*,
|
||||
|
@ -355,7 +355,7 @@ fn setup(
|
|||
transform: Transform::from_xyz(-2.0, 3.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
..default()
|
||||
},
|
||||
BloomSettings::NATURAL,
|
||||
Bloom::NATURAL,
|
||||
CameraRig {
|
||||
yaw: 0.56,
|
||||
pitch: 0.45,
|
||||
|
|
Loading…
Reference in a new issue