Add TransmissiveQuality
enum to control number of taps
This commit is contained in:
parent
d4cc7b8ff7
commit
e2b017fae9
@ -41,6 +41,9 @@ pub struct Camera3d {
|
||||
/// Setting this to `0` disables the screen-space refraction effect entirely, and falls
|
||||
/// back to refracting the environment map light's texture.
|
||||
pub transmissive_steps: usize,
|
||||
|
||||
/// The quality of the transmissive blur effect.
|
||||
pub transmissive_quality: TransmissiveQuality,
|
||||
}
|
||||
|
||||
impl Default for Camera3d {
|
||||
@ -50,6 +53,7 @@ impl Default for Camera3d {
|
||||
depth_load_op: Default::default(),
|
||||
depth_texture_usages: TextureUsages::RENDER_ATTACHMENT.into(),
|
||||
transmissive_steps: 1,
|
||||
transmissive_quality: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,6 +98,34 @@ impl From<Camera3dDepthLoadOp> for LoadOp<f32> {
|
||||
}
|
||||
}
|
||||
|
||||
/// The quality of the transmissive blur effect. Higher qualities are more GPU-intensive.
|
||||
///
|
||||
/// **Note:** You can get better-looking results at any quality level by enabling TAA. See: [`TemporalAntiAliasPlugin`](crate::experimental::taa::TemporalAntiAliasPlugin).
|
||||
#[derive(Resource, Default, Clone, Copy, Reflect, PartialEq, PartialOrd, Debug)]
|
||||
#[reflect(Resource)]
|
||||
pub enum TransmissiveQuality {
|
||||
/// Best performance at the cost of quality. Suitable for lower end GPUs. (e.g. Mobile)
|
||||
///
|
||||
/// `num_taps` = 4
|
||||
Low,
|
||||
|
||||
/// A balanced option between quality and performance.
|
||||
///
|
||||
/// `num_taps` = 8
|
||||
#[default]
|
||||
Medium,
|
||||
|
||||
/// Best quality. Suitable for high end GPUs. (e.g. Desktop)
|
||||
///
|
||||
/// `num_taps` = 16
|
||||
High,
|
||||
|
||||
/// The highest quality, suitable for non-realtime rendering. (e.g. Pre-rendered cinematics and photo mode)
|
||||
///
|
||||
/// `num_taps` = 32
|
||||
Ultra,
|
||||
}
|
||||
|
||||
#[derive(Bundle)]
|
||||
pub struct Camera3dBundle {
|
||||
pub camera: Camera,
|
||||
|
@ -6,7 +6,9 @@ use crate::{
|
||||
use bevy_app::{App, Plugin};
|
||||
use bevy_asset::{Asset, AssetApp, AssetEvent, AssetId, AssetServer, Assets, Handle};
|
||||
use bevy_core_pipeline::{
|
||||
core_3d::{AlphaMask3d, Opaque3d, Transmissive3d, Transparent3d},
|
||||
core_3d::{
|
||||
AlphaMask3d, Camera3d, Opaque3d, Transmissive3d, TransmissiveQuality, Transparent3d,
|
||||
},
|
||||
prepass::NormalPrepass,
|
||||
tonemapping::{DebandDither, Tonemapping},
|
||||
};
|
||||
@ -423,6 +425,17 @@ const fn tonemapping_pipeline_key(tonemapping: Tonemapping) -> MeshPipelineKey {
|
||||
}
|
||||
}
|
||||
|
||||
const fn transmissive_quality_pipeline_key(
|
||||
transmissive_quality: TransmissiveQuality,
|
||||
) -> MeshPipelineKey {
|
||||
match transmissive_quality {
|
||||
TransmissiveQuality::Low => MeshPipelineKey::TRANSMISSIVE_QUALITY_LOW,
|
||||
TransmissiveQuality::Medium => MeshPipelineKey::TRANSMISSIVE_QUALITY_MEDIUM,
|
||||
TransmissiveQuality::High => MeshPipelineKey::TRANSMISSIVE_QUALITY_HIGH,
|
||||
TransmissiveQuality::Ultra => MeshPipelineKey::TRANSMISSIVE_QUALITY_ULTRA,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn queue_material_meshes<M: Material>(
|
||||
opaque_draw_functions: Res<DrawFunctions<Opaque3d>>,
|
||||
@ -451,6 +464,7 @@ pub fn queue_material_meshes<M: Material>(
|
||||
Option<&ScreenSpaceAmbientOcclusionSettings>,
|
||||
Option<&NormalPrepass>,
|
||||
Option<&TemporalJitter>,
|
||||
Option<&Camera3d>,
|
||||
&mut RenderPhase<Opaque3d>,
|
||||
&mut RenderPhase<AlphaMask3d>,
|
||||
&mut RenderPhase<Transmissive3d>,
|
||||
@ -468,6 +482,7 @@ pub fn queue_material_meshes<M: Material>(
|
||||
ssao,
|
||||
normal_prepass,
|
||||
temporal_jitter,
|
||||
camera_3d,
|
||||
mut opaque_phase,
|
||||
mut alpha_mask_phase,
|
||||
mut transmissive_phase,
|
||||
@ -502,6 +517,9 @@ pub fn queue_material_meshes<M: Material>(
|
||||
if ssao.is_some() {
|
||||
view_key |= MeshPipelineKey::SCREEN_SPACE_AMBIENT_OCCLUSION;
|
||||
}
|
||||
if let Some(camera_3d) = camera_3d {
|
||||
view_key |= transmissive_quality_pipeline_key(camera_3d.transmissive_quality);
|
||||
}
|
||||
let rangefinder = view.rangefinder3d();
|
||||
for visible_entity in &visible_entities.entities {
|
||||
let Ok((material_handle, mut material_bind_group_id, mesh_handle, mesh_transforms)) =
|
||||
|
@ -729,6 +729,11 @@ bitflags::bitflags! {
|
||||
const TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM = 5 << Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||
const TONEMAP_METHOD_TONY_MC_MAPFACE = 6 << Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||
const TONEMAP_METHOD_BLENDER_FILMIC = 7 << Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||
const TRANSMISSIVE_QUALITY_RESERVED_BITS = Self::TRANSMISSIVE_QUALITY_MASK_BITS << Self::TRANSMISSIVE_QUALITY_SHIFT_BITS;
|
||||
const TRANSMISSIVE_QUALITY_LOW = 0 << Self::TRANSMISSIVE_QUALITY_SHIFT_BITS;
|
||||
const TRANSMISSIVE_QUALITY_MEDIUM = 1 << Self::TRANSMISSIVE_QUALITY_SHIFT_BITS;
|
||||
const TRANSMISSIVE_QUALITY_HIGH = 2 << Self::TRANSMISSIVE_QUALITY_SHIFT_BITS;
|
||||
const TRANSMISSIVE_QUALITY_ULTRA = 3 << Self::TRANSMISSIVE_QUALITY_SHIFT_BITS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -744,6 +749,9 @@ impl MeshPipelineKey {
|
||||
const TONEMAP_METHOD_MASK_BITS: u32 = 0b111;
|
||||
const TONEMAP_METHOD_SHIFT_BITS: u32 =
|
||||
Self::BLEND_SHIFT_BITS - Self::TONEMAP_METHOD_MASK_BITS.count_ones();
|
||||
const TRANSMISSIVE_QUALITY_MASK_BITS: u32 = 0b11;
|
||||
const TRANSMISSIVE_QUALITY_SHIFT_BITS: u32 =
|
||||
Self::TONEMAP_METHOD_SHIFT_BITS - Self::TRANSMISSIVE_QUALITY_MASK_BITS.count_ones();
|
||||
|
||||
pub fn from_msaa_samples(msaa_samples: u32) -> Self {
|
||||
let msaa_bits =
|
||||
@ -975,6 +983,19 @@ impl SpecializedMeshPipeline for MeshPipeline {
|
||||
shader_defs.push("TEMPORAL_JITTER".into());
|
||||
}
|
||||
|
||||
let transmissive_quality =
|
||||
key.intersection(MeshPipelineKey::TRANSMISSIVE_QUALITY_RESERVED_BITS);
|
||||
|
||||
if transmissive_quality == MeshPipelineKey::TRANSMISSIVE_QUALITY_LOW {
|
||||
shader_defs.push(ShaderDefVal::Int("TRANSMISSIVE_TAPS".into(), 4));
|
||||
} else if transmissive_quality == MeshPipelineKey::TRANSMISSIVE_QUALITY_MEDIUM {
|
||||
shader_defs.push(ShaderDefVal::Int("TRANSMISSIVE_TAPS".into(), 8));
|
||||
} else if transmissive_quality == MeshPipelineKey::TRANSMISSIVE_QUALITY_HIGH {
|
||||
shader_defs.push(ShaderDefVal::Int("TRANSMISSIVE_TAPS".into(), 16));
|
||||
} else if transmissive_quality == MeshPipelineKey::TRANSMISSIVE_QUALITY_ULTRA {
|
||||
shader_defs.push(ShaderDefVal::Int("TRANSMISSIVE_TAPS".into(), 32));
|
||||
}
|
||||
|
||||
let format = if key.contains(MeshPipelineKey::HDR) {
|
||||
ViewTarget::TEXTURE_FORMAT_HDR
|
||||
} else {
|
||||
|
@ -342,8 +342,11 @@ fn fetch_transmissive_background(offset_position: vec2<f32>, frag_coord: vec3<f3
|
||||
// - inversely proportional to view z
|
||||
let blur_intensity = (perceptual_roughness * perceptual_roughness) / view_z;
|
||||
|
||||
// TODO: Make this configurable
|
||||
let num_taps = 8;
|
||||
#ifdef TRANSMISSIVE_TAPS
|
||||
let num_taps = #{TRANSMISSIVE_TAPS}; // Controlled by the `Camera3d::transmissive_quality` property
|
||||
#else
|
||||
let num_taps = 8; // Fallback to 8 taps
|
||||
#endif
|
||||
let num_spirals = i32(ceil(f32(num_taps) / 8.0));
|
||||
let random_angle = interleaved_gradient_noise(frag_coord.xy);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user