@@ -15,7 +15,7 @@ use bevy_ecs::{
15
15
world:: FromWorld ,
16
16
} ;
17
17
use bevy_render:: {
18
- mesh:: Mesh ,
18
+ mesh:: { Mesh , MeshVertexBufferLayout } ,
19
19
render_asset:: { RenderAsset , RenderAssetPlugin , RenderAssets } ,
20
20
render_component:: ExtractComponentPlugin ,
21
21
render_phase:: {
@@ -24,7 +24,7 @@ use bevy_render::{
24
24
} ,
25
25
render_resource:: {
26
26
BindGroup , BindGroupLayout , RenderPipelineCache , RenderPipelineDescriptor , Shader ,
27
- SpecializedPipeline , SpecializedPipelines ,
27
+ SpecializedMeshPipeline , SpecializedMeshPipelines ,
28
28
} ,
29
29
renderer:: RenderDevice ,
30
30
view:: { ExtractedView , Msaa , VisibleEntities } ,
@@ -81,7 +81,12 @@ impl<M: Material> SpecializedMaterial for M {
81
81
fn key ( _material : & <Self as RenderAsset >:: PreparedAsset ) -> Self :: Key { }
82
82
83
83
#[ inline]
84
- fn specialize ( _key : Self :: Key , _descriptor : & mut RenderPipelineDescriptor ) { }
84
+ fn specialize (
85
+ _descriptor : & mut RenderPipelineDescriptor ,
86
+ _key : Self :: Key ,
87
+ _layout : & MeshVertexBufferLayout ,
88
+ ) {
89
+ }
85
90
86
91
#[ inline]
87
92
fn bind_group ( material : & <Self as RenderAsset >:: PreparedAsset ) -> & BindGroup {
@@ -130,7 +135,11 @@ pub trait SpecializedMaterial: Asset + RenderAsset {
130
135
fn key ( material : & <Self as RenderAsset >:: PreparedAsset ) -> Self :: Key ;
131
136
132
137
/// Specializes the given `descriptor` according to the given `key`.
133
- fn specialize ( key : Self :: Key , descriptor : & mut RenderPipelineDescriptor ) ;
138
+ fn specialize (
139
+ descriptor : & mut RenderPipelineDescriptor ,
140
+ key : Self :: Key ,
141
+ layout : & MeshVertexBufferLayout ,
142
+ ) ;
134
143
135
144
/// Returns this material's [`BindGroup`]. This should match the layout returned by [`SpecializedMaterial::bind_group_layout`].
136
145
fn bind_group ( material : & <Self as RenderAsset >:: PreparedAsset ) -> & BindGroup ;
@@ -188,7 +197,7 @@ impl<M: SpecializedMaterial> Plugin for MaterialPlugin<M> {
188
197
. add_render_command :: < Opaque3d , DrawMaterial < M > > ( )
189
198
. add_render_command :: < AlphaMask3d , DrawMaterial < M > > ( )
190
199
. init_resource :: < MaterialPipeline < M > > ( )
191
- . init_resource :: < SpecializedPipelines < MaterialPipeline < M > > > ( )
200
+ . init_resource :: < SpecializedMeshPipelines < MaterialPipeline < M > > > ( )
192
201
. add_system_to_stage ( RenderStage :: Queue , queue_material_meshes :: < M > ) ;
193
202
}
194
203
}
@@ -202,11 +211,15 @@ pub struct MaterialPipeline<M: SpecializedMaterial> {
202
211
marker : PhantomData < M > ,
203
212
}
204
213
205
- impl < M : SpecializedMaterial > SpecializedPipeline for MaterialPipeline < M > {
214
+ impl < M : SpecializedMaterial > SpecializedMeshPipeline for MaterialPipeline < M > {
206
215
type Key = ( MeshPipelineKey , M :: Key ) ;
207
216
208
- fn specialize ( & self , key : Self :: Key ) -> RenderPipelineDescriptor {
209
- let mut descriptor = self . mesh_pipeline . specialize ( key. 0 ) ;
217
+ fn specialize (
218
+ & self ,
219
+ key : Self :: Key ,
220
+ layout : & MeshVertexBufferLayout ,
221
+ ) -> RenderPipelineDescriptor {
222
+ let mut descriptor = self . mesh_pipeline . specialize ( key. 0 , layout) ;
210
223
if let Some ( vertex_shader) = & self . vertex_shader {
211
224
descriptor. vertex . shader = vertex_shader. clone ( ) ;
212
225
}
@@ -220,7 +233,7 @@ impl<M: SpecializedMaterial> SpecializedPipeline for MaterialPipeline<M> {
220
233
self . mesh_pipeline. mesh_layout. clone( ) ,
221
234
] ) ;
222
235
223
- M :: specialize ( key. 1 , & mut descriptor ) ;
236
+ M :: specialize ( & mut descriptor , key. 1 , layout ) ;
224
237
descriptor
225
238
}
226
239
}
@@ -275,7 +288,7 @@ pub fn queue_material_meshes<M: SpecializedMaterial>(
275
288
alpha_mask_draw_functions : Res < DrawFunctions < AlphaMask3d > > ,
276
289
transparent_draw_functions : Res < DrawFunctions < Transparent3d > > ,
277
290
material_pipeline : Res < MaterialPipeline < M > > ,
278
- mut pipelines : ResMut < SpecializedPipelines < MaterialPipeline < M > > > ,
291
+ mut pipelines : ResMut < SpecializedMeshPipelines < MaterialPipeline < M > > > ,
279
292
mut pipeline_cache : ResMut < RenderPipelineCache > ,
280
293
msaa : Res < Msaa > ,
281
294
render_meshes : Res < RenderAssets < Mesh > > ,
@@ -307,72 +320,71 @@ pub fn queue_material_meshes<M: SpecializedMaterial>(
307
320
308
321
let inverse_view_matrix = view. transform . compute_matrix ( ) . inverse ( ) ;
309
322
let inverse_view_row_2 = inverse_view_matrix. row ( 2 ) ;
310
- let mesh_key = MeshPipelineKey :: from_msaa_samples ( msaa. samples ) ;
323
+ let msaa_key = MeshPipelineKey :: from_msaa_samples ( msaa. samples ) ;
311
324
312
325
for visible_entity in & visible_entities. entities {
313
326
if let Ok ( ( material_handle, mesh_handle, mesh_uniform) ) =
314
327
material_meshes. get ( * visible_entity)
315
328
{
316
329
if let Some ( material) = render_materials. get ( material_handle) {
317
- let mut mesh_key = mesh_key;
318
330
if let Some ( mesh) = render_meshes. get ( mesh_handle) {
319
- if mesh. has_tangents {
320
- mesh_key |= MeshPipelineKey :: VERTEX_TANGENTS ;
331
+ let mut mesh_key =
332
+ MeshPipelineKey :: from_primitive_topology ( mesh. primitive_topology )
333
+ | msaa_key;
334
+ let alpha_mode = M :: alpha_mode ( material) ;
335
+ if let AlphaMode :: Blend = alpha_mode {
336
+ mesh_key |= MeshPipelineKey :: TRANSPARENT_MAIN_PASS ;
321
337
}
322
- mesh_key |=
323
- MeshPipelineKey :: from_primitive_topology ( mesh. primitive_topology ) ;
324
- }
325
- let alpha_mode = M :: alpha_mode ( material) ;
326
- if let AlphaMode :: Blend = alpha_mode {
327
- mesh_key |= MeshPipelineKey :: TRANSPARENT_MAIN_PASS ;
328
- }
329
338
330
- let specialized_key = M :: key ( material) ;
331
- let pipeline_id = pipelines. specialize (
332
- & mut pipeline_cache,
333
- & material_pipeline,
334
- ( mesh_key, specialized_key) ,
335
- ) ;
336
-
337
- // NOTE: row 2 of the inverse view matrix dotted with column 3 of the model matrix
338
- // gives the z component of translation of the mesh in view space
339
- let mesh_z = inverse_view_row_2. dot ( mesh_uniform. transform . col ( 3 ) ) ;
340
- match alpha_mode {
341
- AlphaMode :: Opaque => {
342
- opaque_phase. add ( Opaque3d {
343
- entity : * visible_entity,
344
- draw_function : draw_opaque_pbr,
345
- pipeline : pipeline_id,
346
- // NOTE: Front-to-back ordering for opaque with ascending sort means near should have the
347
- // lowest sort key and getting further away should increase. As we have
348
- // -z in front of the camera, values in view space decrease away from the
349
- // camera. Flipping the sign of mesh_z results in the correct front-to-back ordering
350
- distance : -mesh_z,
351
- } ) ;
352
- }
353
- AlphaMode :: Mask ( _) => {
354
- alpha_mask_phase. add ( AlphaMask3d {
355
- entity : * visible_entity,
356
- draw_function : draw_alpha_mask_pbr,
357
- pipeline : pipeline_id,
358
- // NOTE: Front-to-back ordering for alpha mask with ascending sort means near should have the
359
- // lowest sort key and getting further away should increase. As we have
360
- // -z in front of the camera, values in view space decrease away from the
361
- // camera. Flipping the sign of mesh_z results in the correct front-to-back ordering
362
- distance : -mesh_z,
363
- } ) ;
364
- }
365
- AlphaMode :: Blend => {
366
- transparent_phase. add ( Transparent3d {
367
- entity : * visible_entity,
368
- draw_function : draw_transparent_pbr,
369
- pipeline : pipeline_id,
370
- // NOTE: Back-to-front ordering for transparent with ascending sort means far should have the
371
- // lowest sort key and getting closer should increase. As we have
372
- // -z in front of the camera, the largest distance is -far with values increasing toward the
373
- // camera. As such we can just use mesh_z as the distance
374
- distance : mesh_z,
375
- } ) ;
339
+ let specialized_key = M :: key ( material) ;
340
+
341
+ let pipeline_id = pipelines. specialize (
342
+ & mut pipeline_cache,
343
+ & material_pipeline,
344
+ ( mesh_key, specialized_key) ,
345
+ & mesh. layout ,
346
+ ) ;
347
+
348
+ // NOTE: row 2 of the inverse view matrix dotted with column 3 of the model matrix
349
+ // gives the z component of translation of the mesh in view space
350
+ let mesh_z = inverse_view_row_2. dot ( mesh_uniform. transform . col ( 3 ) ) ;
351
+ match alpha_mode {
352
+ AlphaMode :: Opaque => {
353
+ opaque_phase. add ( Opaque3d {
354
+ entity : * visible_entity,
355
+ draw_function : draw_opaque_pbr,
356
+ pipeline : pipeline_id,
357
+ // NOTE: Front-to-back ordering for opaque with ascending sort means near should have the
358
+ // lowest sort key and getting further away should increase. As we have
359
+ // -z in front of the camera, values in view space decrease away from the
360
+ // camera. Flipping the sign of mesh_z results in the correct front-to-back ordering
361
+ distance : -mesh_z,
362
+ } ) ;
363
+ }
364
+ AlphaMode :: Mask ( _) => {
365
+ alpha_mask_phase. add ( AlphaMask3d {
366
+ entity : * visible_entity,
367
+ draw_function : draw_alpha_mask_pbr,
368
+ pipeline : pipeline_id,
369
+ // NOTE: Front-to-back ordering for alpha mask with ascending sort means near should have the
370
+ // lowest sort key and getting further away should increase. As we have
371
+ // -z in front of the camera, values in view space decrease away from the
372
+ // camera. Flipping the sign of mesh_z results in the correct front-to-back ordering
373
+ distance : -mesh_z,
374
+ } ) ;
375
+ }
376
+ AlphaMode :: Blend => {
377
+ transparent_phase. add ( Transparent3d {
378
+ entity : * visible_entity,
379
+ draw_function : draw_transparent_pbr,
380
+ pipeline : pipeline_id,
381
+ // NOTE: Back-to-front ordering for transparent with ascending sort means far should have the
382
+ // lowest sort key and getting closer should increase. As we have
383
+ // -z in front of the camera, the largest distance is -far with values increasing toward the
384
+ // camera. As such we can just use mesh_z as the distance
385
+ distance : mesh_z,
386
+ } ) ;
387
+ }
376
388
}
377
389
}
378
390
}
0 commit comments