Artifact in sprite rendering
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## Bevy version
0.15.0
## \[Optional\] Relevant system information
```ignore
`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](https://github.com/user-attachments/assets/8442c06e-7443-4190-b70b-eda7023269be)
```rust
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,
mut texture_atlas_layouts: ResMut>,
) {
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 
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?!
Contributor guide
Research direction
Start by running the provided reproduction with Bevy 0.15.0, the tilemap image, ImagePlugin::default_nearest(), Sprite::from_atlas_image(), and TextureAtlasLayout::from_grid(). Inspect the sprite atlas rendering path around the generated UVs and compare the bottom-left triangle with its neighboring triangle. Done means the reproduced atlas sprites are aligned without edge bleeding.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- computer-graphics, game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100