#Trouble following the custom vertex attribute example

35 messages · Page 1 of 1 (latest)

crude orchid
#

I am following the custom vertex attribute example to get a simple vertex shader going but i get some shader errors that i dont really understand.
This is the example:https://bevyengine.org/examples/Shaders/custom-vertex-attribute/ and a link to the shader https://github.com/bevyengine/bevy/blob/main/assets/shaders/custom_vertex_attribute.wgsl.

When i run my program i get this error:

2023-11-23T23:33:37.655063Z ERROR log: Handling wgpu errors as fatal by default
thread 'Compute Task Pool (4)' panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
      note: label = `transparent_mesh2d_pipeline`
    Error matching ShaderStages(VERTEX) shader requirements against the pipeline
    Shader global ResourceBinding { group: 2, binding: 0 } is not available in the layout pipeline layout
    Buffer structure size 144, added to one element of an unbound array, if it's the last field, ended up greater than the given `min_binding_size`

', C:\Users\Leonard\.cargo\registry\src\index.crates.io-6f17d22bba15001f\wgpu-0.17.2\src\backend\direct.rs:3056:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_render::render_resource::pipeline_cache::PipelineCache::process_pipeline_queue_system`!
thread 'Compute Task Pool (4)' panicked at 'called `Result::unwrap()` on an `Err` value: RecvError', C:\Users\Leonard\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_render-0.12.0\src\pipelined_rendering.rs:145:45

From what i understand, something requires a resource on group 2 binding 0 but its not there. However from the example i dont see where anything like that would be defined. The mesh position and the custom attribute are defined at location 0 and 1 but nothing on location 2.

I dont really understand how to debug this.

#

For what its worth here is a shortened version of my shader. I dont actually need a custom attribute but i would like to have a custom vertex shader.

#import bevy_pbr::mesh_functions::{get_model_matrix, mesh_position_local_to_clip}

struct CustomMaterial {
    ...
};

@group(1) @binding(0)
var<uniform> material: CustomMaterial;
@group(1) @binding(1)
var base_color_texture: texture_2d<f32>;
@group(1) @binding(2)
var base_color_sampler: sampler;

struct VertexInput{
    @builtin(instance_index) instance_index: u32,
    @location(0) position: vec3<f32>,
    @location(1) uv: vec2<f32>,
}

struct VertexOutput{
    @builtin(position) clip_position: vec4<f32>,
    @location(0) uv: vec2<f32>,
}

@vertex
fn vertex(vertex: VertexInput) -> VertexOutput{
    var out: VertexOutput;
    out.clip_position = mesh_position_local_to_clip(
        get_model_matrix(vertex.instance_index),
        vec4<f32>(vertex.position, 1.0),
    );
    out.clip_position = vec4<f32>(vertex.position, 1.0);
    out.uv = vertex.uv;
    return out;
}

I do belive the problem is somewhere in the vertex shader at the mesh_position_local_to_clip method. If i comment it out the error goes away (as does the output obviously).

#

And my material looks like this:

impl Material2d for CellMaterial {
    fn fragment_shader() -> bevy::render::render_resource::ShaderRef {
        SHADER_HANDLE.into()
    }

    fn vertex_shader() -> bevy::render::render_resource::ShaderRef {
        SHADER_HANDLE.into()
    }

    fn specialize(
        descriptor: &mut bevy::render::render_resource::RenderPipelineDescriptor,
        layout: &bevy::render::mesh::MeshVertexBufferLayout,
        _key: bevy::sprite::Material2dKey<Self>,
    ) -> Result<(), bevy::render::render_resource::SpecializedMeshPipelineError> {
        let vertex_layout = layout.get_layout(&[
            Mesh::ATTRIBUTE_POSITION.at_shader_location(0),
            Mesh::ATTRIBUTE_UV_0.at_shader_location(1),
        ])?;
        descriptor.vertex.buffers = vec![vertex_layout];
        Ok(())
    }
}
pearl drum
#

it looks like ur rust definition of the custom material is different to how you've its defined in the custom shader

crude orchid
# pearl drum have u altered the custom material? ur issue is that somewhere in ur shader (i t...

have u altered the custom material
what does that mean?
My material looks like this:

#[derive(AsBindGroup, Asset, TypeUuid, TypePath, Debug, Clone, Default)]
#[uuid = "02ff810f-b8de-4d62-8b09-7da5072fae14"]
#[uniform(0, MaterialUniform)]
pub struct CellMaterial {
    pub color: Color,
    pub gradient: Gradient,
    pub size: Vec2,
    pub rounding: Vec4,
    #[texture(1)]
    #[sampler(2)]
    pub texture: Option<Handle<Image>>,
}

with:


#[derive(Clone, Default, ShaderType)]
struct MaterialUniform {
    kind: i32,
    color: Vec4,
    color_2: Vec4,
    pos: Vec2,
    spread: f32,
    param_1: f32,
    size: Vec2,
    rounding: Vec4,
}

impl AsBindGroupShaderType<MaterialUniform> for CellMaterial {
    fn as_bind_group_shader_type(&self, _images: &RenderAssets<Image>) -> MaterialUniform {
        let (kind, color_2, position, spread, param_1) = match &self.gradient {
            Gradient::None => (0, Color::default(), Vec2::default(), 0.0, 0.0),
            Gradient::Linear(g) => (1, g.color, g.position, g.spread, g.angle),
            Gradient::Radial(g) => (2, g.color, g.position, g.spread, g.distance),
            Gradient::Conical(g) => (3, g.color, g.position, 0.0, g.angle),
        };
        MaterialUniform {
            kind,
            color: self.color.as_linear_rgba_f32().into(),
            color_2: color_2.as_linear_rgba_f32().into(),
            pos: position.clone(),
            spread,
            param_1,
            size: self.size,
            rounding: self.rounding,
        }
    }
}
#

didnt know how much to include at first.

pearl drum
#

implementing AsBindGroupShaderType manually might not be necessary btw, u might be able to derive it with bevy's macros (give me a second to find examples in my code haha)

crude orchid
#

oh of course. I skiped that for brevity.
here is the struct in the shader:

struct CustomMaterial {
    kind: i32,
    color: vec4<f32>,
    color_2: vec4<f32>,
    pos: vec2<f32>,
    spread: f32,
    param_1: f32,
    size: vec2<f32>,
    rounding: vec4<f32>,
};

Which should match the MaterialUniform defined above.

crude orchid
pearl drum
#
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone, Default)]
pub struct CustomMaterial {
    #[uniform(0)]
    color: Color,
    #[uniform(0)]
    time: f32,
    #[uniform(0)]
    has_texture: f32,
    #[texture(1)]
    #[sampler(2)]
    color_texture: Option<Handle<Image>>,
    #[storage(3)]
    lights: Arc<Vec<CubeLight>>,
}

im deriving AsBindGroup and then using uniform(0) means that the custom material struct will be available as a uniform variable at binding 0

#

Color maps to vec3 or 4 in the shader iirc

pearl drum
#

in which case ur trying to access smth that might not actually exist for ur code

crude orchid
pearl drum
#

i had similar issues before but i copy pasted the functions i was importing and altered them slightly so the variables it used were defined correctly in my own shader

#

idk how to use specific groups either 😅

crude orchid
#

But what the hell is MESH_BINDGROUP_1 and where is it defined / changed / set.

pearl drum
#

those flags(?) are set in the pbr structs in bevy, i think in the specialize method. i did try to check it out before but i got lost in the process haha

#

maybe u can put #define MESH_BINDGROUP_1; in ur shader to manually set the flag

crude orchid
#

em no i can.

Caused by:
    In Device::create_render_pipeline
      note: label = `transparent_mesh2d_pipeline`
    Error matching ShaderStages(VERTEX) shader requirements against the pipeline
    Shader global ResourceBinding { group: 1, binding: 0 } is not available in the layout pipeline layout
    Storage class Uniform doesn't match the shader Storage { access: StorageAccess(LOAD) }

Different error though

#

Hold up; is this maybe a problem with using 2d materials? The example uses normal materials. Perhaps there is a difference there?

pearl drum
#

might be, but im not sure

#

whatevers at group 1 binding 0 is a storage variable, not uniform 🤔 so it could be expecting some entirely different struct etc.

crude orchid
#

I dont think setting the define manually is correct. That just doesnt seam like a good idea.

pearl drum
#

yh probably not 😬 🤦‍♂️

pearl drum
crude orchid
#

Yeah thanks. Ill try with the normal materials tomorrow.

crude orchid
#

There is also this...

#

when i compile the program i get no errors but rust-analyzer shows this error.

crude orchid
#

I found the problem.
I was using 3d mesh function for my 2d material. Instead i have to use the correct 2d functions.
I changed my shader to this:

#import bevy_sprite::mesh2d_functions as mesh_functions;

@vertex
fn vertex(vertex: VertexInput) -> VertexOutput{
    var out: VertexOutput;

    var model = mesh_functions::get_model_matrix(vertex.instance_index);
    let world_position = mesh_functions::mesh2d_position_local_to_world(
        model,
        vec4<f32>(vertex.position, 1.0)
    );
    out.clip_position = mesh_functions::mesh2d_position_world_to_clip(world_position);

    out.uv = vertex.uv;
    return out;
}
#

And this works just fine.