mirror of
https://github.com/bevyengine/bevy
synced 2025-01-07 18:58:58 +00:00
4f20faaa43
# Objective - Implements a more efficient, GPU-driven (https://github.com/bevyengine/bevy/issues/1342) rendering pipeline based on meshlets. - Meshes are split into small clusters of triangles called meshlets, each of which acts as a mini index buffer into the larger mesh data. Meshlets can be compressed, streamed, culled, and batched much more efficiently than monolithic meshes. ![image](https://github.com/bevyengine/bevy/assets/47158642/cb2aaad0-7a9a-4e14-93b0-15d4e895b26a) ![image](https://github.com/bevyengine/bevy/assets/47158642/7534035b-1eb7-4278-9b99-5322e4401715) # Misc * Future work: https://github.com/bevyengine/bevy/issues/11518 * Nanite reference: https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf Two pass occlusion culling explained very well: https://medium.com/@mil_kru/two-pass-occlusion-culling-4100edcad501 --------- Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com> Co-authored-by: vero <email@atlasdostal.com> Co-authored-by: François <mockersf@gmail.com> Co-authored-by: atlas dostal <rodol@rivalrebels.com>
88 lines
2.8 KiB
WebGPU Shading Language
88 lines
2.8 KiB
WebGPU Shading Language
#import bevy_pbr::{
|
|
meshlet_bindings::{
|
|
meshlet_thread_meshlet_ids,
|
|
meshlets,
|
|
meshlet_vertex_ids,
|
|
meshlet_vertex_data,
|
|
meshlet_thread_instance_ids,
|
|
meshlet_instance_uniforms,
|
|
meshlet_instance_material_ids,
|
|
draw_index_buffer,
|
|
view,
|
|
get_meshlet_index,
|
|
unpack_meshlet_vertex,
|
|
},
|
|
mesh_functions::mesh_position_local_to_world,
|
|
}
|
|
#import bevy_render::maths::affine3_to_square
|
|
|
|
/// Vertex/fragment shader for rasterizing meshlets into a visibility buffer.
|
|
|
|
struct VertexOutput {
|
|
@builtin(position) clip_position: vec4<f32>,
|
|
#ifdef MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT
|
|
@location(0) @interpolate(flat) visibility: u32,
|
|
@location(1) @interpolate(flat) material_depth: u32,
|
|
#endif
|
|
#ifdef DEPTH_CLAMP_ORTHO
|
|
@location(0) unclamped_clip_depth: f32,
|
|
#endif
|
|
}
|
|
|
|
#ifdef MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT
|
|
struct FragmentOutput {
|
|
@location(0) visibility: vec4<u32>,
|
|
@location(1) material_depth: vec4<u32>,
|
|
}
|
|
#endif
|
|
|
|
@vertex
|
|
fn vertex(@builtin(vertex_index) vertex_index: u32) -> VertexOutput {
|
|
let packed_ids = draw_index_buffer[vertex_index / 3u];
|
|
let cluster_id = packed_ids >> 8u;
|
|
let triangle_id = extractBits(packed_ids, 0u, 8u);
|
|
let index_id = (triangle_id * 3u) + (vertex_index % 3u);
|
|
let meshlet_id = meshlet_thread_meshlet_ids[cluster_id];
|
|
let meshlet = meshlets[meshlet_id];
|
|
let index = get_meshlet_index(meshlet.start_index_id + index_id);
|
|
let vertex_id = meshlet_vertex_ids[meshlet.start_vertex_id + index];
|
|
let vertex = unpack_meshlet_vertex(meshlet_vertex_data[vertex_id]);
|
|
let instance_id = meshlet_thread_instance_ids[cluster_id];
|
|
let instance_uniform = meshlet_instance_uniforms[instance_id];
|
|
|
|
let model = affine3_to_square(instance_uniform.model);
|
|
let world_position = mesh_position_local_to_world(model, vec4(vertex.position, 1.0));
|
|
var clip_position = view.view_proj * vec4(world_position.xyz, 1.0);
|
|
#ifdef DEPTH_CLAMP_ORTHO
|
|
let unclamped_clip_depth = clip_position.z;
|
|
clip_position.z = min(clip_position.z, 1.0);
|
|
#endif
|
|
|
|
return VertexOutput(
|
|
clip_position,
|
|
#ifdef MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT
|
|
packed_ids,
|
|
meshlet_instance_material_ids[instance_id],
|
|
#endif
|
|
#ifdef DEPTH_CLAMP_ORTHO
|
|
unclamped_clip_depth,
|
|
#endif
|
|
);
|
|
}
|
|
|
|
#ifdef MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT
|
|
@fragment
|
|
fn fragment(vertex_output: VertexOutput) -> FragmentOutput {
|
|
return FragmentOutput(
|
|
vec4(vertex_output.visibility, 0u, 0u, 0u),
|
|
vec4(vertex_output.material_depth, 0u, 0u, 0u),
|
|
);
|
|
}
|
|
#endif
|
|
|
|
#ifdef DEPTH_CLAMP_ORTHO
|
|
@fragment
|
|
fn fragment(vertex_output: VertexOutput) -> @builtin(frag_depth) f32 {
|
|
return vertex_output.unclamped_clip_depth;
|
|
}
|
|
#endif
|