Skip to content

Artifact in sprite rendering #16918

Description

@sofia-m-a

Bevy version

0.15.0

[Optional] Relevant system information

`AdapterInfo { name: "AMD Radeon Graphics (RADV RENOIR)", vendor: 4098, device: 5686, device_type: IntegratedGpu, driver: "radv", driver_info: "Mesa 24.2.6", backend: Vulkan }`

What you did

Example code, using this CC0 tilemap texture Image

use bevy::prelude::*;
use std::collections::HashMap;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
        .add_systems(Startup, startup)
        .run();
}

fn startup(
    mut commands: Commands,
    assets: ResMut<AssetServer>,
    mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
) {
    let texture_handle = assets.load_with_settings(
        "kenney_tiny-dungeon/Tilemap/tilemap_packed.png",
        |settings: &mut bevy::image::ImageLoaderSettings| {
            // Use `nearest` image sampling to preserve the pixel art style.
            settings.sampler = bevy::image::ImageSampler::nearest();
        },
    );
    let texture_atlas_layout =
        TextureAtlasLayout::from_grid(UVec2::new(16, 16), 12, 11, None, None);
    let texture_atlas_layout = texture_atlas_layouts.add(texture_atlas_layout);
    commands.spawn(Camera2d);

    let mut out = HashMap::new();

    { // generation, not super important, it just is easier to see the bug with some variety
        for x in -2..=2 {
            for y in -2..=2 {
                out.insert(IVec2::new(x, y), 48);
            }
        }

        for y in -2..=2 {
            out.insert(IVec2::new(-3, y), 13);
            out.insert(IVec2::new(3, y), 15);
        }

        for x in -2..=2 {
            out.insert(IVec2::new(x, -3), 26);
            out.insert(IVec2::new(x, 3), 2);
        }

        out.insert(IVec2::new(-3, -3), 25);
        out.insert(IVec2::new(3, -3), 27);
        out.insert(IVec2::new(-3, 3), 1);
        out.insert(IVec2::new(3, 3), 3);
    }

    for (place, kind) in out {
        let mut s = Sprite::from_atlas_image(texture_handle.clone(), TextureAtlas {
            layout: texture_atlas_layout.clone(),
            index: kind,
        });
        s.custom_size = Some(Vec2::new(1.0, 1.0));

        let scale = 6.0;
        commands.spawn((
            s,
            Transform::from_scale(Vec2::splat(16.0 * scale).extend(1.0))
                * Transform::from_translation(place.as_vec2().extend(0.0)),
        ));
    }
}

What went wrong

There is misalignment Image
It seems the bottom-left triangle of each quad has incorrect texturing, seemingly the wrong UVs, leading to it not matching the neighbouring triangle, and also bleeding over the edge of the atlas by 1 pixel

Additional information

Maybe its something to do with rounding?!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-RenderingDrawing game state to the screenC-BugAn unexpected or incorrect behaviorS-Needs-InvestigationThis issue requires detective work to figure out what's going wrong

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions