首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用VK_IMAGE_TILING_LINEAR作为srgb格式?

使用VK_IMAGE_TILING_LINEAR作为srgb格式?
EN

Stack Overflow用户
提问于 2018-04-13 17:06:16
回答 1查看 1K关注 0票数 1

所以我仍然在努力找出渲染纹理的颜色空间,以及如何在不分色的情况下创建图像。在我的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行中:

代码语言:javascript
复制
      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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49822020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档