From bf2385f167f903be1bc821cc44bad382225a2f0b Mon Sep 17 00:00:00 2001 From: Robin KAY Date: Wed, 22 Nov 2023 00:57:07 +0000 Subject: [PATCH] Fix bind group errors when prepasses are enabled. --- src/draw.rs | 12 +++++------ src/fragment.wgsl | 2 +- src/outline.wgsl | 6 +++--- src/pipeline.rs | 49 +++++++++++++++++++++++--------------------- src/view_uniforms.rs | 38 +++++++++++++++++++++++++--------- 5 files changed, 63 insertions(+), 44 deletions(-) diff --git a/src/draw.rs b/src/draw.rs index 06e4817..7d9b5e3 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -1,4 +1,4 @@ -use bevy::pbr::{DrawMesh, SetMeshBindGroup, SetMeshViewBindGroup}; +use bevy::pbr::{DrawMesh, SetMeshBindGroup}; use bevy::prelude::*; use bevy::render::render_asset::RenderAssets; use bevy::render::render_phase::{DrawFunctions, RenderPhase, SetItemPipeline}; @@ -16,10 +16,9 @@ use crate::OutlineRenderLayers; pub(crate) type DrawStencil = ( SetItemPipeline, - SetMeshViewBindGroup<0>, + SetOutlineViewBindGroup<0>, SetMeshBindGroup<1>, - SetOutlineViewBindGroup<2>, - SetOutlineStencilBindGroup<3>, + SetOutlineStencilBindGroup<2>, DrawMesh, ); @@ -87,10 +86,9 @@ pub(crate) fn queue_outline_stencil_mesh( pub(crate) type DrawOutline = ( SetItemPipeline, - SetMeshViewBindGroup<0>, + SetOutlineViewBindGroup<0>, SetMeshBindGroup<1>, - SetOutlineViewBindGroup<2>, - SetOutlineVolumeBindGroup<3>, + SetOutlineVolumeBindGroup<2>, DrawMesh, ); diff --git a/src/fragment.wgsl b/src/fragment.wgsl index dd1d197..1e31003 100644 --- a/src/fragment.wgsl +++ b/src/fragment.wgsl @@ -11,7 +11,7 @@ struct OutlineFragmentUniform { }; #ifdef VOLUME -@group(3) @binding(1) +@group(2) @binding(1) var fstage: OutlineFragmentUniform; #endif diff --git a/src/outline.wgsl b/src/outline.wgsl index a47fb00..069e1f0 100644 --- a/src/outline.wgsl +++ b/src/outline.wgsl @@ -42,14 +42,14 @@ struct OutlineVertexUniform { @group(0) @binding(0) var view: View; +@group(0) @binding(1) +var view_uniform: OutlineViewUniform; + #import bevy_pbr::mesh_bindings #import bevy_pbr::skinning #import bevy_pbr::morph @group(2) @binding(0) -var view_uniform: OutlineViewUniform; - -@group(3) @binding(0) var vstage: OutlineVertexUniform; #ifdef MORPH_TARGETS diff --git a/src/pipeline.rs b/src/pipeline.rs index 058be66..1cebe5f 100644 --- a/src/pipeline.rs +++ b/src/pipeline.rs @@ -4,8 +4,7 @@ use bevy::ecs::query::QueryItem; use bevy::ecs::system::lifetimeless::Read; use bevy::ecs::system::SystemParamItem; use bevy::pbr::{ - setup_morph_and_skinning_defs, MeshFlags, MeshPipelineKey, MeshPipelineViewLayoutKey, - MeshTransforms, MeshUniform, + setup_morph_and_skinning_defs, MeshFlags, MeshPipelineKey, MeshTransforms, MeshUniform, }; use bevy::prelude::*; use bevy::render::batching::GetBatchData; @@ -13,13 +12,13 @@ use bevy::render::render_resource::{ BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, BlendState, BufferBindingType, BufferSize, ColorTargetState, ColorWrites, CompareFunction, DepthBiasState, DepthStencilState, Face, FragmentState, FrontFace, MultisampleState, PolygonMode, - PrimitiveState, PrimitiveTopology, ShaderDefVal, ShaderSize, ShaderStages, StencilState, - TextureFormat, VertexState, + PrimitiveState, PrimitiveTopology, ShaderDefVal, ShaderSize, ShaderStages, ShaderType, + StencilState, TextureFormat, VertexState, }; use bevy::render::renderer::RenderDevice; use bevy::render::settings::WgpuSettings; use bevy::render::texture::BevyDefault; -use bevy::render::view::ViewTarget; +use bevy::render::view::{ViewTarget, ViewUniform}; use bevy::{ pbr::MeshPipeline, render::{ @@ -172,16 +171,28 @@ impl FromWorld for OutlinePipeline { let outline_view_bind_group_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { label: Some("outline_view_bind_group_layout"), - entries: &[BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::VERTEX, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: true, - min_binding_size: BufferSize::new(OutlineViewUniform::SHADER_SIZE.get()), + entries: &[ + BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::VERTEX, + ty: BindingType::Buffer { + ty: BufferBindingType::Uniform, + has_dynamic_offset: true, + min_binding_size: Some(ViewUniform::min_size()), + }, + count: None, }, - count: None, - }], + BindGroupLayoutEntry { + binding: 1, + visibility: ShaderStages::VERTEX, + ty: BindingType::Buffer { + ty: BufferBindingType::Uniform, + has_dynamic_offset: true, + min_binding_size: Some(OutlineViewUniform::min_size()), + }, + count: None, + }, + ], }); let outline_volume_bind_group_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { @@ -254,14 +265,7 @@ impl SpecializedMeshPipeline for OutlinePipeline { buffer_attrs.push(Mesh::ATTRIBUTE_POSITION.at_shader_location(0)); } - let mut bind_layouts = vec![self - .mesh_pipeline - .get_view_layout(if key.msaa() == Msaa::Off { - MeshPipelineViewLayoutKey::empty() - } else { - MeshPipelineViewLayoutKey::MULTISAMPLED - }) - .clone()]; + let mut bind_layouts = vec![self.outline_view_bind_group_layout.clone()]; bind_layouts.push(setup_morph_and_skinning_defs( &self.mesh_pipeline.mesh_layouts, @@ -272,7 +276,6 @@ impl SpecializedMeshPipeline for OutlinePipeline { &mut buffer_attrs, )); - bind_layouts.push(self.outline_view_bind_group_layout.clone()); let cull_mode; if key.depth_mode() == DepthMode::Flat { let val = ShaderDefVal::from("FLAT_DEPTH"); diff --git a/src/view_uniforms.rs b/src/view_uniforms.rs index b503ab9..5582e92 100644 --- a/src/view_uniforms.rs +++ b/src/view_uniforms.rs @@ -1,3 +1,4 @@ +use bevy::ecs::query::ROQueryItem; use bevy::ecs::system::lifetimeless::{Read, SRes}; use bevy::ecs::system::SystemParamItem; use bevy::prelude::*; @@ -8,7 +9,7 @@ use bevy::render::render_phase::{ use bevy::render::render_resource::ShaderType; use bevy::render::render_resource::{BindGroup, BindGroupEntry}; use bevy::render::renderer::RenderDevice; -use bevy::render::view::RenderLayers; +use bevy::render::view::{RenderLayers, ViewUniformOffset, ViewUniforms}; use bevy::render::Extract; use crate::node::{OpaqueOutline, StencilOutline, TransparentOutline}; @@ -53,16 +54,26 @@ pub(crate) fn prepare_outline_view_bind_group( mut commands: Commands, render_device: Res, outline_pipeline: Res, - view_uniforms: Res>, + core_view_uniforms: Res, + outline_view_uniforms: Res>, ) { - if let Some(view_binding) = view_uniforms.binding() { + if let (Some(core_view_binding), Some(outline_view_binding)) = ( + core_view_uniforms.uniforms.binding(), + outline_view_uniforms.binding(), + ) { let bind_group = render_device.create_bind_group( "outline_view_bind_group", &outline_pipeline.outline_view_bind_group_layout, - &[BindGroupEntry { - binding: 0, - resource: view_binding.clone(), - }], + &[ + BindGroupEntry { + binding: 0, + resource: core_view_binding.clone(), + }, + BindGroupEntry { + binding: 1, + resource: outline_view_binding.clone(), + }, + ], ); commands.insert_resource(OutlineViewBindGroup { bind_group }); } @@ -71,17 +82,24 @@ pub(crate) fn prepare_outline_view_bind_group( pub(crate) struct SetOutlineViewBindGroup(); impl RenderCommand

for SetOutlineViewBindGroup { - type ViewWorldQuery = Read>; + type ViewWorldQuery = ( + Read, + Read>, + ); type ItemWorldQuery = (); type Param = SRes; fn render<'w>( _item: &P, - view_data: &DynamicUniformIndex, + (core_view_data, outline_view_data): ROQueryItem<'w, Self::ViewWorldQuery>, _entity_data: (), bind_group: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - pass.set_bind_group(I, &bind_group.into_inner().bind_group, &[view_data.index()]); + pass.set_bind_group( + I, + &bind_group.into_inner().bind_group, + &[core_view_data.offset, outline_view_data.index()], + ); RenderCommandResult::Success } }