mirror of
https://github.com/bevyengine/bevy
synced 2024-12-29 22:43:14 +00:00
a4640046fc
Adds a new `Handle<Storage>` asset type that can be used as a render asset, particularly for use with `AsBindGroup`. Closes: #13658 # Objective Allow users to create storage buffers in the main world without having to access the `RenderDevice`. While this resource is technically available, it's bad form to use in the main world and requires mixing rendering details with main world code. Additionally, this makes storage buffers easier to use with `AsBindGroup`, particularly in the following scenarios: - Sharing the same buffers between a compute stage and material shader. We already have examples of this for storage textures (see game of life example) and these changes allow a similar pattern to be used with storage buffers. - Preventing repeated gpu upload (see the previous easier to use `Vec` `AsBindGroup` option). - Allow initializing custom materials using `Default`. Previously, the lack of a `Default` implement for the raw `wgpu::Buffer` type made implementing a `AsBindGroup + Default` bound difficult in the presence of buffers. ## Solution Adds a new `Handle<Storage>` asset type that is prepared into a `GpuStorageBuffer` render asset. This asset can either be initialized with a `Vec<u8>` of properly aligned data or with a size hint. Users can modify the underlying `wgpu::BufferDescriptor` to provide additional usage flags. ## Migration Guide The `AsBindGroup` `storage` attribute has been modified to reference the new `Handle<Storage>` asset instead. Usages of Vec` should be converted into assets instead. --------- Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
38 lines
No EOL
1.1 KiB
WebGPU Shading Language
38 lines
No EOL
1.1 KiB
WebGPU Shading Language
#import bevy_pbr::{
|
|
mesh_functions,
|
|
view_transformations::position_world_to_clip
|
|
}
|
|
|
|
@group(2) @binding(0) var<storage, read> colors: array<vec4<f32>, 5>;
|
|
|
|
struct Vertex {
|
|
@builtin(instance_index) instance_index: u32,
|
|
@location(0) position: vec3<f32>,
|
|
};
|
|
|
|
struct VertexOutput {
|
|
@builtin(position) clip_position: vec4<f32>,
|
|
@location(0) world_position: vec4<f32>,
|
|
@location(1) color: vec4<f32>,
|
|
};
|
|
|
|
@vertex
|
|
fn vertex(vertex: Vertex) -> VertexOutput {
|
|
var out: VertexOutput;
|
|
var world_from_local = mesh_functions::get_world_from_local(vertex.instance_index);
|
|
out.world_position = mesh_functions::mesh_position_local_to_world(world_from_local, vec4(vertex.position, 1.0));
|
|
out.clip_position = position_world_to_clip(out.world_position.xyz);
|
|
|
|
// We have 5 colors in the storage buffer, but potentially many instances of the mesh, so
|
|
// we use the instance index to select a color from the storage buffer.
|
|
out.color = colors[vertex.instance_index % 5];
|
|
|
|
return out;
|
|
}
|
|
|
|
@fragment
|
|
fn fragment(
|
|
mesh: VertexOutput,
|
|
) -> @location(0) vec4<f32> {
|
|
return mesh.color;
|
|
} |