所以我仍然在努力找出渲染纹理的颜色空间,以及如何在不分色的情况下创建图像。在我的gbuffer中,我使用VK_FORMAT_R8G8B8A8_UNORM和VK_IMAGE_TILING来表示反照率纹理,使用VK_FORMAT_A2B10G10R10_UNORM_PACK32和VK_IMAGE_TILING_OPTIMAL表示正常和发射渲染纹理。对于我的亮度纹理(在场景中包含被认为是“亮”的像素值)和显示纹理(稍后将添加到最终场景中的布卢姆效果的最终纹理),我使用VK_FORMAT_R8G8B8A8_SRGB和VK_IMAGE_TILING_OPTIMAL (尽管从这个角度来看,我可能应该使用明亮和最终的纹理R16G16B16A16浮标格式)。我得到的绝对不是我想要的:

然而,将我的正常、发射、发光和亮度纹理的贴图更改为VK_IMAGE_TILING_LINEAR,反而给我带来了不错的结果,但代价是性能:

不过,令人欣慰的是(对左上角的奇怪边框感到抱歉,它是在MS was上剪切的……),图像没有受到颜色条带的影响,例如,当我使用VK_FORMAT_R8G8B8A8_UNORM和VK_IMAGE_TILING_OPTIMAL,而不是将这些格式用于我的纹理时:

你是否可以看到在头盔的左上角,以及在它下面(黑管在那里)。当然,我听说过避免VK_IMAGE_TILING_LINEAR从这个帖子
一般来说,我很难找到在使用srgb纹理时避免使用VK_IMAGE_TILING_LINEAR的最佳方法是什么?我仍然想保留srgb给我的清晰的图片,但是我不知道如何解决这个问题。链接可能确实有解决方案,但我不太确定是否有方法将它应用到gbuffer中。
我还想澄清的是,VK_IMAGE_TILING_OPTIMAL对于基于Nvidia的GPUs (嗯,在GTX870M上进行了测试)很好,但是抱怨使用VK_IMAGE_TILING_LINEAR作为srgb格式,然而,基于英特尔的gpus在VK_IMAGE_TILING_LINEAR上工作得很好,在使用VK_IMAGE_TILING_OPTIMAL时就像第一张图片一样。
该引擎是自定义的,请在此链接中查看它。
如果您喜欢一些代码,那么在Engine/Renderer/Private/Renderer.cpp文件中使用一个名为SetUpRenderTextures()的函数,在第1396行中:
VkImageCreateInfo cImageInfo = { };
VkImageViewCreateInfo cViewInfo = { };
// TODO(): Need to make this more adaptable, as intel chips have trouble with srgb optimal tiling.
cImageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
cImageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
cImageInfo.imageType = VK_IMAGE_TYPE_2D;
cImageInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
cImageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
cImageInfo.mipLevels = 1;
cImageInfo.extent.depth = 1;
cImageInfo.arrayLayers = 1;
cImageInfo.extent.width = m_pWindow->Width();
cImageInfo.extent.height = m_pWindow->Height();
cImageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
cImageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
cImageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
cViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
cViewInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
cViewInfo.image = nullptr; // No need to set the image, texture->Initialize() handles this for us.
cViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
cViewInfo.subresourceRange = { };
cViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
cViewInfo.subresourceRange.baseArrayLayer = 0;
cViewInfo.subresourceRange.baseMipLevel = 0;
cViewInfo.subresourceRange.layerCount = 1;
cViewInfo.subresourceRange.levelCount = 1;
gbuffer_Albedo->Initialize(cImageInfo, cViewInfo);
gbuffer_Emission->Initialize(cImageInfo, cViewInfo);
cImageInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
cViewInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
cImageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
GlowTarget->Initialize(cImageInfo, cViewInfo);
// It's probably best that these be 64bit float formats as well...
pbr_Bright->Initialize(cImageInfo, cViewInfo);
pbr_Final->Initialize(cImageInfo, cViewInfo);
cImageInfo.format = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
cImageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
cViewInfo.format = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
gbuffer_Normal->Initialize(cImageInfo, cViewInfo);
gbuffer_Position->Initialize(cImageInfo, cViewInfo);所以是的,破旧不堪。如何避免对srgb纹理使用线性图像拼接?这是一种特定于硬件的东西吗?它是强制性的吗?另外,我也为我在这个问题上的任何形式的无知而道歉。
谢谢:3
发布于 2018-04-13 18:22:43
对此组合的支持是强制性的,因此您的第一个映像中的损坏不是应用程序就是驱动程序错误。
那么,VK_FORMAT_R8G8B8A8_SRGB正在与VK_IMAGE_TILING_OPTIMAL合作您的Nvidia GPU,而不是您的英特尔GPU?但是VK_FORMAT_R8G8B8A8_SRGB在英特尔的GPU上和VK_IMAGE_TILING_LINEAR一起工作吗?
如果是这样的话,听起来你好像有一些丢失或不正确的图像布局转换。英特尔比Nvidia更敏感地对待这些问题。验证层会抱怨什么吗?您需要确保图像呈现时是VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,采样时是VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL。
https://stackoverflow.com/questions/49822020
复制相似问题