1
\$\begingroup\$

I have just completed the Vulkan tutorial using rust and the ash crate. I've been following along with this repository. I am unable to determine what is causing my textures to render lighter. If anyone can enlighten me as to any probable causes for this that would help a great deal.

My shaders are very basic. They are the exact same as what's in the tutorial, so I've ruled them out. I originally thought my problem had to do with multisampling but I've just completed that part of the course with no improvements to the color of my textures. my render

The texture I'm rendering from is directly taken from the vulkan-tutorial website. It looks as follows~enter image description here

As you can see my render is clearly lighter. You'll see I am using the "image.rs" crate to get raw byte data to create the texture.

pub fn create_texture_image(
    device: &ash::Device,
    command_pool: vk::CommandPool,
    submit_queue: vk::Queue,
    device_memory_properties: &vk::PhysicalDeviceMemoryProperties,
    image_path: &std::path::Path
) -> (vk::Image, vk::DeviceMemory, u32) {

    //Get image data
    let mut image_object = image::open(image_path).unwrap();
    image_object = image_object.flipv(); // flip vertically

    // destructuring image data
    let (image_width, image_height) = (image_object.width(), image_object.height());
    let image_size =
        (std::mem::size_of::<u8>() as u32 * image_width * image_height * 4) as vk::DeviceSize;

    let mip_levels = ((std::cmp::max(image_width, image_height) as f32)
        .log2()
        .floor() as u32) 
        + 1;
    
    let image_data;
    image_data = match &image_object {
        image::DynamicImage::ImageLuma8(_) |
        image::DynamicImage::ImageBgr8(_) |
        image::DynamicImage::ImageRgb8(_) => image_object.to_rgba8().into_raw(),
        image::DynamicImage::ImageLumaA8(_) |
        image::DynamicImage::ImageBgra8(_) |
        image::DynamicImage::ImageRgba8(_) => image_object.to_rgba8().into_raw(),
        _ => { panic!("Image is not one of the 8 bit formats")}
    };

    if image_size <= 0 {
        panic!("Failed to load texture image");
    }

    let (staging_buffer, staging_buffer_memory) = buffer::create_buffer(
        &device,
        image_size,
        vk::BufferUsageFlags::TRANSFER_SRC,
        vk::MemoryPropertyFlags::HOST_VISIBLE | 
        vk::MemoryPropertyFlags::HOST_COHERENT,
        device_memory_properties,
    );

    unsafe {
        let data_ptr = device
            .map_memory(
                staging_buffer_memory,
                0,
                image_size,
                vk::MemoryMapFlags::empty(),
            ).expect("Failed to Map Memory") as *mut u8;

        data_ptr.copy_from_nonoverlapping(image_data.as_ptr(), image_data.len());
        device.unmap_memory(staging_buffer_memory);
    }

    let (texture_image, texture_image_memory) = image_view::create_image(
        &device,
        image_width,
        image_height,
        mip_levels,
        vk::SampleCountFlags::TYPE_1,
        vk::Format::R8G8B8A8_UNORM,
        vk::ImageTiling::OPTIMAL,
        vk::ImageUsageFlags::TRANSFER_SRC
            | vk::ImageUsageFlags::TRANSFER_DST
            | vk::ImageUsageFlags::SAMPLED,
        vk::MemoryPropertyFlags::DEVICE_LOCAL,
        device_memory_properties,
    );

    transiiton_image_layout(
        device, 
        command_pool, 
        submit_queue, 
        texture_image, 
        vk::Format::R8G8B8A8_UNORM, 
        vk::ImageLayout::UNDEFINED, 
        vk::ImageLayout::TRANSFER_DST_OPTIMAL,
        mip_levels,
    );

    copy_buffer_to_image(
        device,
        command_pool,
        submit_queue,
        staging_buffer,
        texture_image,
        image_width,
        image_height,
    );

    generate_mipmaps(
        device,
        command_pool,
        submit_queue,
        texture_image,
        image_width,
        image_height,
        mip_levels,
    );

    unsafe {
        device.destroy_buffer(staging_buffer, None);
        device.free_memory(staging_buffer_memory, None);
    }

    (texture_image, texture_image_memory, mip_levels)
}
\$\endgroup\$
3
  • 2
    \$\begingroup\$ My gamma sense is tingling, as incorrect configuration of gamma-to-linear or linear-to-gamma colour encoding can cause images to look washed out (I just can never remember which). I'd recommend examining where you import/create textures: do you have an option to interpret them as sRGB instead of linear? And then I'd examine where you set up your frame buffer / render operation: do you have an option to output sRGB to the screen instead of linear? \$\endgroup\$
    – DMGregory
    Oct 14, 2021 at 12:34
  • \$\begingroup\$ Ah, ok. Yeah, this helps! I don't have time to look at my project at the moment, but in googling gamma correction in Vulkan I've got a waive of more trouble shooting possibilities. Thanks! I'll get back to you if I have definite answer. \$\endgroup\$ Oct 14, 2021 at 13:16
  • \$\begingroup\$ Ok, The problem was that my image_view, and my texture were different formats. Thanks! You're comment helped! \$\endgroup\$ Oct 15, 2021 at 10:44

1 Answer 1

1
\$\begingroup\$

Special thanks to a comment by DMGregory! The issue is caused because my Texture ImageView and my texture were using different formats. One was set to R8G8B8A_UNORM, and the other to R8G8B8A_SRGB.

Resolved by setting the format of both to R8G8B8A8_SRGB.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .