Skip to content

Commit

Permalink
Pipelined separate shadow vertex shader (#2727)
Browse files Browse the repository at this point in the history
# Objective

- Avoid unnecessary work in the vertex shader of the numerous shadow passes
- Have the natural order of bind groups in the pbr shader: view, material, mesh

## Solution

- Separate out the vertex stage of pbr.wgsl into depth.wgsl
- Remove the unnecessary calculation of uv and normal, as well as removing the unnecessary vertex inputs and outputs
- Use the depth.wgsl for shadow passes
- Reorder the bind groups in pbr.wgsl and PbrShaders to be 0 - view, 1 - material, 2 - mesh in decreasing order of rebind frequency
  • Loading branch information
superdump committed Aug 25, 2021
1 parent f4aa328 commit dd32cd0
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 35 deletions.
30 changes: 30 additions & 0 deletions pipelined/bevy_pbr2/src/render/depth.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[[block]]
struct View {
view_proj: mat4x4<f32>;
world_position: vec3<f32>;
};
[[group(0), binding(0)]]
var view: View;


[[block]]
struct Mesh {
transform: mat4x4<f32>;
};
[[group(1), binding(0)]]
var mesh: Mesh;

struct Vertex {
[[location(0)]] position: vec3<f32>;
};

struct VertexOutput {
[[builtin(position)]] clip_position: vec4<f32>;
};

[[stage(vertex)]]
fn vertex(vertex: Vertex) -> VertexOutput {
var out: VertexOutput;
out.clip_position = view.view_proj * mesh.transform * vec4<f32>(vertex.position, 1.0);
return out;
}
7 changes: 6 additions & 1 deletion pipelined/bevy_pbr2/src/render/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use bevy_render2::{
render_phase::{Draw, DrawFunctions, RenderPhase, TrackedRenderPass},
render_resource::*,
renderer::{RenderContext, RenderDevice},
shader::Shader,
texture::*,
view::{ExtractedView, ViewUniformOffset},
};
Expand Down Expand Up @@ -93,6 +94,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,
Expand All @@ -104,6 +106,8 @@ impl FromWorld for ShadowShaders {
fn from_world(world: &mut World) -> Self {
let render_device = world.get_resource::<RenderDevice>().unwrap();
let pbr_shaders = world.get_resource::<PbrShaders>().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: &[
Expand Down Expand Up @@ -157,7 +161,7 @@ impl FromWorld for ShadowShaders {
},
],
}],
module: &pbr_shaders.shader_module,
module: &shader_module,
entry_point: "vertex",
},
fragment: None,
Expand Down Expand Up @@ -191,6 +195,7 @@ impl FromWorld for ShadowShaders {
});

ShadowShaders {
shader_module,
pipeline,
view_layout,
point_light_sampler: render_device.create_sampler(&SamplerDescriptor {
Expand Down
46 changes: 22 additions & 24 deletions pipelined/bevy_pbr2/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use wgpu::{

pub struct PbrShaders {
pipeline: RenderPipeline,
shader_module: ShaderModule,
view_layout: BindGroupLayout,
material_layout: BindGroupLayout,
mesh_layout: BindGroupLayout,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -360,7 +359,6 @@ impl FromWorld for PbrShaders {
};
PbrShaders {
pipeline,
shader_module,
view_layout,
material_layout,
mesh_layout,
Expand Down Expand Up @@ -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(..));
Expand Down
20 changes: 10 additions & 10 deletions pipelined/bevy_pbr2/src/render/pbr.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<f32>;
[[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<f32>;
[[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<f32>;
[[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<f32>;
[[group(2), binding(8)]]
[[group(1), binding(8)]]
var occlusion_sampler: sampler;

let PI: f32 = 3.141592653589793;
Expand Down

0 comments on commit dd32cd0

Please sign in to comment.