11use bevy_app:: { App , Plugin } ;
2- use bevy_asset:: { embedded_asset, load_embedded_asset, AssetServer , Handle } ;
2+ use bevy_asset:: { embedded_asset, load_embedded_asset, AssetServer } ;
33use bevy_camera:: { Camera , Camera3d } ;
44use bevy_core_pipeline:: {
55 core_3d:: graph:: { Core3d , Node3d } ,
@@ -8,6 +8,7 @@ use bevy_core_pipeline::{
88} ;
99use bevy_diagnostic:: FrameCount ;
1010use bevy_ecs:: {
11+ error:: BevyError ,
1112 prelude:: { Component , Entity , ReflectComponent } ,
1213 query:: { QueryItem , With } ,
1314 resource:: Resource ,
@@ -25,11 +26,11 @@ use bevy_render::{
2526 render_resource:: {
2627 binding_types:: { sampler, texture_2d, texture_depth_2d} ,
2728 BindGroupEntries , BindGroupLayoutDescriptor , BindGroupLayoutEntries ,
28- CachedRenderPipelineId , ColorTargetState , ColorWrites , FilterMode , FragmentState ,
29- Operations , PipelineCache , RenderPassColorAttachment , RenderPassDescriptor ,
30- RenderPipelineDescriptor , Sampler , SamplerBindingType , SamplerDescriptor , ShaderStages ,
31- SpecializedRenderPipeline , SpecializedRenderPipelines , TextureDescriptor , TextureDimension ,
32- TextureFormat , TextureSampleType , TextureUsages ,
29+ CachedRenderPipelineId , Canonical , ColorTargetState , ColorWrites , FilterMode ,
30+ FragmentState , Operations , PipelineCache , RenderPassColorAttachment , RenderPassDescriptor ,
31+ RenderPipeline , RenderPipelineDescriptor , Sampler , SamplerBindingType , SamplerDescriptor ,
32+ ShaderStages , Specializer , SpecializerKey , TextureDescriptor , TextureDimension ,
33+ TextureFormat , TextureSampleType , TextureUsages , Variants ,
3334 } ,
3435 renderer:: { RenderContext , RenderDevice } ,
3536 sync_component:: SyncComponentPlugin ,
@@ -38,7 +39,6 @@ use bevy_render::{
3839 view:: { ExtractedView , Msaa , ViewTarget } ,
3940 ExtractSchedule , MainWorld , Render , RenderApp , RenderStartup , RenderSystems ,
4041} ;
41- use bevy_shader:: Shader ;
4242use bevy_utils:: default;
4343use tracing:: warn;
4444
@@ -58,7 +58,6 @@ impl Plugin for TemporalAntiAliasPlugin {
5858 return ;
5959 } ;
6060 render_app
61- . init_resource :: < SpecializedRenderPipelines < TaaPipeline > > ( )
6261 . add_systems ( RenderStartup , init_taa_pipeline)
6362 . add_systems ( ExtractSchedule , extract_taa_settings)
6463 . add_systems (
@@ -239,8 +238,7 @@ struct TaaPipeline {
239238 taa_bind_group_layout : BindGroupLayoutDescriptor ,
240239 nearest_sampler : Sampler ,
241240 linear_sampler : Sampler ,
242- fullscreen_shader : FullscreenShader ,
243- fragment_shader : Handle < Shader > ,
241+ variants : Variants < RenderPipeline , TaaPipelineSpecializer > ,
244242}
245243
246244fn init_taa_pipeline (
@@ -283,61 +281,68 @@ fn init_taa_pipeline(
283281 ) ,
284282 ) ;
285283
284+ let fragment_shader = load_embedded_asset ! ( asset_server. as_ref( ) , "taa.wgsl" ) ;
285+
286+ let variants = Variants :: new (
287+ TaaPipelineSpecializer ,
288+ RenderPipelineDescriptor {
289+ label : Some ( "taa_pipeline" . into ( ) ) ,
290+ layout : vec ! [ taa_bind_group_layout. clone( ) ] ,
291+ vertex : fullscreen_shader. to_vertex_state ( ) ,
292+ fragment : Some ( FragmentState {
293+ shader : fragment_shader,
294+ ..default ( )
295+ } ) ,
296+ ..default ( )
297+ } ,
298+ ) ;
299+
286300 commands. insert_resource ( TaaPipeline {
287301 taa_bind_group_layout,
288302 nearest_sampler,
289303 linear_sampler,
290- fullscreen_shader : fullscreen_shader. clone ( ) ,
291- fragment_shader : load_embedded_asset ! ( asset_server. as_ref( ) , "taa.wgsl" ) ,
304+ variants,
292305 } ) ;
293306}
294307
295- #[ derive( PartialEq , Eq , Hash , Clone ) ]
308+ struct TaaPipelineSpecializer ;
309+
310+ #[ derive( PartialEq , Eq , Hash , Clone , SpecializerKey ) ]
296311struct TaaPipelineKey {
297312 hdr : bool ,
298313 reset : bool ,
299314}
300315
301- impl SpecializedRenderPipeline for TaaPipeline {
316+ impl Specializer < RenderPipeline > for TaaPipelineSpecializer {
302317 type Key = TaaPipelineKey ;
303318
304- fn specialize ( & self , key : Self :: Key ) -> RenderPipelineDescriptor {
305- let mut shader_defs = vec ! [ ] ;
306-
319+ fn specialize (
320+ & self ,
321+ key : Self :: Key ,
322+ descriptor : & mut RenderPipelineDescriptor ,
323+ ) -> Result < Canonical < Self :: Key > , BevyError > {
324+ let fragment = descriptor. fragment_mut ( ) ?;
307325 let format = if key. hdr {
308- shader_defs. push ( "TONEMAP" . into ( ) ) ;
326+ fragment . shader_defs . push ( "TONEMAP" . into ( ) ) ;
309327 ViewTarget :: TEXTURE_FORMAT_HDR
310328 } else {
311329 TextureFormat :: bevy_default ( )
312330 } ;
313331
314332 if key. reset {
315- shader_defs. push ( "RESET" . into ( ) ) ;
333+ fragment . shader_defs . push ( "RESET" . into ( ) )
316334 }
317335
318- RenderPipelineDescriptor {
319- label : Some ( "taa_pipeline" . into ( ) ) ,
320- layout : vec ! [ self . taa_bind_group_layout. clone( ) ] ,
321- vertex : self . fullscreen_shader . to_vertex_state ( ) ,
322- fragment : Some ( FragmentState {
323- shader : self . fragment_shader . clone ( ) ,
324- shader_defs,
325- targets : vec ! [
326- Some ( ColorTargetState {
327- format,
328- blend: None ,
329- write_mask: ColorWrites :: ALL ,
330- } ) ,
331- Some ( ColorTargetState {
332- format,
333- blend: None ,
334- write_mask: ColorWrites :: ALL ,
335- } ) ,
336- ] ,
337- ..default ( )
338- } ) ,
339- ..default ( )
340- }
336+ let color_target_state = ColorTargetState {
337+ format,
338+ blend : None ,
339+ write_mask : ColorWrites :: ALL ,
340+ } ;
341+
342+ fragment. set_target ( 0 , color_target_state. clone ( ) ) ;
343+ fragment. set_target ( 1 , color_target_state) ;
344+
345+ Ok ( key)
341346 }
342347}
343348
@@ -455,25 +460,30 @@ pub struct TemporalAntiAliasPipelineId(CachedRenderPipelineId);
455460fn prepare_taa_pipelines (
456461 mut commands : Commands ,
457462 pipeline_cache : Res < PipelineCache > ,
458- mut pipelines : ResMut < SpecializedRenderPipelines < TaaPipeline > > ,
459- pipeline : Res < TaaPipeline > ,
463+ mut pipeline : ResMut < TaaPipeline > ,
460464 views : Query < ( Entity , & ExtractedView , & TemporalAntiAliasing ) > ,
461- ) {
465+ ) -> Result < ( ) , BevyError > {
462466 for ( entity, view, taa_settings) in & views {
463467 let mut pipeline_key = TaaPipelineKey {
464468 hdr : view. hdr ,
465469 reset : taa_settings. reset ,
466470 } ;
467- let pipeline_id = pipelines. specialize ( & pipeline_cache, & pipeline, pipeline_key. clone ( ) ) ;
471+ let pipeline_id = pipeline
472+ . variants
473+ . specialize ( & pipeline_cache, pipeline_key. clone ( ) ) ?;
468474
469475 // Prepare non-reset pipeline anyways - it will be necessary next frame
470476 if pipeline_key. reset {
471477 pipeline_key. reset = false ;
472- pipelines. specialize ( & pipeline_cache, & pipeline, pipeline_key) ;
478+ pipeline
479+ . variants
480+ . specialize ( & pipeline_cache, pipeline_key) ?;
473481 }
474482
475483 commands
476484 . entity ( entity)
477485 . insert ( TemporalAntiAliasPipelineId ( pipeline_id) ) ;
478486 }
487+
488+ Ok ( ( ) )
479489}
0 commit comments