Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable full aliasing of wgpu texture inside rend3 texture/material. #552

Open
pillowtrucker opened this issue Dec 29, 2023 · 0 comments
Open

Comments

@pillowtrucker
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant