Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lines are always behind sprites in a 2d scene #20

Open
thisjaiden opened this issue Jun 1, 2022 · 21 comments
Open

Lines are always behind sprites in a 2d scene #20

thisjaiden opened this issue Jun 1, 2022 · 21 comments

Comments

@thisjaiden
Copy link
Contributor

Given a 2d orthographic camera and some SpriteBundles, debug lines will never appear in front of the sprites no matter what Z value is used for either. I'm not sure if this is intentional but it also happens when with_depth_test is enabled.

bevy v0.7.0
bevy_debug_lines v0.7.1
rustc v1.59.0

@Toqozz
Copy link
Owner

Toqozz commented Jun 1, 2022

Hmmm... I wonder if we should be setting the fragment depth in the 2d shader like we do in the 3d one. Will check on this when I get the time.

@thisjaiden
Copy link
Contributor Author

It looks like bevyengine/bevy#4011 was fixed in bevy v0.7.0, so it may be possible to join the 2d and 3d shaders at the same time. I'll look into this, but I don't have much experience with shaders.

@Indeximal
Copy link

I've run into the same issue. Would super appreciate it if this got fixed.

@Toqozz
Copy link
Owner

Toqozz commented Jun 5, 2022

I'm running the following example:

use bevy::prelude::*;

use bevy_prototype_debug_lines::{DebugLines, DebugLinesPlugin};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(DebugLinesPlugin::default())
        .add_startup_system(setup)
        .add_system(demo)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    let mut camera = OrthographicCameraBundle::new_2d();
    camera.transform = Transform::from_translation(Vec3::new(0.0, 0.0, 5.0));

    commands.spawn_bundle(camera);
    commands.spawn_bundle(SpriteBundle {
        texture: asset_server.load("icon.png"),
        ..default()
    });
}

fn demo(mut lines: ResMut<DebugLines>) {
    lines.line_colored(
        Vec3::new(-400.0, 0.0, -1.0),
        Vec3::new(400.0, 0.0, -1.0),
        0.9,
        Color::GREEN,
    );
}

And the line draws on top of the sprite -- am I missing something?

I'll think about making with_depth_test do something for 2d, but as a workaround you can just make the z position -999 or something like that.
EDIT: actually, it looks like -1 z just draws on top, but -2 etc doesn't. Dunno what's happening there.

Toqozz added a commit that referenced this issue Jun 5, 2022
@Toqozz
Copy link
Owner

Toqozz commented Jun 5, 2022

Ok I pushed a change to master that should make lines always draw on top of sprites, if my understanding is correct.

Let me know if it doesn't work properly.

Will push a new version out shortly if there are no issues.

@thisjaiden
Copy link
Contributor Author

thisjaiden commented Jun 5, 2022

Okay- this is bizarre.
I was always using positive Z coordinates for my lines, which may have caused the original problems.

Using master, lines now draw on top of sprites if the line's Z coordinate is in front of the sprite's Z coordinate. Somehow "disabling" depth fixed it.

Negative Z values make the disappear. (Outside of orthographic camera's default view?)

There's a new issue that lines always draw behind Text2dBundles, but that's a separate issue and may be related to how bevy separates UI from the scene. I consider this fixed, if in a strange way.

Side note: I am not near my main workstation so I am running these tests on an entirely different platform. I doubt there's any platform semantics but I will check tomorrow.

Thank you for the quick fix!

@Indeximal
Copy link

Indeximal commented Jun 5, 2022

Sadly I don't see the same result for sprites not within the (0, 1) z-interval. Running this example, where the line is still occluded by the sprite:

use bevy::prelude::*;
use bevy_prototype_debug_lines::{DebugLines, DebugLinesPlugin};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(DebugLinesPlugin::default())
        .add_startup_system(setup)
        .add_system(demo)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    let camera = OrthographicCameraBundle::new_2d();
    commands.spawn_bundle(camera);

    commands
        .spawn_bundle(SpriteBundle {
            texture: asset_server.load("icon.png"),
            transform: Transform::from_translation(Vec3::new(0.0, 0.0, 100.0)),
            ..default()
        })
        .insert(Name::new("Sprite"));
}

fn demo(mut lines: ResMut<DebugLines>) {
    lines.line_colored(
        Vec3::new(-400.0, 0.0, 999.0),
        Vec3::new(400.0, 0.0, 999.0),
        0.9,
        Color::GREEN,
    );
}

From the testing I've done it seems that lines are rendered "correctly" at 999, because if I change the near clip plane the line disappears. However, they are still rendered behind the sprite, if the sprite has z > 1.0. Anything from 0.0 to 1.0 works as expected.
Thanks for your quick reaction :)

EDIT: further testing indicates that in the (0, 1) z-interval (of the sprite) the lines is always drawn on top. Thus I can't replicate @thisjaiden 's observation.

@Toqozz
Copy link
Owner

Toqozz commented Jun 5, 2022

So bizarre. I tried a bunch of different coordinates to see if it changed after the latest master change, but it seemed to always be on top.

I'll have to try look into this further and perhaps ask other bevy people more about the 2d pipeline.

@thisjaiden
Copy link
Contributor Author

I'll do some more testing and provide results with examples later today.

@thisjaiden
Copy link
Contributor Author

Upon further inspection it's probably something in my environment. I modified the example to draw various lines at different depths (see my fork) and got the expected results: all lines within clipping bounds render on top of the sprite and those outside the camera's view do not render. This issue can be closed whenever you see fit! Thank you again for the quick work.

@lordbenedikt
Copy link

I have the same issue. I don't know why, but each time I run my code I get a different ordering. I had the same issue with bevy_prototype_lyon.

@Indeximal
Copy link

For the time being, setting all z translations to be between 0 and 1, but not changing the camera (still 999 near field and 0 far field) has worked perfectly for me.
Since z values are all floats anyway, I just devided all of them by 1000.
@lordbenedikt Different orderings might be due to equivalent z translations, so maybe check your ordering?

@lordbenedikt
Copy link

lordbenedikt commented Jun 13, 2022

That works for you?
@Indeximal I used your code but changed z tranlations to be between 0 and 1.

use bevy::prelude::*;
use bevy_prototype_debug_lines::{DebugLines, DebugLinesPlugin};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(DebugLinesPlugin::default())
        .add_startup_system(setup)
        .add_system(demo)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    let camera = OrthographicCameraBundle::new_2d();
    commands.spawn_bundle(camera);

    commands
        .spawn_bundle(SpriteBundle {
            texture: asset_server.load("head.png"),
            transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.3)),
            ..default()
        })
        .insert(Name::new("Sprite"));
}

fn demo(mut lines: ResMut<DebugLines>) {
    lines.line_colored(
        Vec3::new(-400.0, 0.0, 0.5),
        Vec3::new(400.0, 0.0, 0.5),
        0.9,
        Color::GREEN,
    );
}

No matter what I change the z to, now the line is always in the back. Am I doing something wrong?

@thisjaiden
Copy link
Contributor Author

+1, experiencing ordering randomness/issues too after further inspection. Seems to order all lines either behind or in front, but I'm not sure what's deciding when they're ordered last or first in rendering.

@Toqozz
Copy link
Owner

Toqozz commented Jun 15, 2022

I still can't reproduce, but would you guys mind trying the latest master?

@thisjaiden
Copy link
Contributor Author

afaik master fixes the issue for me, though the issue is hard to reproduce. If this works for @lordbenedikt too I have no further issues here

@zaycev
Copy link

zaycev commented Jun 16, 2022

I've go the same problem. Sprites are drawn on top of lines no matter what z-coordinate I set. Here is a render doc capture if that helps:

https://www.dropbox.com/s/bqqlty9rp8kjmnn/capture.rdc?dl=0

example-2

example

@zaycev
Copy link

zaycev commented Jun 16, 2022

Seems like it's fixed on main now.

Toqozz added a commit that referenced this issue Jun 16, 2022
@lordbenedikt
Copy link

@Toqozz Sorry for the late reply.

Sadly it isn't working. As before specifying the z value doesn't let me change the ordering of the sprites. It still seems as if the z value is being ignored. Here is my code:

use bevy::prelude::*;
use bevy_prototype_debug_lines::{DebugLines, DebugLinesPlugin};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(DebugLinesPlugin::with_depth_test(true))
        .add_startup_system(setup)
        .add_system(demo)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    let camera = OrthographicCameraBundle::new_2d();
    commands.spawn_bundle(camera);

    commands
        .spawn_bundle(SpriteBundle {
            texture: asset_server.load("head.png"),
            transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.9)),
            ..default()
        });
}

fn demo(mut lines: ResMut<DebugLines>) {
    lines.line_colored(
        Vec3::new(-400.0, 0.0, 0.1),
        Vec3::new(400.0, 0.0, 0.1),
        0.9,
        Color::GREEN,
    );
}

The green line show's up in front of the sprite. I also tried the values 90 for sprite and 20 for line, or 90 for sprite and 200 for line, none of which had any effect on the outcome. A green line is drawn over my head.png. I specified 'bevy_prototype_debug_lines = "= 0.7.2"' in my cargo.toml. Interestingly after updating from 0.7.1 to 0.7.2 the sprite is now always behind the line as opposed to in front of it. This is definitely preferable to having the lines always in the back, but of course it's best to have control.

@thisjaiden
Copy link
Contributor Author

right, I think this is the intended behavior, I don't believe depth is supported for 2d unfortunately

@Toqozz
Copy link
Owner

Toqozz commented Jun 25, 2022

Correct this is intended behaviour currently. What you describe should have been the intended/the behaviour of the first implementation before this issue, but didn't seem to be working that way. I would have to investigate further, but assuming the implementation wasn't screwed up, this might have something to do with how bevy is doing layering for sprite, which I haven't looked at at all.

Has anyone managed to make a line that goes through a sprite? I'm kind of wondering if this is even possible with Mesh2D.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants