Stop extracting mesh entities to the render world. (#11803)
This fixes a `FIXME` in `extract_meshes` and results in a performance improvement. As a result of this change, meshes in the render world might not be attached to entities anymore. Therefore, the `entity` parameter to `RenderCommand::render()` is now wrapped in an `Option`. Most applications that use the render app's ECS can simply unwrap the `Option`. Note that for now sprites, gizmos, and UI elements still use the render world as usual. ## Migration guide * For efficiency reasons, some meshes in the render world may not have corresponding `Entity` IDs anymore. As a result, the `entity` parameter to `RenderCommand::render()` is now wrapped in an `Option`. Custom rendering code may need to be updated to handle the case in which no `Entity` exists for an object that is to be rendered.
This commit is contained in:
		
							parent
							
								
									55ada617cb
								
							
						
					
					
						commit
						3af8526786
					
				@ -383,10 +383,13 @@ impl<const I: usize, P: PhaseItem> RenderCommand<P> for SetLineGizmoBindGroup<I>
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        _view: ROQueryItem<'w, Self::ViewQuery>,
 | 
			
		||||
        uniform_index: ROQueryItem<'w, Self::ItemQuery>,
 | 
			
		||||
        uniform_index: Option<ROQueryItem<'w, Self::ItemQuery>>,
 | 
			
		||||
        bind_group: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
        let Some(uniform_index) = uniform_index else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
        pass.set_bind_group(
 | 
			
		||||
            I,
 | 
			
		||||
            &bind_group.into_inner().bindgroup,
 | 
			
		||||
@ -406,10 +409,13 @@ impl<P: PhaseItem> RenderCommand<P> for DrawLineGizmo {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        _view: ROQueryItem<'w, Self::ViewQuery>,
 | 
			
		||||
        handle: ROQueryItem<'w, Self::ItemQuery>,
 | 
			
		||||
        handle: Option<ROQueryItem<'w, Self::ItemQuery>>,
 | 
			
		||||
        line_gizmos: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
        let Some(handle) = handle else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
        let Some(line_gizmo) = line_gizmos.into_inner().get(handle) else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@ -388,7 +388,7 @@ impl<P: PhaseItem, M: Material, const I: usize> RenderCommand<P> for SetMaterial
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        _item_query: (),
 | 
			
		||||
        _item_query: Option<()>,
 | 
			
		||||
        (materials, material_instances): SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
 | 
			
		||||
@ -912,7 +912,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetPrepassViewBindGroup<
 | 
			
		||||
            &'_ ViewUniformOffset,
 | 
			
		||||
            Option<&'_ PreviousViewProjectionUniformOffset>,
 | 
			
		||||
        ),
 | 
			
		||||
        _entity: (),
 | 
			
		||||
        _entity: Option<()>,
 | 
			
		||||
        prepass_view_bind_group: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
 | 
			
		||||
@ -256,12 +256,7 @@ pub struct RenderMeshInstance {
 | 
			
		||||
#[derive(Default, Resource, Deref, DerefMut)]
 | 
			
		||||
pub struct RenderMeshInstances(EntityHashMap<Entity, RenderMeshInstance>);
 | 
			
		||||
 | 
			
		||||
#[derive(Component)]
 | 
			
		||||
pub struct Mesh3d;
 | 
			
		||||
 | 
			
		||||
pub fn extract_meshes(
 | 
			
		||||
    mut commands: Commands,
 | 
			
		||||
    mut previous_len: Local<usize>,
 | 
			
		||||
    mut render_mesh_instances: ResMut<RenderMeshInstances>,
 | 
			
		||||
    mut thread_local_queues: Local<ThreadLocal<Cell<Vec<(Entity, RenderMeshInstance)>>>>,
 | 
			
		||||
    meshes_query: Extract<
 | 
			
		||||
@ -328,15 +323,9 @@ pub fn extract_meshes(
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    render_mesh_instances.clear();
 | 
			
		||||
    let mut entities = Vec::with_capacity(*previous_len);
 | 
			
		||||
    for queue in thread_local_queues.iter_mut() {
 | 
			
		||||
        // FIXME: Remove this - it is just a workaround to enable rendering to work as
 | 
			
		||||
        // render commands require an entity to exist at the moment.
 | 
			
		||||
        entities.extend(queue.get_mut().iter().map(|(e, _)| (*e, Mesh3d)));
 | 
			
		||||
        render_mesh_instances.extend(queue.get_mut().drain(..));
 | 
			
		||||
    }
 | 
			
		||||
    *previous_len = entities.len();
 | 
			
		||||
    commands.insert_or_spawn_batch(entities);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Resource, Clone)]
 | 
			
		||||
@ -1050,7 +1039,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetMeshViewBindGroup<I>
 | 
			
		||||
            'w,
 | 
			
		||||
            Self::ViewQuery,
 | 
			
		||||
        >,
 | 
			
		||||
        _entity: (),
 | 
			
		||||
        _entity: Option<()>,
 | 
			
		||||
        _: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
@ -1085,7 +1074,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetMeshBindGroup<I> {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        _item_query: (),
 | 
			
		||||
        _item_query: Option<()>,
 | 
			
		||||
        (bind_groups, mesh_instances, skin_indices, morph_indices, lightmaps): SystemParamItem<
 | 
			
		||||
            'w,
 | 
			
		||||
            '_,
 | 
			
		||||
@ -1154,7 +1143,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMesh {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        _item_query: (),
 | 
			
		||||
        _item_query: Option<()>,
 | 
			
		||||
        (meshes, mesh_instances): SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
 | 
			
		||||
@ -190,6 +190,11 @@ pub trait RenderCommand<P: PhaseItem> {
 | 
			
		||||
    ///
 | 
			
		||||
    /// The item is the entity that will be rendered for the corresponding view.
 | 
			
		||||
    /// All components have to be accessed read only.
 | 
			
		||||
    ///
 | 
			
		||||
    /// For efficiency reasons, Bevy doesn't always extract entities to the
 | 
			
		||||
    /// render world; for instance, entities that simply consist of meshes are
 | 
			
		||||
    /// often not extracted. If the entity doesn't exist in the render world,
 | 
			
		||||
    /// the supplied query data will be `None`.
 | 
			
		||||
    type ItemQuery: ReadOnlyQueryData;
 | 
			
		||||
 | 
			
		||||
    /// Renders a [`PhaseItem`] by recording commands (e.g. setting pipelines, binding bind groups,
 | 
			
		||||
@ -197,7 +202,7 @@ pub trait RenderCommand<P: PhaseItem> {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        item: &P,
 | 
			
		||||
        view: ROQueryItem<'w, Self::ViewQuery>,
 | 
			
		||||
        entity: ROQueryItem<'w, Self::ItemQuery>,
 | 
			
		||||
        entity: Option<ROQueryItem<'w, Self::ItemQuery>>,
 | 
			
		||||
        param: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult;
 | 
			
		||||
@ -220,13 +225,22 @@ macro_rules! render_command_tuple_impl {
 | 
			
		||||
            fn render<'w>(
 | 
			
		||||
                _item: &P,
 | 
			
		||||
                ($($view,)*): ROQueryItem<'w, Self::ViewQuery>,
 | 
			
		||||
                ($($entity,)*): ROQueryItem<'w, Self::ItemQuery>,
 | 
			
		||||
                maybe_entities: Option<ROQueryItem<'w, Self::ItemQuery>>,
 | 
			
		||||
                ($($name,)*): SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
                _pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
            ) -> RenderCommandResult {
 | 
			
		||||
                $(if let RenderCommandResult::Failure = $name::render(_item, $view, $entity, $name, _pass) {
 | 
			
		||||
                match maybe_entities {
 | 
			
		||||
                    None => {
 | 
			
		||||
                        $(if let RenderCommandResult::Failure = $name::render(_item, $view, None, $name, _pass) {
 | 
			
		||||
                            return RenderCommandResult::Failure;
 | 
			
		||||
                        })*
 | 
			
		||||
                    }
 | 
			
		||||
                    Some(($($entity,)*)) => {
 | 
			
		||||
                        $(if let RenderCommandResult::Failure = $name::render(_item, $view, Some($entity), $name, _pass) {
 | 
			
		||||
                            return RenderCommandResult::Failure;
 | 
			
		||||
                        })*
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                RenderCommandResult::Success
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@ -278,7 +292,7 @@ where
 | 
			
		||||
    ) {
 | 
			
		||||
        let param = self.state.get_manual(world);
 | 
			
		||||
        let view = self.view.get_manual(world, view).unwrap();
 | 
			
		||||
        let entity = self.entity.get_manual(world, item.entity()).unwrap();
 | 
			
		||||
        let entity = self.entity.get_manual(world, item.entity()).ok();
 | 
			
		||||
        // TODO: handle/log `RenderCommand` failure
 | 
			
		||||
        C::render(item, view, entity, param, pass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -202,7 +202,7 @@ impl<P: CachedRenderPipelinePhaseItem> RenderCommand<P> for SetItemPipeline {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        _entity: (),
 | 
			
		||||
        _entity: Option<()>,
 | 
			
		||||
        pipeline_cache: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
 | 
			
		||||
@ -337,7 +337,7 @@ impl<P: PhaseItem, M: Material2d, const I: usize> RenderCommand<P>
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        _item_query: (),
 | 
			
		||||
        _item_query: Option<()>,
 | 
			
		||||
        (materials, material_instances): SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
 | 
			
		||||
@ -624,7 +624,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetMesh2dViewBindGroup<I
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        (view_uniform, mesh2d_view_bind_group): ROQueryItem<'w, Self::ViewQuery>,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        _view: Option<()>,
 | 
			
		||||
        _param: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
@ -644,7 +644,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetMesh2dBindGroup<I> {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        _item_query: (),
 | 
			
		||||
        _item_query: Option<()>,
 | 
			
		||||
        mesh2d_bind_group: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
@ -673,7 +673,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMesh2d {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        _item_query: (),
 | 
			
		||||
        _item_query: Option<()>,
 | 
			
		||||
        (meshes, render_mesh2d_instances): SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
 | 
			
		||||
@ -752,7 +752,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetSpriteViewBindGroup<I
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        view_uniform: &'_ ViewUniformOffset,
 | 
			
		||||
        _entity: (),
 | 
			
		||||
        _entity: Option<()>,
 | 
			
		||||
        sprite_meta: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
@ -773,11 +773,14 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetSpriteTextureBindGrou
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        batch: &'_ SpriteBatch,
 | 
			
		||||
        batch: Option<&'_ SpriteBatch>,
 | 
			
		||||
        image_bind_groups: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
        let image_bind_groups = image_bind_groups.into_inner();
 | 
			
		||||
        let Some(batch) = batch else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pass.set_bind_group(
 | 
			
		||||
            I,
 | 
			
		||||
@ -800,11 +803,15 @@ impl<P: PhaseItem> RenderCommand<P> for DrawSpriteBatch {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        batch: &'_ SpriteBatch,
 | 
			
		||||
        batch: Option<&'_ SpriteBatch>,
 | 
			
		||||
        sprite_meta: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
        let sprite_meta = sprite_meta.into_inner();
 | 
			
		||||
        let Some(batch) = batch else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pass.set_index_buffer(
 | 
			
		||||
            sprite_meta.sprite_index_buffer.buffer().unwrap().slice(..),
 | 
			
		||||
            0,
 | 
			
		||||
 | 
			
		||||
@ -161,7 +161,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetUiViewBindGroup<I> {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        view_uniform: &'w ViewUniformOffset,
 | 
			
		||||
        _entity: (),
 | 
			
		||||
        _entity: Option<()>,
 | 
			
		||||
        ui_meta: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
@ -183,11 +183,15 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetUiTextureBindGroup<I>
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        batch: &'w UiBatch,
 | 
			
		||||
        batch: Option<&'w UiBatch>,
 | 
			
		||||
        image_bind_groups: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
        let image_bind_groups = image_bind_groups.into_inner();
 | 
			
		||||
        let Some(batch) = batch else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pass.set_bind_group(I, image_bind_groups.values.get(&batch.image).unwrap(), &[]);
 | 
			
		||||
        RenderCommandResult::Success
 | 
			
		||||
    }
 | 
			
		||||
@ -202,10 +206,14 @@ impl<P: PhaseItem> RenderCommand<P> for DrawUiNode {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        batch: &'w UiBatch,
 | 
			
		||||
        batch: Option<&'w UiBatch>,
 | 
			
		||||
        ui_meta: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
        let Some(batch) = batch else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pass.set_vertex_buffer(0, ui_meta.into_inner().vertices.buffer().unwrap().slice(..));
 | 
			
		||||
        pass.draw(batch.range.clone(), 0..1);
 | 
			
		||||
        RenderCommandResult::Success
 | 
			
		||||
 | 
			
		||||
@ -272,7 +272,7 @@ impl<P: PhaseItem, M: UiMaterial, const I: usize> RenderCommand<P> for SetMatUiV
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        view_uniform: &'w ViewUniformOffset,
 | 
			
		||||
        _entity: (),
 | 
			
		||||
        _entity: Option<()>,
 | 
			
		||||
        ui_meta: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
@ -296,10 +296,13 @@ impl<P: PhaseItem, M: UiMaterial, const I: usize> RenderCommand<P>
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        material_handle: ROQueryItem<'_, Self::ItemQuery>,
 | 
			
		||||
        material_handle: Option<ROQueryItem<'_, Self::ItemQuery>>,
 | 
			
		||||
        materials: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
        let Some(material_handle) = material_handle else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
        let Some(material) = materials.into_inner().get(&material_handle.material) else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
@ -318,10 +321,14 @@ impl<P: PhaseItem, M: UiMaterial> RenderCommand<P> for DrawUiMaterialNode<M> {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        _item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        batch: &'w UiMaterialBatch<M>,
 | 
			
		||||
        batch: Option<&'w UiMaterialBatch<M>>,
 | 
			
		||||
        ui_meta: SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
        let Some(batch) = batch else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pass.set_vertex_buffer(0, ui_meta.into_inner().vertices.buffer().unwrap().slice(..));
 | 
			
		||||
        pass.draw(batch.range.clone(), 0..1);
 | 
			
		||||
        RenderCommandResult::Success
 | 
			
		||||
 | 
			
		||||
@ -244,7 +244,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMeshInstanced {
 | 
			
		||||
    fn render<'w>(
 | 
			
		||||
        item: &P,
 | 
			
		||||
        _view: (),
 | 
			
		||||
        instance_buffer: &'w InstanceBuffer,
 | 
			
		||||
        instance_buffer: Option<&'w InstanceBuffer>,
 | 
			
		||||
        (meshes, render_mesh_instances): SystemParamItem<'w, '_, Self::Param>,
 | 
			
		||||
        pass: &mut TrackedRenderPass<'w>,
 | 
			
		||||
    ) -> RenderCommandResult {
 | 
			
		||||
@ -254,6 +254,9 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMeshInstanced {
 | 
			
		||||
        let Some(gpu_mesh) = meshes.into_inner().get(mesh_instance.mesh_asset_id) else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
        let Some(instance_buffer) = instance_buffer else {
 | 
			
		||||
            return RenderCommandResult::Failure;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..));
 | 
			
		||||
        pass.set_vertex_buffer(1, instance_buffer.buffer.slice(..));
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user