mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
Pipelined separate shadow vertex shader (#2727)
# 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
This commit is contained in:
parent
f4aa3284a8
commit
dd32cd029d
4 changed files with 68 additions and 35 deletions
30
pipelined/bevy_pbr2/src/render/depth.wgsl
Normal file
30
pipelined/bevy_pbr2/src/render/depth.wgsl
Normal file
|
@ -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;
|
||||
}
|
|
@ -14,6 +14,7 @@ use bevy_render2::{
|
|||
render_phase::{Draw, DrawFunctions, RenderPhase, TrackedRenderPass},
|
||||
render_resource::*,
|
||||
renderer::{RenderContext, RenderDevice},
|
||||
shader::Shader,
|
||||
texture::*,
|
||||
view::{ExtractedView, ViewUniformOffset},
|
||||
};
|
||||
|
@ -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,
|
||||
|
@ -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: &[
|
||||
|
@ -157,7 +161,7 @@ impl FromWorld for ShadowShaders {
|
|||
},
|
||||
],
|
||||
}],
|
||||
module: &pbr_shaders.shader_module,
|
||||
module: &shader_module,
|
||||
entry_point: "vertex",
|
||||
},
|
||||
fragment: None,
|
||||
|
@ -191,6 +195,7 @@ impl FromWorld for ShadowShaders {
|
|||
});
|
||||
|
||||
ShadowShaders {
|
||||
shader_module,
|
||||
pipeline,
|
||||
view_layout,
|
||||
point_light_sampler: render_device.create_sampler(&SamplerDescriptor {
|
||||
|
|
|
@ -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(..));
|
||||
|
|
|
@ -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<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;
|
||||
|
|
Loading…
Add table
Reference in a new issue