mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Bias texture mipmaps (#7614)
# Objective - Closes #7323 - Reduce texture blurriness for TAA ## Solution - Add a `MipBias` component and view uniform. - Switch material `textureSample()` calls to `textureSampleBias()`. - Add a `-1.0` bias to TAA. --- ## Changelog - Added `MipBias` camera component, mostly for internal use. --------- Co-authored-by: François <mockersf@gmail.com> Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
parent
c6170d48f9
commit
724e69bff4
7 changed files with 40 additions and 15 deletions
|
@ -10,14 +10,14 @@ use bevy_core::FrameCount;
|
|||
use bevy_ecs::{
|
||||
prelude::{Bundle, Component, Entity},
|
||||
query::{QueryItem, With},
|
||||
schedule::IntoSystemConfigs,
|
||||
schedule::{apply_deferred, IntoSystemConfigs},
|
||||
system::{Commands, Query, Res, ResMut, Resource},
|
||||
world::{FromWorld, World},
|
||||
};
|
||||
use bevy_math::vec2;
|
||||
use bevy_reflect::{Reflect, TypeUuid};
|
||||
use bevy_render::{
|
||||
camera::{ExtractedCamera, TemporalJitter},
|
||||
camera::{ExtractedCamera, MipBias, TemporalJitter},
|
||||
prelude::{Camera, Projection},
|
||||
render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner},
|
||||
render_resource::{
|
||||
|
@ -65,7 +65,8 @@ impl Plugin for TemporalAntiAliasPlugin {
|
|||
.add_systems(
|
||||
Render,
|
||||
(
|
||||
prepare_taa_jitter
|
||||
(prepare_taa_jitter_and_mip_bias, apply_deferred)
|
||||
.chain()
|
||||
.before(prepare_view_uniforms)
|
||||
.in_set(RenderSet::Prepare),
|
||||
prepare_taa_history_textures.in_set(RenderSet::Prepare),
|
||||
|
@ -140,6 +141,8 @@ pub struct TemporalAntiAliasBundle {
|
|||
/// are added using a third party library, the library must either:
|
||||
/// 1. Write particle motion vectors to the motion vectors prepass texture
|
||||
/// 2. Render particles after TAA
|
||||
///
|
||||
/// If no [`MipBias`] component is attached to the camera, TAA will add a MipBias(-1.0) component.
|
||||
#[derive(Component, Reflect, Clone)]
|
||||
pub struct TemporalAntiAliasSettings {
|
||||
/// Set to true to delete the saved temporal history (past frames).
|
||||
|
@ -436,9 +439,13 @@ fn extract_taa_settings(mut commands: Commands, mut main_world: ResMut<MainWorld
|
|||
}
|
||||
}
|
||||
|
||||
fn prepare_taa_jitter(
|
||||
fn prepare_taa_jitter_and_mip_bias(
|
||||
frame_count: Res<FrameCount>,
|
||||
mut query: Query<&mut TemporalJitter, With<TemporalAntiAliasSettings>>,
|
||||
mut query: Query<
|
||||
(Entity, &mut TemporalJitter, Option<&MipBias>),
|
||||
With<TemporalAntiAliasSettings>,
|
||||
>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
// Halton sequence (2, 3) - 0.5, skipping i = 0
|
||||
let halton_sequence = [
|
||||
|
@ -454,8 +461,12 @@ fn prepare_taa_jitter(
|
|||
|
||||
let offset = halton_sequence[frame_count.0 as usize % halton_sequence.len()];
|
||||
|
||||
for mut jitter in &mut query {
|
||||
for (entity, mut jitter, mip_bias) in &mut query {
|
||||
jitter.offset = offset;
|
||||
|
||||
if mip_bias.is_none() {
|
||||
commands.entity(entity).insert(MipBias(-1.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
|||
#endif
|
||||
#ifdef VERTEX_UVS
|
||||
if ((material.flags & STANDARD_MATERIAL_FLAGS_BASE_COLOR_TEXTURE_BIT) != 0u) {
|
||||
output_color = output_color * textureSample(base_color_texture, base_color_sampler, uv);
|
||||
output_color = output_color * textureSampleBias(base_color_texture, base_color_sampler, uv, view.mip_bias);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -74,7 +74,7 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
|||
var emissive: vec4<f32> = material.emissive;
|
||||
#ifdef VERTEX_UVS
|
||||
if ((material.flags & STANDARD_MATERIAL_FLAGS_EMISSIVE_TEXTURE_BIT) != 0u) {
|
||||
emissive = vec4<f32>(emissive.rgb * textureSample(emissive_texture, emissive_sampler, uv).rgb, 1.0);
|
||||
emissive = vec4<f32>(emissive.rgb * textureSampleBias(emissive_texture, emissive_sampler, uv, view.mip_bias).rgb, 1.0);
|
||||
}
|
||||
#endif
|
||||
pbr_input.material.emissive = emissive;
|
||||
|
@ -83,7 +83,7 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
|||
var perceptual_roughness: f32 = material.perceptual_roughness;
|
||||
#ifdef VERTEX_UVS
|
||||
if ((material.flags & STANDARD_MATERIAL_FLAGS_METALLIC_ROUGHNESS_TEXTURE_BIT) != 0u) {
|
||||
let metallic_roughness = textureSample(metallic_roughness_texture, metallic_roughness_sampler, uv);
|
||||
let metallic_roughness = textureSampleBias(metallic_roughness_texture, metallic_roughness_sampler, uv, view.mip_bias);
|
||||
// Sampling from GLTF standard channels for now
|
||||
metallic = metallic * metallic_roughness.b;
|
||||
perceptual_roughness = perceptual_roughness * metallic_roughness.g;
|
||||
|
@ -96,7 +96,7 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
|||
var occlusion: vec3<f32> = vec3(1.0);
|
||||
#ifdef VERTEX_UVS
|
||||
if ((material.flags & STANDARD_MATERIAL_FLAGS_OCCLUSION_TEXTURE_BIT) != 0u) {
|
||||
occlusion = vec3(textureSample(occlusion_texture, occlusion_sampler, in.uv).r);
|
||||
occlusion = vec3(textureSampleBias(occlusion_texture, occlusion_sampler, in.uv, view.mip_bias).r);
|
||||
}
|
||||
#endif
|
||||
#ifdef SCREEN_SPACE_AMBIENT_OCCLUSION
|
||||
|
|
|
@ -82,7 +82,7 @@ fn apply_normal_mapping(
|
|||
#ifdef VERTEX_UVS
|
||||
#ifdef STANDARDMATERIAL_NORMAL_MAP
|
||||
// Nt is the tangent-space normal.
|
||||
var Nt = textureSample(normal_map_texture, normal_map_sampler, uv).rgb;
|
||||
var Nt = textureSampleBias(normal_map_texture, normal_map_sampler, uv, view.mip_bias).rgb;
|
||||
if (standard_material_flags & STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP) != 0u {
|
||||
// Only use the xy components and derive z for 2-component normal maps.
|
||||
Nt = vec3<f32>(Nt.rg * 2.0 - 1.0, 0.0);
|
||||
|
|
|
@ -39,7 +39,7 @@ fn prepass_alpha_discard(in: FragmentInput) {
|
|||
|
||||
#ifdef VERTEX_UVS
|
||||
if (material.flags & STANDARD_MATERIAL_FLAGS_BASE_COLOR_TEXTURE_BIT) != 0u {
|
||||
output_color = output_color * textureSample(base_color_texture, base_color_sampler, in.uv);
|
||||
output_color = output_color * textureSampleBias(base_color_texture, base_color_sampler, in.uv, view.mip_bias);
|
||||
}
|
||||
#endif // VERTEX_UVS
|
||||
|
||||
|
|
|
@ -771,3 +771,9 @@ impl TemporalJitter {
|
|||
projection.z_axis.y += jitter.y;
|
||||
}
|
||||
}
|
||||
|
||||
/// Camera component specifying a mip bias to apply when sampling from material textures.
|
||||
///
|
||||
/// Often used in conjunction with antialiasing post-process effects to reduce textures blurriness.
|
||||
#[derive(Component)]
|
||||
pub struct MipBias(pub f32);
|
||||
|
|
|
@ -6,7 +6,7 @@ pub use visibility::*;
|
|||
pub use window::*;
|
||||
|
||||
use crate::{
|
||||
camera::{ExtractedCamera, ManualTextureViews, TemporalJitter},
|
||||
camera::{ExtractedCamera, ManualTextureViews, MipBias, TemporalJitter},
|
||||
extract_resource::{ExtractResource, ExtractResourcePlugin},
|
||||
prelude::{Image, Shader},
|
||||
render_asset::RenderAssets,
|
||||
|
@ -173,6 +173,7 @@ pub struct ViewUniform {
|
|||
// viewport(x_origin, y_origin, width, height)
|
||||
viewport: Vec4,
|
||||
color_grading: ColorGrading,
|
||||
mip_bias: f32,
|
||||
}
|
||||
|
||||
#[derive(Resource, Default)]
|
||||
|
@ -352,11 +353,16 @@ pub fn prepare_view_uniforms(
|
|||
render_device: Res<RenderDevice>,
|
||||
render_queue: Res<RenderQueue>,
|
||||
mut view_uniforms: ResMut<ViewUniforms>,
|
||||
views: Query<(Entity, &ExtractedView, Option<&TemporalJitter>)>,
|
||||
views: Query<(
|
||||
Entity,
|
||||
&ExtractedView,
|
||||
Option<&TemporalJitter>,
|
||||
Option<&MipBias>,
|
||||
)>,
|
||||
) {
|
||||
view_uniforms.uniforms.clear();
|
||||
|
||||
for (entity, camera, temporal_jitter) in &views {
|
||||
for (entity, camera, temporal_jitter, mip_bias) in &views {
|
||||
let viewport = camera.viewport.as_vec4();
|
||||
let unjittered_projection = camera.projection;
|
||||
let mut projection = unjittered_projection;
|
||||
|
@ -383,6 +389,7 @@ pub fn prepare_view_uniforms(
|
|||
world_position: camera.transform.translation(),
|
||||
viewport,
|
||||
color_grading: camera.color_grading,
|
||||
mip_bias: mip_bias.unwrap_or(&MipBias(0.0)).0,
|
||||
}),
|
||||
};
|
||||
|
||||
|
|
|
@ -19,4 +19,5 @@ struct View {
|
|||
// viewport(x_origin, y_origin, width, height)
|
||||
viewport: vec4<f32>,
|
||||
color_grading: ColorGrading,
|
||||
mip_bias: f32,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue