james-j-obrien / bevy_vector_shapes

A library for rendering vector shapes using the Bevy game engine
Other
324 stars 22 forks source link

RenderLayers doesn't seem to work with 3D Camera #34

Open bkwhite opened 8 months ago

bkwhite commented 8 months ago

I have tried using global config

.add_plugins(ShapePlugin {
            base_config: ShapeConfig {
                alignment: Alignment::Billboard,
                render_layers: Some(RenderLayers::layer(1)),
                ..ShapeConfig::default_3d()
            },
            ..default()
        })

and a per shape config

commands.spawn(
                ShapeBundle::rect(
                    &ShapeConfig {
                        color: Color::MIDNIGHT_BLUE,
                        corner_radii: Vec4::splat(0.3),
                        transform: hit_transfrom,
                        render_layers: Some(RenderLayers::layer(1)),
                        ..ShapeConfig::default_3d()
                    },
                    Vec2::splat(2.0),
                )
                .insert_3d(),
            );

with no success, the shape seems to be rendering on layer 0 regardless of telling it to render elsewhere.

bkwhite commented 8 months ago

interestingly, it seems to work by transplanting the render_layer example into my code.

maybe this is a problem with the commands interface?

bkwhite commented 8 months ago

Changing this line to true seems to make things work

james-j-obrien commented 8 months ago

If you use commands.spawn_shape or commands.rect on a ShapeCommands instead of commands.spawn it will automatically attach the bevy RenderLayers component which should be respected when rendering. I would prefer to re-use that component then hide it away inside ShapeMaterial so it is better interoperable with other systems.

One alternative would be to make RenderLayers part of ShapeBundle, the only hitch is that most shapes won't actually need RenderLayers so it's wasted memory for most users. If bevy supported optional components in bundles this would be a perfect use case.

It's unfortunate that passing the render layers in the config like you show in your second example is misleading as the constructed ShapeBundle doesn't actually extract the value from it (similar to how rect doesn't use radius) since it doesn't store it.

bkwhite commented 8 months ago

I don't think I was aware of ShapeCommands as much as i am now, this does sound like the right move.

I def through me off a bit, but the alternative you have suggested makes sense to me!

Thank you for the reply, this crate is very useful!

bkwhite commented 8 months ago

Hmm trying to use shape_commands.spawn_shape doesn't seem to attach the render layers? (I switch my cargo back to 0.6.0. (I might still be doing something weird, please lmk)

Here is a minimal example,

fn handle_hits(mut shape_commands: ShapeCommands) {
    let polygon_shape_bundle = ShapeBundle::ngon(
        &ShapeConfig {
            alignment: Alignment::Billboard,
            color: Color::RED,
            corner_radii: Vec4::splat(0.3),
            render_layers: Some(RenderLayers::layer(1)),
            ..ShapeConfig::default_3d()
        },
        6.0,
        0.5,
    )
    .insert_3d();

    shape_commands.spawn_shape(polygon_shape_bundle);
}
bkwhite commented 8 months ago

Doing it this way did work

shape_commands.set_config(ShapeConfig {
    alignment: Alignment::Billboard,
    color: Color::RED,
    corner_radii: Vec4::splat(0.3),
    render_layers: Some(RenderLayers::layer(1)),
    transform: hit_transfrom,
    ..ShapeConfig::default_3d()
});

shape_commands.ngon(6.0, 0.5);
james-j-obrien commented 7 months ago

Sorry didn't see this after it was re-opened, spawn_shape uses the config inside the ShapeCommands not the one you pass to create the bundle. Unfortunately there is no way to conditionally include the RenderLayers component in ShapeBundle so the bundle itself can't contain the layers, nor is there a way to store the entire config since the bundle components only contain what they need to render that shape.

Your alternative is the intended way to use the API, perhaps I can take spawn_shape private and just expect users to use ShapeEntityCommands to add any additional components.

james-j-obrien commented 7 months ago

I've added documentation noting this behavior but until the point that bevy supports bundles with optional components I won't be able to change this significantly.

bkwhite commented 7 months ago

I've added documentation noting this behavior but until the point that bevy supports bundles with optional components I won't be able to change this significantly.

makes sense! I appreciate your efforts!