Trait bevy::render::render_resource::AsBindGroup
source · pub trait AsBindGroup {
type Data: Send + Sync;
// Required methods
fn unprepared_bind_group(
&self,
layout: &BindGroupLayout,
render_device: &RenderDevice,
images: &RenderAssets<GpuImage>,
fallback_image: &FallbackImage
) -> Result<UnpreparedBindGroup<Self::Data>, AsBindGroupError>;
fn bind_group_layout_entries(
render_device: &RenderDevice
) -> Vec<BindGroupLayoutEntry>
where Self: Sized;
// Provided methods
fn label() -> Option<&'static str> { ... }
fn as_bind_group(
&self,
layout: &BindGroupLayout,
render_device: &RenderDevice,
images: &RenderAssets<GpuImage>,
fallback_image: &FallbackImage
) -> Result<PreparedBindGroup<Self::Data>, AsBindGroupError> { ... }
fn bind_group_layout(render_device: &RenderDevice) -> BindGroupLayout
where Self: Sized { ... }
}Expand description
Converts a value to a BindGroup with a given BindGroupLayout, which can then be used in Bevy shaders.
This trait can be derived (and generally should be). Read on for details and examples.
This is an opinionated trait that is intended to make it easy to generically
convert a type into a BindGroup. It provides access to specific render resources,
such as RenderAssets<GpuImage> and FallbackImage. If a type has a Handle<Image>,
these can be used to retrieve the corresponding Texture resource.
AsBindGroup::as_bind_group is intended to be called once, then the result cached somewhere. It is generally
ok to do “expensive” work here, such as creating a Buffer for a uniform.
If for some reason a BindGroup cannot be created yet (for example, the Texture
for an Image hasn’t loaded yet), just return AsBindGroupError::RetryNextUpdate, which signals that the caller
should retry again later.
§Deriving
This trait can be derived. Field attributes like uniform and texture are used to define which fields should be bindings,
what their binding type is, and what index they should be bound at:
#[derive(AsBindGroup)]
struct CoolMaterial {
#[uniform(0)]
color: LinearRgba,
#[texture(1)]
#[sampler(2)]
color_texture: Handle<Image>,
#[storage(3, read_only)]
values: Vec<f32>,
#[storage(4, read_only, buffer)]
buffer: Buffer,
#[storage_texture(5)]
storage_texture: Handle<Image>,
}In WGSL shaders, the binding would look like this:
@group(2) @binding(0) var<uniform> color: vec4<f32>;
@group(2) @binding(1) var color_texture: texture_2d<f32>;
@group(2) @binding(2) var color_sampler: sampler;
@group(2) @binding(3) var<storage> values: array<f32>;
@group(2) @binding(5) var storage_texture: texture_storage_2d<rgba8unorm, read_write>;
Note that the “group” index is determined by the usage context. It is not defined in AsBindGroup. For example, in Bevy material bind groups
are generally bound to group 2.
The following field-level attributes are supported:
-
uniform(BINDING_INDEX)- The field will be converted to a shader-compatible type using the
ShaderTypetrait, written to aBuffer, and bound as a uniform.ShaderTypeis implemented for most math types already, such asf32,Vec4, andLinearRgba. It can also be derived for custom structs.
- The field will be converted to a shader-compatible type using the
-
texture(BINDING_INDEX, arguments)- This field’s
Handle<Image>will be used to look up the matchingTextureGPU resource, which will be bound as a texture in shaders. The field will be assumed to implementInto<Option<Handle<Image>>>. In practice, most fields should be aHandle<Image>orOption<Handle<Image>>. If the value of anOption<Handle<Image>>isNone, theFallbackImageresource will be used instead. This attribute can be used in conjunction with asamplerbinding attribute (with a different binding index) if a binding of the sampler for theImageis also required.
- This field’s
| Arguments | Values | Default |
|---|---|---|
dimension = “…” | "1d", "2d", "2d_array", "3d", "cube", "cube_array" | "2d" |
sample_type = “…” | "float", "depth", "s_int" or "u_int" | "float" |
filterable = … | true, false | true |
multisampled = … | true, false | false |
visibility(...) | all, none, or a list-combination of vertex, fragment, compute | vertex, fragment |
storage_texture(BINDING_INDEX, arguments)- This field’s
Handle<Image>will be used to look up the matchingTextureGPU resource, which will be bound as a storage texture in shaders. The field will be assumed to implementInto<Option<Handle<Image>>>. In practice, most fields should be aHandle<Image>orOption<Handle<Image>>. If the value of anOption<Handle<Image>>isNone, theFallbackImageresource will be used instead.
- This field’s
| Arguments | Values | Default |
|---|---|---|
dimension = “…” | "1d", "2d", "2d_array", "3d", "cube", "cube_array" | "2d" |
image_format = … | any member of TextureFormat | Rgba8Unorm |
access = … | any member of StorageTextureAccess | ReadWrite |
visibility(...) | all, none, or a list-combination of vertex, fragment, compute | compute |
sampler(BINDING_INDEX, arguments)- This field’s
Handle<Image>will be used to look up the matchingSamplerGPU resource, which will be bound as a sampler in shaders. The field will be assumed to implementInto<Option<Handle<Image>>>. In practice, most fields should be aHandle<Image>orOption<Handle<Image>>. If the value of anOption<Handle<Image>>isNone, theFallbackImageresource will be used instead. This attribute can be used in conjunction with atexturebinding attribute (with a different binding index) if a binding of the texture for theImageis also required.
- This field’s
| Arguments | Values | Default |
|---|---|---|
sampler_type = “…” | "filtering", "non_filtering", "comparison". | "filtering" |
visibility(...) | all, none, or a list-combination of vertex, fragment, compute | vertex, fragment |
storage(BINDING_INDEX, arguments)- The field will be converted to a shader-compatible type using the
ShaderTypetrait, written to aBuffer, and bound as a storage buffer. - It supports and optional
read_onlyparameter. Defaults to false if not present.
- The field will be converted to a shader-compatible type using the
| Arguments | Values | Default |
|---|---|---|
visibility(...) | all, none, or a list-combination of vertex, fragment, compute | vertex, fragment |
read_only | if present then value is true, otherwise false | false |
Note that fields without field-level binding attributes will be ignored.
#[derive(AsBindGroup)]
struct CoolMaterial {
#[uniform(0)]
color: LinearRgba,
this_field_is_ignored: String,
}As mentioned above, Option<Handle<Image>> is also supported:
#[derive(AsBindGroup)]
struct CoolMaterial {
#[uniform(0)]
color: LinearRgba,
#[texture(1)]
#[sampler(2)]
color_texture: Option<Handle<Image>>,
}This is useful if you want a texture to be optional. When the value is None, the FallbackImage will be used for the binding instead, which defaults
to “pure white”.
Field uniforms with the same index will be combined into a single binding:
#[derive(AsBindGroup)]
struct CoolMaterial {
#[uniform(0)]
color: LinearRgba,
#[uniform(0)]
roughness: f32,
}In WGSL shaders, the binding would look like this:
struct CoolMaterial {
color: vec4<f32>,
roughness: f32,
};
@group(2) @binding(0) var<uniform> material: CoolMaterial;
Some less common scenarios will require “struct-level” attributes. These are the currently supported struct-level attributes:
uniform(BINDING_INDEX, ConvertedShaderType)- This also creates a
BufferusingShaderTypeand binds it as a uniform, much much like the field-leveluniformattribute. The difference is that the entireAsBindGroupvalue is converted toConvertedShaderType, which must implementShaderType, instead of a specific field implementingShaderType. This is useful if more complicated conversion logic is required. The conversion is done using theAsBindGroupShaderType<ConvertedShaderType>trait, which is automatically implemented if&SelfimplementsInto<ConvertedShaderType>. Only useAsBindGroupShaderTypeif access to resources likeRenderAssets<GpuImage>is required.
- This also creates a
bind_group_data(DataType)- The
AsBindGrouptype will be converted to someDataTypeusingInto<DataType>and stored asAsBindGroup::Dataas part of theAsBindGroup::as_bind_groupcall. This is useful if data needs to be stored alongside the generated bind group, such as a unique identifier for a material’s bind group. The most common use case for this attribute is “shader pipeline specialization”. SeeSpecializedRenderPipeline.
- The
The previous CoolMaterial example illustrating “combining multiple field-level uniform attributes with the same binding index” can
also be equivalently represented with a single struct-level uniform attribute:
#[derive(AsBindGroup)]
#[uniform(0, CoolMaterialUniform)]
struct CoolMaterial {
color: LinearRgba,
roughness: f32,
}
#[derive(ShaderType)]
struct CoolMaterialUniform {
color: LinearRgba,
roughness: f32,
}
impl From<&CoolMaterial> for CoolMaterialUniform {
fn from(material: &CoolMaterial) -> CoolMaterialUniform {
CoolMaterialUniform {
color: material.color,
roughness: material.roughness,
}
}
}Setting bind_group_data looks like this:
#[derive(AsBindGroup)]
#[bind_group_data(CoolMaterialKey)]
struct CoolMaterial {
#[uniform(0)]
color: LinearRgba,
is_shaded: bool,
}
#[derive(Copy, Clone, Hash, Eq, PartialEq)]
struct CoolMaterialKey {
is_shaded: bool,
}
impl From<&CoolMaterial> for CoolMaterialKey {
fn from(material: &CoolMaterial) -> CoolMaterialKey {
CoolMaterialKey {
is_shaded: material.is_shaded,
}
}
}Required Associated Types§
Required Methods§
sourcefn unprepared_bind_group(
&self,
layout: &BindGroupLayout,
render_device: &RenderDevice,
images: &RenderAssets<GpuImage>,
fallback_image: &FallbackImage
) -> Result<UnpreparedBindGroup<Self::Data>, AsBindGroupError>
fn unprepared_bind_group( &self, layout: &BindGroupLayout, render_device: &RenderDevice, images: &RenderAssets<GpuImage>, fallback_image: &FallbackImage ) -> Result<UnpreparedBindGroup<Self::Data>, AsBindGroupError>
Returns a vec of (binding index, OwnedBindingResource).
In cases where OwnedBindingResource is not available (as for bindless texture arrays currently),
an implementor may define as_bind_group directly. This may prevent certain features
from working correctly.
sourcefn bind_group_layout_entries(
render_device: &RenderDevice
) -> Vec<BindGroupLayoutEntry>where
Self: Sized,
fn bind_group_layout_entries(
render_device: &RenderDevice
) -> Vec<BindGroupLayoutEntry>where
Self: Sized,
Returns a vec of bind group layout entries
Provided Methods§
sourcefn as_bind_group(
&self,
layout: &BindGroupLayout,
render_device: &RenderDevice,
images: &RenderAssets<GpuImage>,
fallback_image: &FallbackImage
) -> Result<PreparedBindGroup<Self::Data>, AsBindGroupError>
fn as_bind_group( &self, layout: &BindGroupLayout, render_device: &RenderDevice, images: &RenderAssets<GpuImage>, fallback_image: &FallbackImage ) -> Result<PreparedBindGroup<Self::Data>, AsBindGroupError>
Creates a bind group for self matching the layout defined in AsBindGroup::bind_group_layout.
sourcefn bind_group_layout(render_device: &RenderDevice) -> BindGroupLayoutwhere
Self: Sized,
fn bind_group_layout(render_device: &RenderDevice) -> BindGroupLayoutwhere
Self: Sized,
Creates the bind group layout matching all bind groups returned by AsBindGroup::as_bind_group