1
1
use bevy:: {
2
- core_pipeline:: { SetItemPipeline , Transparent3d } ,
2
+ core_pipeline:: Transparent3d ,
3
3
diagnostic:: { FrameTimeDiagnosticsPlugin , LogDiagnosticsPlugin } ,
4
4
ecs:: {
5
5
prelude:: * ,
@@ -19,11 +19,12 @@ use bevy::{
19
19
render_asset:: { PrepareAssetError , RenderAsset , RenderAssetPlugin , RenderAssets } ,
20
20
render_component:: ExtractComponentPlugin ,
21
21
render_phase:: {
22
- AddRenderCommand , DrawFunctions , RenderCommand , RenderPhase , TrackedRenderPass ,
22
+ AddRenderCommand , DrawFunctions , EntityRenderCommand , RenderPhase , SetItemPipeline ,
23
+ TrackedRenderPass ,
23
24
} ,
24
25
render_resource:: * ,
25
26
renderer:: RenderDevice ,
26
- view:: ExtractedView ,
27
+ view:: { ComputedVisibility , ExtractedView , Msaa , Visibility } ,
27
28
RenderApp , RenderStage ,
28
29
} ,
29
30
PipelinedDefaultPlugins ,
@@ -51,6 +52,8 @@ fn setup(
51
52
meshes. add ( Mesh :: from ( shape:: Cube { size : 1.0 } ) ) ,
52
53
Transform :: from_xyz ( 0.0 , 0.5 , 0.0 ) ,
53
54
GlobalTransform :: default ( ) ,
55
+ Visibility :: default ( ) ,
56
+ ComputedVisibility :: default ( ) ,
54
57
materials. add ( CustomMaterial {
55
58
color : Color :: GREEN ,
56
59
} ) ,
@@ -118,21 +121,36 @@ impl Plugin for CustomMaterialPlugin {
118
121
app. sub_app ( RenderApp )
119
122
. add_render_command :: < Transparent3d , DrawCustom > ( )
120
123
. init_resource :: < CustomPipeline > ( )
124
+ . init_resource :: < SpecializedPipelines < CustomPipeline > > ( )
121
125
. add_system_to_stage ( RenderStage :: Queue , queue_custom) ;
122
126
}
123
127
}
124
128
125
129
pub struct CustomPipeline {
126
130
material_layout : BindGroupLayout ,
127
- pipeline : CachedPipelineId ,
131
+ shader : Handle < Shader > ,
132
+ pbr_pipeline : PbrPipeline ,
133
+ }
134
+
135
+ impl SpecializedPipeline for CustomPipeline {
136
+ type Key = PbrPipelineKey ;
137
+
138
+ fn specialize ( & self , key : Self :: Key ) -> RenderPipelineDescriptor {
139
+ let mut descriptor = self . pbr_pipeline . specialize ( key) ;
140
+ descriptor. vertex . shader = self . shader . clone ( ) ;
141
+ descriptor. fragment . as_mut ( ) . unwrap ( ) . shader = self . shader . clone ( ) ;
142
+ descriptor. layout = Some ( vec ! [
143
+ self . pbr_pipeline. view_layout. clone( ) ,
144
+ self . pbr_pipeline. mesh_layout. clone( ) ,
145
+ self . material_layout. clone( ) ,
146
+ ] ) ;
147
+ descriptor
148
+ }
128
149
}
129
150
130
151
impl FromWorld for CustomPipeline {
131
152
fn from_world ( world : & mut World ) -> Self {
132
- let world = world. cell ( ) ;
133
153
let asset_server = world. get_resource :: < AssetServer > ( ) . unwrap ( ) ;
134
- let shader = asset_server. load ( "shaders/custom.wgsl" ) ;
135
-
136
154
let render_device = world. get_resource :: < RenderDevice > ( ) . unwrap ( ) ;
137
155
let material_layout = render_device. create_bind_group_layout ( & BindGroupLayoutDescriptor {
138
156
entries : & [ BindGroupLayoutEntry {
@@ -148,43 +166,42 @@ impl FromWorld for CustomPipeline {
148
166
label : None ,
149
167
} ) ;
150
168
151
- let pbr_pipeline = world. get_resource :: < PbrPipeline > ( ) . unwrap ( ) ;
152
- let mut descriptor = pbr_pipeline. specialize ( PbrPipelineKey :: empty ( ) ) ;
153
- descriptor. vertex . shader = shader. clone ( ) ;
154
- descriptor. fragment . as_mut ( ) . unwrap ( ) . shader = shader;
155
- descriptor. layout = Some ( vec ! [
156
- pbr_pipeline. view_layout. clone( ) ,
157
- material_layout. clone( ) ,
158
- pbr_pipeline. mesh_layout. clone( ) ,
159
- ] ) ;
160
-
161
- let mut pipeline_cache = world. get_resource_mut :: < RenderPipelineCache > ( ) . unwrap ( ) ;
162
169
CustomPipeline {
163
- pipeline : pipeline_cache. queue ( descriptor) ,
170
+ pbr_pipeline : world. get_resource :: < PbrPipeline > ( ) . unwrap ( ) . clone ( ) ,
171
+ shader : asset_server. load ( "shaders/custom.wgsl" ) ,
164
172
material_layout,
165
173
}
166
174
}
167
175
}
168
176
177
+ #[ allow( clippy:: too_many_arguments) ]
169
178
pub fn queue_custom (
170
179
transparent_3d_draw_functions : Res < DrawFunctions < Transparent3d > > ,
171
180
materials : Res < RenderAssets < CustomMaterial > > ,
172
181
custom_pipeline : Res < CustomPipeline > ,
182
+ mut pipeline_cache : ResMut < RenderPipelineCache > ,
183
+ mut specialized_pipelines : ResMut < SpecializedPipelines < CustomPipeline > > ,
184
+ msaa : Res < Msaa > ,
173
185
material_meshes : Query < ( Entity , & Handle < CustomMaterial > , & MeshUniform ) , With < Handle < Mesh > > > ,
174
186
mut views : Query < ( & ExtractedView , & mut RenderPhase < Transparent3d > ) > ,
175
187
) {
176
188
let draw_custom = transparent_3d_draw_functions
177
189
. read ( )
178
190
. get_id :: < DrawCustom > ( )
179
191
. unwrap ( ) ;
192
+ let key = PbrPipelineKey :: from_msaa_samples ( msaa. samples ) ;
180
193
for ( view, mut transparent_phase) in views. iter_mut ( ) {
181
194
let view_matrix = view. transform . compute_matrix ( ) ;
182
195
let view_row_2 = view_matrix. row ( 2 ) ;
183
196
for ( entity, material_handle, mesh_uniform) in material_meshes. iter ( ) {
184
197
if materials. contains_key ( material_handle) {
185
198
transparent_phase. add ( Transparent3d {
186
199
entity,
187
- pipeline : custom_pipeline. pipeline ,
200
+ pipeline : specialized_pipelines. specialize (
201
+ & mut pipeline_cache,
202
+ & custom_pipeline,
203
+ key,
204
+ ) ,
188
205
draw_function : draw_custom,
189
206
distance : view_row_2. dot ( mesh_uniform. transform . col ( 3 ) ) ,
190
207
} ) ;
@@ -196,25 +213,25 @@ pub fn queue_custom(
196
213
type DrawCustom = (
197
214
SetItemPipeline ,
198
215
SetMeshViewBindGroup < 0 > ,
216
+ SetTransformBindGroup < 1 > ,
199
217
SetCustomMaterialBindGroup ,
200
- SetTransformBindGroup < 2 > ,
201
218
DrawMesh ,
202
219
) ;
203
220
204
221
struct SetCustomMaterialBindGroup ;
205
- impl RenderCommand < Transparent3d > for SetCustomMaterialBindGroup {
222
+ impl EntityRenderCommand for SetCustomMaterialBindGroup {
206
223
type Param = (
207
224
SRes < RenderAssets < CustomMaterial > > ,
208
225
SQuery < Read < Handle < CustomMaterial > > > ,
209
226
) ;
210
227
fn render < ' w > (
211
228
_view : Entity ,
212
- item : & Transparent3d ,
229
+ item : Entity ,
213
230
( materials, query) : SystemParamItem < ' w , ' _ , Self :: Param > ,
214
231
pass : & mut TrackedRenderPass < ' w > ,
215
232
) {
216
- let material_handle = query. get ( item. entity ) . unwrap ( ) ;
233
+ let material_handle = query. get ( item) . unwrap ( ) ;
217
234
let material = materials. into_inner ( ) . get ( material_handle) . unwrap ( ) ;
218
- pass. set_bind_group ( 1 , & material. bind_group , & [ ] ) ;
235
+ pass. set_bind_group ( 2 , & material. bind_group , & [ ] ) ;
219
236
}
220
237
}
0 commit comments