Bevy中立方体仅单面显模糊纹理,无法全面贴清晰纹理的原因及解决
Bevy中16x16纹理立方体单面模糊的问题与修复
问题描述
尝试在Bevy中渲染一个各面均贴有16x16纹理的1单位立方体,编译后立方体仅单面显示清晰纹理,其余面模糊(原纹理本身是清晰的)。相关代码如下:
use bevy::prelude::*; fn main() { App::new() .add_plugins(DefaultPlugins.set(WindowPlugin { window: WindowDescriptor { title: "Definitely Minecraft".to_string(), ..Default::default() }, ..Default::default() })) .add_startup_system(setup_system) .add_startup_system_to_stage(StartupStage::PostStartup, generate_world_system) .run(); } #[derive(Resource)] struct GameMaterials { dirt: Handle<StandardMaterial> } fn setup_system ( mut commands: Commands, asset_server: Res<AssetServer>, mut materials: ResMut<Assets<StandardMaterial>>, ) { // Light commands.spawn(DirectionalLightBundle { transform: Transform::from_xyz(4., 80., 4.), ..Default::default() }); commands.insert_resource(GameMaterials { dirt: materials.add(StandardMaterial { base_color_texture: Some(asset_server.load("dirt.png")), alpha_mode: AlphaMode::Blend, unlit: false, ..Default::default() }) }); // Camera commands.spawn(Camera3dBundle { transform: Transform::from_xyz(3., 5., 8.).looking_at(Vec3::ZERO, Vec3::Y), ..Default::default() }); } fn generate_world_system( mut commands: Commands, game_materials: Res<GameMaterials>, mut meshes: ResMut<Assets<Mesh>>, ) { let block_handle = meshes.add(Mesh::from(shape::Cube::new(1.))); commands.spawn(PbrBundle { mesh: block_handle.clone(), material: game_materials.dirt.clone(), transform: Transform::from_xyz(0., 0., 1.5), ..Default::default() }); }
问题原因
- 默认纹理过滤模式导致模糊:Bevy默认使用线性过滤(Linear),这种过滤会对相邻纹理像素进行插值,当16x16的小尺寸纹理贴在和纹理尺寸接近的立方体表面时,插值会让纹理失去像素感,呈现模糊效果。单面清晰是因为该面的视角刚好让纹理采样更接近原始像素,插值影响较小。
- Mipmap自动切换:Bevy默认会为纹理生成mipmap(不同分辨率的纹理层级),当立方体与相机的距离变化时,渲染器会自动选择低分辨率的mipmap层级,进一步加剧模糊。
修复方案
1. 修改纹理过滤为最近邻模式并禁用Mipmap
最近邻过滤会直接取距离采样点最近的纹理像素,完美保留16x16纹理的像素感。修改setup_system中的材质创建代码:
commands.insert_resource(GameMaterials { dirt: materials.add(StandardMaterial { base_color_texture: Some(asset_server.load_with_settings("dirt.png", |settings: &mut bevy::render::texture::ImageSettings| { // 设置放大、缩小过滤为最近邻 settings.sampler.min_filter = bevy::render::texture::FilterMode::Nearest; settings.sampler.mag_filter = bevy::render::texture::FilterMode::Nearest; // 禁用Mipmap生成,避免层级切换导致的模糊 settings.generate_mip_maps = false; })), alpha_mode: AlphaMode::Blend, unlit: false, ..Default::default() }) });
2. 验证立方体UV映射(可选)
Bevy默认的shape::Cube生成的Mesh已经包含正确的UV映射(每个面的UV范围都是0.0到1.0,刚好适配纹理),所以这一步通常不需要修改。如果仍有个别面纹理异常,可以手动构建Mesh并自定义UV坐标,确保每个面的顶点UV都覆盖完整的纹理区域。
内容的提问来源于stack exchange,提问作者NaniNoni
相关产品推荐
相关产品推荐

