rend3
rend3 copied to clipboard
Enable full aliasing of wgpu texture inside rend3 texture/material.
Sometimes, a third party library will write directly to a wgpu texture. E.g. to draw a 2d animation and/or 2d UI elements.
Currently, the only way that I could find to display this texture on a rend3 material/texture is to copy the data with a separate instruction for the encoder for each frame.
As mentioned on Discord - it should not be necessary to take ownership of the wgpu texture to link it to a rend3 texture.
Currently, the code below kind of works, but my_texture_wgpu
is consumed by my_texture_wgpu_internal
. Because of that, I am no longer able to create further views of it or to directly access it with the third-party non-rend3-aware pure-wgpu renderer - which really only works if the texture is generated once, not for an animated texture/material. (or interactive UI element)
let my_texture_descriptor = wgpu::TextureDescriptor {
size: texture_size,
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format,
usage: wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::RENDER_ATTACHMENT,
label: Some("my texture"),
view_formats: &[wgpu::TextureFormat::Bgra8Unorm],
};
let my_texture_wgpu = renderer.device.create_texture(&texture_descriptor);
let texture_wgpu_view = my_texture_wgpu.create_view(&wgpu::TextureViewDescriptor::default());
let my_texture_rend3 = rend3::types::Texture {
label: Some("my texture but rend3".to_owned()),
format,
size: texture_size_uvec2,
mip_count: MipmapCount::Specific(NonZeroU32::new(1).unwrap()),
mip_source: rend3::types::MipmapSource::Uploaded,
data: vec![0; (texture_size_uvec2.x * texture_size_uvec2.y * 4) as usize],
};
let my_texture_rend3_handle = renderer.add_texture_2d(my_texture_rend3).unwrap();
let my_texture_rend3_raw_handle = my_texture_rend3_handle.get_raw();
let my_texture_wgpu_internal = InternalTexture {
texture: my_texture_wgpu,
view: my_texture_wgpu_view,
desc: my_texture_descriptor,
};
{
renderer
.data_core
.lock()
.d2_texture_manager
.fill(my_texture_rend3_raw_handle, my_texture_wgpu_internal);
}
// Create mesh and calculate smooth normals based on vertices
let sprite_mesh = create_quad(300.0);
// Add mesh to renderer's world.
//
// All handles are refcounted, so we only need to hang onto the handle until we
// make an object.
let sprite_mesh_handle = renderer.add_mesh(sprite_mesh).unwrap();
let sprite_material = rend3_routine::pbr::PbrMaterial {
albedo: rend3_routine::pbr::AlbedoComponent::Texture(my_texture_rend3_handle.clone()),
transparency: rend3_routine::pbr::Transparency::Blend,
..Default::default()
};
let sprite_material_handle = renderer.add_material(sprite_material);
// Combine the mesh and the material with a location to give an object.
let sprite_object = rend3::types::Object {
mesh_kind: rend3::types::ObjectMeshKind::Static(sprite_mesh_handle),
material: sprite_material_handle.clone(),
transform: glam::Mat4::from_scale_rotation_translation(
glam::Vec3::new(1.0, 1.0, 1.0),
glam::Quat::from_euler(glam::EulerRot::XYZ, 0.0, 0.0, 0.0),
glam::Vec3::new(0.0, 0.0, 0.0),
),
};
As a bit of a side note / maybe material for another request: The other approach I've tried in my attempts to achieve this - namely, by reading an existing internal wgpu::Texture
from a rend3::types::Texture
's handle, presents a different problem: The rend3::Texture
's internal texture doesn't have the RENDER_ATTACHMENT
usage on it and that field is read-only. I have tried to re-fill
such a texture with a raw wgpu::Texture
with the RENDER_ATTACHMENT
usage enabled, but it doesn't seem to become aware of it either way. This means I can't use the external non-rend3 renderer on that texture.