#Custom Vertex Shader with Bevy PBR

47 messages · Page 1 of 1 (latest)

steel sage
#

I'm making a voxel engine
here's my shader:

#import bevy_pbr::{
    mesh_functions,
    view_transformations::position_world_to_clip
}

struct VertexInput {
    @builtin(instance_index) instance_index: u32,
    @location(0) packed_data: u32,
};

struct VertexOutput {
    @builtin(position) pos: vec4<f32>,
};

struct UnpackedData {
    pos: vec3<f32>,
    face: u32,
};

fn unpack(packed: u32) -> UnpackedData {
    let x = f32((packed >> 0) & 0xF);
    let z = f32((packed >> 4) & 0xF);
    let y = f32((packed >> 8) & 0x1F);
    let f = (packed >> 13) & 0x7; // face direction
    return UnpackedData(vec3(x, y, z), f);
}

@vertex
fn vs_main(in: VertexInput) -> VertexOutput {
    var out: VertexOutput;
    let data = unpack(in.packed_data);

    var world_from_local = mesh_functions::get_world_from_local(in.instance_index);
    let world_position = mesh_functions::mesh_position_local_to_world(world_from_local, vec4(data.pos, 1.0));
    out.pos = position_world_to_clip(world_position.xyz);

    return out;
}

@fragment
fn fs_main() -> @location(0) vec4<f32> {
    return vec4<f32>(0.486, 1.0, 0.564, 1.0);
}

Currently I'm getting this validation error:
In Device::create_render_pipeline, label = 'opaque_mesh_pipeline'
Error matching ShaderStages(VERTEX) shader requirements against the pipeline
Location[0] Uint32 interpolated as Some(Flat) with sampling None is not provided by the previous stage outputs
Input type is not compatible with the provided Float32x3

If I return the same data as the default vertex shader, could I use bevy's PBR fragment shader+?A
Also how could I later implement shadowmaps?

keen juniper
#

you have a return on the vertex stage, but no arguments on the fragment stage

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
    return vec4<f32>(0.486, 1.0, 0.564, 1.0);
}
steel sage
#

yea i removed it

#

the error rdidnt change

keen juniper
#

hmm

#

it is saying that the @location(0) packed_data: u32 is not being passed to the shader, i know that there is extra work to make a custom attribute be sent to the shader

steel sage
#

ok im very stupid

#

i had 2 systems and i registered the older one that used the default material

keen juniper
steel sage
#

Where is the label even displayed?

keen juniper
#
In Device::create_render_pipeline, label = 'opaque_mesh_pipeline'
steel sage
#

ok thanks

#

in some example i saw that there was an import for a bevy vertex output struct

keen juniper
#

there is, but it assumes you are using just the "default" attributes

steel sage
#

wdym, the vertex attributes arent connected to the output of the vertex shader

keen juniper
#

there are 3 structs that you can import Vertex, VertexOutput and FragmentOutput

#

most of the members of Vertex and VertexOutput are behind shader definitions that are set automatically if you are using the "default" attributes, if you want to use them with you custom packed data material, you would need to pass the shader definitions yourself

#

if you want to have shadows, you need to have a prepass vertex stage

steel sage
#

what is a shader definition

keen juniper
#

do you see all those #ifdef on the forward_io.wgsl? those are shader definitions, it allows to have multiple permutations of a shader on the same file

steel sage
#

thats not a problem

#

i can calcualte that data on the shader based on the packed data

keen juniper
#

it is equivalent to doing #[cfg(something)] in rust code, the code after it will not exist in the final binary if something is not true

#

e.g.,

#[cfg(feature = "VERTEX_UVS_A")]
@location(2) uv: vec2<f32>,
steel sage
#

back to the previous topic

#

im still getting the same error

keen juniper
#

how is the specialize of your material?

steel sage
#
#[derive(Asset, TypePath, bevy::render::render_resource::AsBindGroup, Debug, Clone)]
pub struct VoxelMaterial {}

impl Material for VoxelMaterial {
    fn fragment_shader() -> bevy::shader::ShaderRef {
        "shaders/voxel.wgsl".into()
    }
    fn vertex_shader() -> bevy::shader::ShaderRef {
        "shaders/voxel.wgsl".into()
    }
}
steel sage
#

okay ill trythat thanks

keen juniper
#

on the specialize you will also need to change the entry_point to be vs_main and fg_main, the defaults are vertex and fragment

steel sage
#

wow thank you man

#

i failed horribyl

keen juniper
#

descriptor.vertex is not an Option so the if let is unnecessary

#

but other than that it is the same

steel sage
#

you set shader deifnitions from here?

steel sage
keen juniper
#

beats me

steel sage
#

ok so i guess ill go fight with the mesh generation code