bevyengine / bevyengine/bevy

ImageAddressMode::Repeat "twitchy" texture rendering

Open
#15,162 3 comments 0 reactions 0 assignees View on GitHub
A-Rendering C-Bug D-Modest O-Vulkan S-Needs-Investigation
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version
0.14.2

## \[Optional\] Relevant system information
AdapterInfo { name: "NVIDIA GeForce GTX 1060 6GB", vendor: 4318, device: 7171, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "535.183.01", backend: Vulkan }
Also occurs with any other computer I have tried (they all happen to be using Vulkan, haven't tested other backends).

## What you did
Set ImagePlugin to
```rust
ImagePlugin {
default_sampler: ImageSamplerDescriptor {
address_mode_u: ImageAddressMode::Repeat,
address_mode_v: ImageAddressMode::Repeat,
address_mode_w: ImageAddressMode::Repeat,
..Default::default()
},
}
```
and mapped a texture to a mesh.

## What went wrong
The texture "twitches" depending on the position of the camera and the entity. That is, sometimes the texture is not mapped to the vertices as it should according to the specified UV.

## Additional information
Minimal example
```rust
use bevy::prelude::*;
use bevy::render::texture::{ImageAddressMode, ImageSamplerDescriptor};
use bevy::render::{
mesh::Indices, render_asset::RenderAssetUsages, render_resource::PrimitiveTopology,
};
use bevy::sprite::MaterialMesh2dBundle;

fn main() {
App::new()
.insert_resource(ClearColor(Color::BLACK))
.add_plugins(DefaultPlugins.set(ImagePlugin {
default_sampler: ImageSamplerDescriptor {
address_mode_u: ImageAddressMode::Repeat,
address_mode_v: ImageAddressMode::Repeat,
address_mode_w: ImageAddressMode::Repeat,
..Default::default()
},
}))
.add_systems(Startup, setup)
.add_systems(Update, update)
.run();
}

fn setup(
mut commands: Commands,
asset_server: Res,
mut materials: ResMut>,
mut meshes: ResMut>,
) {
const TRANSFORM: Transform = Transform::from_translation(Vec3::ZERO);

let mut camera = Camera2dBundle::default();
camera.transform.scale = Vec3::splat(0.125f32);
commands.spawn(camera);

let texture = asset_server.load("generic-rpg-tile68.png"); // Can be any non-solid color texture.

let mesh = Mesh::new(
PrimitiveTopology::TriangleList,
RenderAssetUsages::default(),
)
.with_inserted_attribute(
Mesh::ATTRIBUTE_POSITION,
vec![
[16.0, 32.0, 0.0],
[-16.0, 32.0, 0.0],
[-16.0, -32.0, 0.0],
[16.0, -32.0, 0.0],
],
)
.with_inserted_attribute(
Mesh::ATTRIBUTE_UV_0,
vec![[1.0, -2.0], [-1.0, -2.0], [-1.0, 2.0], [1.0, 2.0]],
)
.with_inserted_attribute(
Mesh::ATTRIBUTE_NORMAL,
vec![
[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0],
],
)
.with_inserted_indices(Indices::U32(vec![0, 1, 2, 0, 2, 3]));

commands.spawn(MaterialMesh2dBundle {
mesh: meshes.add(mesh).into(),
material: materials.add(ColorMaterial {
color: Color::WHITE,
texture: texture.into(),
}),
global_transform: TRANSFORM.into(),
transform: TRANSFORM,
..Default::default()
});
}

fn update(mut camera: Query<&mut Transform, With>) {
const DELTA: f32 = 1f32 / 128f32;
camera.get_single_mut().unwrap().translation.x += DELTA;
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.