From 38d6e6341619e7805f94ac3ca91266e1af24f376 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Wed, 25 Aug 2021 11:20:13 +0200 Subject: [PATCH 1/2] bevy_pbr2: Use a separate shader for the shadow pass --- pipelined/bevy_pbr2/src/render/depth.wgsl | 30 +++++++++++++++++++++++ pipelined/bevy_pbr2/src/render/light.rs | 8 +++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 pipelined/bevy_pbr2/src/render/depth.wgsl diff --git a/pipelined/bevy_pbr2/src/render/depth.wgsl b/pipelined/bevy_pbr2/src/render/depth.wgsl new file mode 100644 index 0000000000000..9313118d16f1d --- /dev/null +++ b/pipelined/bevy_pbr2/src/render/depth.wgsl @@ -0,0 +1,30 @@ +[[block]] +struct View { + view_proj: mat4x4; + world_position: vec3; +}; +[[group(0), binding(0)]] +var view: View; + + +[[block]] +struct Mesh { + transform: mat4x4; +}; +[[group(1), binding(0)]] +var mesh: Mesh; + +struct Vertex { + [[location(0)]] position: vec3; +}; + +struct VertexOutput { + [[builtin(position)]] clip_position: vec4; +}; + +[[stage(vertex)]] +fn vertex(vertex: Vertex) -> VertexOutput { + var out: VertexOutput; + out.clip_position = view.view_proj * mesh.transform * vec4(vertex.position, 1.0); + return out; +} diff --git a/pipelined/bevy_pbr2/src/render/light.rs b/pipelined/bevy_pbr2/src/render/light.rs index c77e021aeb6ff..4f0956782907c 100644 --- a/pipelined/bevy_pbr2/src/render/light.rs +++ b/pipelined/bevy_pbr2/src/render/light.rs @@ -14,12 +14,14 @@ use bevy_render2::{ render_phase::{Draw, DrawFunctions, RenderPhase, TrackedRenderPass}, render_resource::*, renderer::{RenderContext, RenderDevice}, + shader::Shader, texture::*, view::{ExtractedView, ViewUniformOffset}, }; use bevy_transform::components::GlobalTransform; use crevice::std140::AsStd140; use std::num::NonZeroU32; +use wgpu::ShaderModel; pub struct ExtractedAmbientLight { color: Color, @@ -93,6 +95,7 @@ pub const DIRECTIONAL_SHADOW_LAYERS: u32 = MAX_DIRECTIONAL_LIGHTS as u32; pub const SHADOW_FORMAT: TextureFormat = TextureFormat::Depth32Float; pub struct ShadowShaders { + pub shader_module: ShaderModule, pub pipeline: RenderPipeline, pub view_layout: BindGroupLayout, pub point_light_sampler: Sampler, @@ -104,6 +107,8 @@ impl FromWorld for ShadowShaders { fn from_world(world: &mut World) -> Self { let render_device = world.get_resource::().unwrap(); let pbr_shaders = world.get_resource::().unwrap(); + let shader = Shader::from_wgsl(include_str!("depth.wgsl")); + let shader_module = render_device.create_shader_module(&shader); let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { entries: &[ @@ -157,7 +162,7 @@ impl FromWorld for ShadowShaders { }, ], }], - module: &pbr_shaders.shader_module, + module: &shader_module, entry_point: "vertex", }, fragment: None, @@ -191,6 +196,7 @@ impl FromWorld for ShadowShaders { }); ShadowShaders { + shader_module, pipeline, view_layout, point_light_sampler: render_device.create_sampler(&SamplerDescriptor { From 24d9d0e9b3f6ed68eebc3869e6db925f4ec8dd45 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Wed, 25 Aug 2021 11:23:32 +0200 Subject: [PATCH 2/2] bevy_pbr2: Reorder bind groups to be view, material, mesh order --- pipelined/bevy_pbr2/src/render/light.rs | 1 - pipelined/bevy_pbr2/src/render/mod.rs | 46 ++++++++++++------------- pipelined/bevy_pbr2/src/render/pbr.wgsl | 20 +++++------ 3 files changed, 32 insertions(+), 35 deletions(-) diff --git a/pipelined/bevy_pbr2/src/render/light.rs b/pipelined/bevy_pbr2/src/render/light.rs index 4f0956782907c..c26a4b754ed5e 100644 --- a/pipelined/bevy_pbr2/src/render/light.rs +++ b/pipelined/bevy_pbr2/src/render/light.rs @@ -21,7 +21,6 @@ use bevy_render2::{ use bevy_transform::components::GlobalTransform; use crevice::std140::AsStd140; use std::num::NonZeroU32; -use wgpu::ShaderModel; pub struct ExtractedAmbientLight { color: Color, diff --git a/pipelined/bevy_pbr2/src/render/mod.rs b/pipelined/bevy_pbr2/src/render/mod.rs index 915657d60d5b7..683ad9b5db21c 100644 --- a/pipelined/bevy_pbr2/src/render/mod.rs +++ b/pipelined/bevy_pbr2/src/render/mod.rs @@ -27,7 +27,6 @@ use wgpu::{ pub struct PbrShaders { pipeline: RenderPipeline, - shader_module: ShaderModule, view_layout: BindGroupLayout, material_layout: BindGroupLayout, mesh_layout: BindGroupLayout, @@ -117,20 +116,6 @@ impl FromWorld for PbrShaders { label: None, }); - let mesh_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStage::VERTEX | ShaderStage::FRAGMENT, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: true, - min_binding_size: BufferSize::new(80), - }, - count: None, - }], - label: None, - }); - let material_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { entries: &[ BindGroupLayoutEntry { @@ -233,10 +218,24 @@ impl FromWorld for PbrShaders { label: None, }); + let mesh_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { + entries: &[BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStage::VERTEX | ShaderStage::FRAGMENT, + ty: BindingType::Buffer { + ty: BufferBindingType::Uniform, + has_dynamic_offset: true, + min_binding_size: BufferSize::new(80), + }, + count: None, + }], + label: None, + }); + let pipeline_layout = render_device.create_pipeline_layout(&PipelineLayoutDescriptor { label: None, push_constant_ranges: &[], - bind_group_layouts: &[&view_layout, &mesh_layout, &material_layout], + bind_group_layouts: &[&view_layout, &material_layout, &mesh_layout], }); let pipeline = render_device.create_render_pipeline(&RenderPipelineDescriptor { @@ -360,7 +359,6 @@ impl FromWorld for PbrShaders { }; PbrShaders { pipeline, - shader_module, view_layout, material_layout, mesh_layout, @@ -818,21 +816,21 @@ impl Draw for DrawPbr { &mesh_view_bind_groups.view, &[view_uniforms.offset, view_lights.gpu_light_binding_index], ); + let mesh_draw_info = &mesh_meta.mesh_draw_info[draw_key]; pass.set_bind_group( 1, + // &mesh_meta.material_bind_groups[sort_key & ((1 << 10) - 1)], + &mesh_meta.material_bind_groups[mesh_draw_info.material_bind_group_key], + &[], + ); + pass.set_bind_group( + 2, mesh_meta .mesh_transform_bind_group .get_value(mesh_meta.mesh_transform_bind_group_key.unwrap()) .unwrap(), &[extracted_mesh.transform_binding_offset], ); - let mesh_draw_info = &mesh_meta.mesh_draw_info[draw_key]; - pass.set_bind_group( - 2, - // &mesh_meta.material_bind_groups[sort_key & ((1 << 10) - 1)], - &mesh_meta.material_bind_groups[mesh_draw_info.material_bind_group_key], - &[], - ); let gpu_mesh = meshes.into_inner().get(&extracted_mesh.mesh).unwrap(); pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..)); diff --git a/pipelined/bevy_pbr2/src/render/pbr.wgsl b/pipelined/bevy_pbr2/src/render/pbr.wgsl index 81be4e8241a33..de9c856be9e53 100644 --- a/pipelined/bevy_pbr2/src/render/pbr.wgsl +++ b/pipelined/bevy_pbr2/src/render/pbr.wgsl @@ -17,7 +17,7 @@ let MESH_FLAGS_SHADOW_RECEIVER_BIT: u32 = 1u; [[group(0), binding(0)]] var view: View; -[[group(1), binding(0)]] +[[group(2), binding(0)]] var mesh: Mesh; struct Vertex { @@ -142,23 +142,23 @@ var directional_shadow_textures: texture_depth_2d_array; [[group(0), binding(5)]] var directional_shadow_textures_sampler: sampler_comparison; -[[group(2), binding(0)]] +[[group(1), binding(0)]] var material: StandardMaterial; -[[group(2), binding(1)]] +[[group(1), binding(1)]] var base_color_texture: texture_2d; -[[group(2), binding(2)]] +[[group(1), binding(2)]] var base_color_sampler: sampler; -[[group(2), binding(3)]] +[[group(1), binding(3)]] var emissive_texture: texture_2d; -[[group(2), binding(4)]] +[[group(1), binding(4)]] var emissive_sampler: sampler; -[[group(2), binding(5)]] +[[group(1), binding(5)]] var metallic_roughness_texture: texture_2d; -[[group(2), binding(6)]] +[[group(1), binding(6)]] var metallic_roughness_sampler: sampler; -[[group(2), binding(7)]] +[[group(1), binding(7)]] var occlusion_texture: texture_2d; -[[group(2), binding(8)]] +[[group(1), binding(8)]] var occlusion_sampler: sampler; let PI: f32 = 3.141592653589793;