所以我仍然试图找出渲染纹理的颜色空间,以及如何创建没有颜色条带的图像。在我的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画面上裁剪而感到遗憾......),是图像不会受到色带的影响,例如在使用时不使用我的纹理的这些格式,我使用VK_FORMAT_R8G8B8A8_UNORM与VK_IMAGE_TILING_OPTIMAL:
您是否可以看到头盔左上方以及下方(黑色管子所在的位置)出现条带。当然,我听说过从post
中避免使用VK_IMAGE_TILING_LINEAR一般来说,我在查找使用srgb纹理时避免使用VK_IMAGE_TILING_LINEAR的最佳方法时遇到问题?我仍然想保留srgb给我的漂亮清晰的图像,但我不确定如何解决这个问题。该链接实际上可能有解决方案,但我不太确定是否有办法将其应用于我的gbuffer。
我还想澄清一点,VK_IMAGE_TILING_OPTIMAL适用于基于Nvidia的GPU(好吧,在GTX 870M上测试过)但是抱怨使用VK_IMAGE_TILING_LINEAR用于srgb格式,但是,基于intel的gpus可以正常使用VK_IMAGE_TILING_LINEAR并且有点像废话一样使用VK_IMAGE_TILING_OPTIMAL时,第一张图片在这篇文章的顶部。
引擎是定制的,请随时查看link
如果你想要一些代码,我在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
答案 0 :(得分:2)
必须支持此组合,因此第一张图片中的损坏是应用程序或驱动程序错误。
因此VK_FORMAT_R8G8B8A8_SRGB
正在您的Nvidia GPU上使用VK_IMAGE_TILING_OPTIMAL
,但在您的英特尔GPU上却没有?但是VK_FORMAT_R8G8B8A8_SRGB
是否适用于英特尔GPU上的VK_IMAGE_TILING_LINEAR
?
如果是这样,听起来你的图像布局过渡有些缺失或不正确。英特尔比Nvidia更加敏感。验证层是否会抱怨什么?您需要确保图片在呈现时为VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
,并在从中进行采样时VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
。