#Weird subpixel rendering issue after changing to TextureAtlas

1 messages · Page 1 of 1 (latest)

earnest iron
#

Previously, I was rendering a bunch of Sprites by loading their handle JIT for spawning:

pub fn on_spawn_element(
    mut commands: Commands,
    elements: Query<(Entity, &Position, &Element), (Added<Element>, Without<Air>)>,
    world_map: Res<WorldMap>,
    asset_server: Res<AssetServer>,
) {
    for (entity, position, element) in &elements {
        commands.entity(entity).insert(SpriteBundle {
            texture: get_element_texture(element, &asset_server),
            transform: Transform::from_translation(position.as_world_position(&world_map)),
            sprite: Sprite {
                custom_size: Some(Vec2::splat(1.0)),
                ..default()
            },
            ..default()
        });
    }
}

pub fn get_element_texture(element: &Element, asset_server: &Res<AssetServer>) -> Handle<Image> {
    match element {
        // Air is transparent - reveals background color such as tunnel or sky
        Element::Air => panic!("Air element should not be rendered"),
        Element::Dirt => asset_server.load("images/dirt/dirt.png"),
        Element::Sand => asset_server.load("images/sand/sand.png"),
        Element::Food => asset_server.load("images/food/food.png"),
    }
}

This worked well.

Now, I am trying to support rendering edges on my rendered Elements. I think this means I need to introduce 9 images per Element. I think this also means I am supposed to adopt a SpriteSheet for performance, but I don't really understand the details as to why that's better now.

So, I rewrote my code following this TextureAtlas example: https://github.com/bevyengine/bevy/blob/latest/examples/2d/texture_atlas.rs with a modification of not calling load_folder because I am targeting WASM.

pub fn get_element_handle(element: &Element, asset_server: &Res<AssetServer>) -> Handle<Image> {
    match element {
        // Air is transparent - reveals background color such as tunnel or sky
        Element::Air => panic!("Air element should not be rendered"),
        Element::Dirt => asset_server.load("images/dirt/dirt.png"),
        Element::Sand => asset_server.load("images/sand/sand.png"),
        Element::Food => asset_server.load("images/food/food.png"),
    }
}

pub fn on_spawn_element(
    mut commands: Commands,
    elements: Query<(Entity, &Position, &Element), (Added<Element>, Without<Air>)>,
    world_map: Res<WorldMap>,
    sprite_sheets: Res<SpriteSheets>,
    asset_server: Res<AssetServer>,
    texture_atlases: Res<Assets<TextureAtlas>>
) {
    for (entity, position, element) in &elements {
        let element_sprite_sheet = texture_atlases.get(&sprite_sheets.element).unwrap();
        let element_handle = get_element_handle(element, &asset_server);
        let element_index = element_sprite_sheet.get_texture_index(&element_handle).unwrap();

        let mut sprite = TextureAtlasSprite::new(element_index);
        sprite.custom_size = Some(Vec2::splat(1.0));

        commands.entity(entity).insert(SpriteSheetBundle {
            sprite,
            texture_atlas: sprite_sheets.element.clone(),
            transform: Transform::from_translation(position.as_world_position(&world_map)),
            ..default()
        });
    }
}

This mostly works. I see the sprites render. However, I now see this odd visual artifact where grid lines are rendered throughout my dirt. This started occurring when I swapped to using a SpriteSheetBundle to render my sprite.

I feel like these outputs should be the same. Am I not understanding something or is this a rendering bug?

GitHub

A refreshingly simple data-driven game engine built in Rust - bevyengine/bevy

earnest iron
#

Looks like the easiest fix is to adopt bevy_ecs_tilemap maybe

spare drum
#

Maybe adding padding will help

earnest iron
#

I think that requires me to put all my images onto one large sheet though, right? Where as using add_texture allows me to load individual images

#

Not opposed just confirming

spare drum
earnest iron
#

I tried editing them directly and it seemed fussy

#

but I was able to get to a working, yet fragile, fix with the grid approach

#

I used a single image composed of three 128x128 images in a row, then used TextureAtlas::from_grid with tile_size of 126 and padding of 4

#

anything closer to 128x128 caused grid lines to appear shrug