@@ -32,7 +32,7 @@ use bevy::{
32
32
Render , RenderApp , RenderSet ,
33
33
} ,
34
34
} ;
35
- use bevy_render:: render_resource:: { RenderPipeline , Specialize , Specializer } ;
35
+ use bevy_render:: render_resource:: { HasBaseDescriptor , RenderPipeline , Specialize , Specializer } ;
36
36
use bytemuck:: { Pod , Zeroable } ;
37
37
38
38
/// A marker component that represents an entity that is to be rendered using
@@ -162,16 +162,10 @@ fn main() {
162
162
. add_plugins ( ExtractComponentPlugin :: < CustomRenderedEntity > :: default ( ) )
163
163
. add_systems ( Startup , setup) ;
164
164
165
- let base_pipeline_descriptor = base_pipeline_descriptor ( app. world ( ) . resource :: < AssetServer > ( ) ) ;
166
-
167
165
// We make sure to add these to the render app, not the main app.
168
166
app. get_sub_app_mut ( RenderApp )
169
167
. unwrap ( )
170
- . insert_resource ( Specializer :: new (
171
- CustomPhaseSpecializer ,
172
- None ,
173
- base_pipeline_descriptor,
174
- ) )
168
+ . init_resource :: < Specializer < RenderPipeline , CustomPhaseSpecializer > > ( )
175
169
. add_render_command :: < Opaque3d , DrawCustomPhaseItemCommands > ( )
176
170
. add_systems (
177
171
Render ,
@@ -269,7 +263,21 @@ fn queue_custom_phase_item(
269
263
}
270
264
}
271
265
272
- struct CustomPhaseSpecializer ;
266
+ /// Holds a reference to our shader.
267
+ ///
268
+ /// This is loaded at app creation time.
269
+ struct CustomPhaseSpecializer {
270
+ shader : Handle < Shader > ,
271
+ }
272
+
273
+ impl FromWorld for CustomPhaseSpecializer {
274
+ fn from_world ( world : & mut World ) -> Self {
275
+ let asset_server = world. resource :: < AssetServer > ( ) ;
276
+ Self {
277
+ shader : asset_server. load ( "shaders/custom_phase_item.wgsl" ) ,
278
+ }
279
+ }
280
+ }
273
281
274
282
impl Specialize < RenderPipeline > for CustomPhaseSpecializer {
275
283
type Key = Msaa ;
@@ -279,63 +287,64 @@ impl Specialize<RenderPipeline> for CustomPhaseSpecializer {
279
287
}
280
288
}
281
289
282
- fn base_pipeline_descriptor ( asset_server : & AssetServer ) -> RenderPipelineDescriptor {
283
- let shader = asset_server. load ( "shaders/custom_phase_item.wgsl" ) ;
284
- RenderPipelineDescriptor {
285
- label : Some ( "custom render pipeline" . into ( ) ) ,
286
- layout : vec ! [ ] ,
287
- push_constant_ranges : vec ! [ ] ,
288
- vertex : VertexState {
289
- shader : shader. clone ( ) ,
290
- shader_defs : vec ! [ ] ,
291
- entry_point : "vertex" . into ( ) ,
292
- buffers : vec ! [ VertexBufferLayout {
293
- array_stride: size_of:: <Vertex >( ) as u64 ,
294
- step_mode: VertexStepMode :: Vertex ,
295
- // This needs to match the layout of [`Vertex`].
296
- attributes: vec![
297
- VertexAttribute {
298
- format: VertexFormat :: Float32x3 ,
299
- offset: 0 ,
300
- shader_location: 0 ,
301
- } ,
302
- VertexAttribute {
303
- format: VertexFormat :: Float32x3 ,
304
- offset: 16 ,
305
- shader_location: 1 ,
306
- } ,
307
- ] ,
308
- } ] ,
309
- } ,
310
- fragment : Some ( FragmentState {
311
- shader,
312
- shader_defs : vec ! [ ] ,
313
- entry_point : "fragment" . into ( ) ,
314
- targets : vec ! [ Some ( ColorTargetState {
315
- // Ordinarily, you'd want to check whether the view has the
316
- // HDR format and substitute the appropriate texture format
317
- // here, but we omit that for simplicity.
318
- format: TextureFormat :: bevy_default( ) ,
319
- blend: None ,
320
- write_mask: ColorWrites :: ALL ,
321
- } ) ] ,
322
- } ) ,
323
- primitive : PrimitiveState :: default ( ) ,
324
- // Note that if your view has no depth buffer this will need to be
325
- // changed.
326
- depth_stencil : Some ( DepthStencilState {
327
- format : CORE_3D_DEPTH_FORMAT ,
328
- depth_write_enabled : false ,
329
- depth_compare : CompareFunction :: Always ,
330
- stencil : default ( ) ,
331
- bias : default ( ) ,
332
- } ) ,
333
- multisample : MultisampleState {
334
- count : 0 ,
335
- mask : !0 ,
336
- alpha_to_coverage_enabled : false ,
337
- } ,
338
- zero_initialize_workgroup_memory : false ,
290
+ impl HasBaseDescriptor < RenderPipeline > for CustomPhaseSpecializer {
291
+ fn base_descriptor ( & self ) -> RenderPipelineDescriptor {
292
+ RenderPipelineDescriptor {
293
+ label : Some ( "custom render pipeline" . into ( ) ) ,
294
+ layout : vec ! [ ] ,
295
+ push_constant_ranges : vec ! [ ] ,
296
+ vertex : VertexState {
297
+ shader : self . shader . clone ( ) ,
298
+ shader_defs : vec ! [ ] ,
299
+ entry_point : "vertex" . into ( ) ,
300
+ buffers : vec ! [ VertexBufferLayout {
301
+ array_stride: size_of:: <Vertex >( ) as u64 ,
302
+ step_mode: VertexStepMode :: Vertex ,
303
+ // This needs to match the layout of [`Vertex`].
304
+ attributes: vec![
305
+ VertexAttribute {
306
+ format: VertexFormat :: Float32x3 ,
307
+ offset: 0 ,
308
+ shader_location: 0 ,
309
+ } ,
310
+ VertexAttribute {
311
+ format: VertexFormat :: Float32x3 ,
312
+ offset: 16 ,
313
+ shader_location: 1 ,
314
+ } ,
315
+ ] ,
316
+ } ] ,
317
+ } ,
318
+ fragment : Some ( FragmentState {
319
+ shader : self . shader . clone ( ) ,
320
+ shader_defs : vec ! [ ] ,
321
+ entry_point : "fragment" . into ( ) ,
322
+ targets : vec ! [ Some ( ColorTargetState {
323
+ // Ordinarily, you'd want to check whether the view has the
324
+ // HDR format and substitute the appropriate texture format
325
+ // here, but we omit that for simplicity.
326
+ format: TextureFormat :: bevy_default( ) ,
327
+ blend: None ,
328
+ write_mask: ColorWrites :: ALL ,
329
+ } ) ] ,
330
+ } ) ,
331
+ primitive : PrimitiveState :: default ( ) ,
332
+ // Note that if your view has no depth buffer this will need to be
333
+ // changed.
334
+ depth_stencil : Some ( DepthStencilState {
335
+ format : CORE_3D_DEPTH_FORMAT ,
336
+ depth_write_enabled : false ,
337
+ depth_compare : CompareFunction :: Always ,
338
+ stencil : default ( ) ,
339
+ bias : default ( ) ,
340
+ } ) ,
341
+ multisample : MultisampleState {
342
+ count : 0 ,
343
+ mask : !0 ,
344
+ alpha_to_coverage_enabled : false ,
345
+ } ,
346
+ zero_initialize_workgroup_memory : false ,
347
+ }
339
348
}
340
349
}
341
350
0 commit comments