Last active
January 18, 2025 22:40
-
-
Save bas-ie/abfe57a0fd136d7ff547e623527f63de to your computer and use it in GitHub Desktop.
Minimal repro of image render target issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use bevy::{ | |
prelude::*, | |
render::{ | |
render_asset::RenderAssetUsages, | |
render_resource::{ | |
AsBindGroup, Extent3d, ShaderRef, TextureDimension, TextureFormat, TextureUsages, | |
}, | |
view::RenderLayers, | |
}, | |
sprite::{Material2d, Material2dPlugin}, | |
}; | |
fn main() { | |
App::new() | |
.init_resource::<ImageRenderTarget>() | |
.add_plugins(( | |
DefaultPlugins.set(WindowPlugin { | |
primary_window: Window { | |
resizable: false, | |
..default() | |
} | |
.into(), | |
..default() | |
}), | |
Material2dPlugin::<CustomMaterial>::default(), | |
)) | |
.add_systems(Startup, init) | |
.add_systems(Update, check_image) | |
.run(); | |
} | |
const SHADER_ASSET_PATH: &str = "color_shader.wgsl"; | |
#[derive(Resource, Default)] | |
pub struct ImageRenderTarget { | |
pub texture: Handle<Image>, | |
} | |
#[derive(Asset, Default, TypePath, AsBindGroup, Debug, Clone)] | |
pub struct CustomMaterial { | |
#[uniform(0)] | |
pub color: Vec4, | |
#[texture(1)] | |
#[sampler(2)] | |
pub texture: Handle<Image>, | |
} | |
impl Material2d for CustomMaterial { | |
fn fragment_shader() -> ShaderRef { | |
SHADER_ASSET_PATH.into() | |
} | |
} | |
#[derive(Component)] | |
struct RenderTargetCamera; | |
#[derive(Component)] | |
struct MainCamera; | |
fn init( | |
asset_server: Res<AssetServer>, | |
mut commands: Commands, | |
mut materials: ResMut<Assets<CustomMaterial>>, | |
mut meshes: ResMut<Assets<Mesh>>, | |
mut images: ResMut<Assets<Image>>, | |
mut target_image: ResMut<ImageRenderTarget>, | |
) { | |
let size = Extent3d { | |
width: 256, | |
height: 256, | |
..default() | |
}; | |
let mut image = Image::new_fill( | |
size, | |
TextureDimension::D2, | |
&[0, 0, 0, 0], | |
TextureFormat::Bgra8UnormSrgb, | |
RenderAssetUsages::default(), | |
); | |
image.texture_descriptor.usage = | |
TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST | TextureUsages::RENDER_ATTACHMENT; | |
target_image.texture = images.add(image); | |
// RenderTarget or "source" cam? | |
commands.spawn(( | |
Name::new("ImageRenderTarget Camera"), | |
RenderTargetCamera, | |
Camera2d, | |
Camera { | |
order: -1, | |
target: bevy::render::camera::RenderTarget::Image(target_image.texture.clone()), | |
clear_color: ClearColorConfig::None, | |
..default() | |
}, | |
)); | |
// Source custom material | |
commands.spawn(( | |
Name::new("Mesh With Custom Material"), | |
Mesh2d(meshes.add(Rectangle::new(256., 256.))), | |
MeshMaterial2d(materials.add(CustomMaterial { | |
color: Vec4::new(0., 0., 0., 1.), | |
texture: asset_server.load("green.png"), | |
})), | |
)); | |
// Main or "destination" cam? | |
commands.spawn(( | |
Name::new("Main Camera"), | |
MainCamera, | |
Camera2d, | |
RenderLayers::layer(1), | |
)); | |
// Destination image (on a sprite) | |
commands.spawn(( | |
Name::new("Debug ImageRenderTarget"), | |
RenderLayers::layer(1), | |
Sprite { | |
image: target_image.texture.clone(), | |
..Default::default() | |
}, | |
)); | |
} | |
fn check_image(images: Res<Assets<Image>>, render_target: Res<ImageRenderTarget>) { | |
let Some(img) = images.get(&render_target.texture) else { | |
return; | |
}; | |
// I would expect this to be black (0, 0, 0, 1) due to the shader output of that colour, but | |
// it's still zero-d out from its initialisation (0, 0, 0, 0). | |
let Some(pixel) = img.pixel_bytes(UVec3::new(128, 128, 0)) else { | |
return; | |
}; | |
dbg!(pixel); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment