Skip to content

Artifact in sprite rendering #16918

Open
Open
@sofia-m-a

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?!

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