Вот ряд текстур / квадов, с ближайшим к камере созданным последним изображением :
Снимок экрана 1
Это работаетв совершенстве!Однако, как только вы просматриваете текстуры под углом, в котором самое близкое к камере изображение создается первым , прозрачные пиксели выбирают только фоновый цвет:
Снимок экрана 2
Что сбивает с толку, так это то, что пиксели под этим углом будут правильно подбирать «реальные» 3D-модели, полностью игнорируя четырехугольники между ними, независимо от того, в каком порядке была создана 3D-модель:
Снимок экрана 3
Дамп кода
Если честно, я не уверен, какие части кода размещать здесь, будь тоэта проблема вызвана неправильно настроенным шаблоном глубины или чем-то еще полностью.Если чего-то не хватает, пожалуйста, дайте мне знать, и я обновлю вопрос.
createDepthStencil ()
// Get Depth Format
std::array<VkFormat, 5> depthFormats = {
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_D32_SFLOAT,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_D16_UNORM_S8_UINT,
VK_FORMAT_D16_UNORM
};
for (auto& format : depthFormats)
{
VkFormatProperties formatProps;
vkGetPhysicalDeviceFormatProperties(vulkanDevice.physicalDevice, format, &formatProps);
// Format must support depth stencil attachment for optimal tiling
if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
{
depthFormat = format;
break;
}
}
// Assert that we have a depth format to use
assert(depthFormat != VK_FORMAT_UNDEFINED);
VkImageCreateInfo depthImageInfo = {};
depthImageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
depthImageInfo.pNext = nullptr;
depthImageInfo.imageType = VK_IMAGE_TYPE_2D;
depthImageInfo.format = depthFormat;
depthImageInfo.extent = { vulkanSwapChain.extent.width, vulkanSwapChain.extent.height, 1 };
depthImageInfo.mipLevels = 1;
depthImageInfo.arrayLayers = 1;
depthImageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
depthImageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
depthImageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
depthImageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
depthImageInfo.flags = 0;
VmaAllocationCreateInfo depthImageAllocCreateInfo = {};
depthImageAllocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
// Create Depth Stencil Image
if (vmaCreateImage(vulkanMemory, &depthImageInfo, &depthImageAllocCreateInfo, &depthImage, &depthImageAllocation, &depthImageAllocationInfo) != VK_SUCCESS) {
throw std::runtime_error("Failed to create Depth Stencil Image!");
}
VkImageViewCreateInfo depthStencilView = {};
depthStencilView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
depthStencilView.pNext = nullptr;
depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D;
depthStencilView.image = depthImage;
depthStencilView.format = depthFormat;
depthStencilView.flags = 0;
depthStencilView.subresourceRange = {};
depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
depthStencilView.subresourceRange.baseMipLevel = 0;
depthStencilView.subresourceRange.levelCount = 1;
depthStencilView.subresourceRange.baseArrayLayer = 0;
depthStencilView.subresourceRange.layerCount = 1;
// Create Depth Stencil Image View
if (vkCreateImageView(vulkanDevice.logicalDevice, &depthStencilView, nullptr, &depthImageView) != VK_SUCCESS) {
throw std::runtime_error("Failed to create Depth Stencil Image View!");
}
createRenderPasses ()
std::array<VkAttachmentDescription, 2> attachments = {};
...
// Depth attachment
attachments[1].format = depthFormat;
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentReference depthAttachmentRef = {};
depthAttachmentRef.attachment = 1;
depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass = {};
subpass.pDepthStencilAttachment = &depthAttachmentRef;
renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
renderPassInfo.pAttachments = attachments.data();
createGraphicsPipelines ()
VkPipelineRasterizationStateCreateInfo rasterizer = {};
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterizer.depthClampEnable = VK_FALSE;
rasterizer.rasterizerDiscardEnable = VK_FALSE;
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
rasterizer.lineWidth = 1.0f;
rasterizer.cullMode = VK_CULL_MODE_NONE;
rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
rasterizer.depthBiasEnable = VK_TRUE; // VK_DYNAMIC_STATE_DEPTH_BIAS is set
rasterizer.flags = 0;
VkPipelineDepthStencilStateCreateInfo depthStencil = {};
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencil.depthTestEnable = VK_TRUE;
depthStencil.depthWriteEnable = VK_TRUE;
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
depthStencil.depthBoundsTestEnable = VK_FALSE;
depthStencil.minDepthBounds = 0.0f;
depthStencil.maxDepthBounds = 1.0f;
depthStencil.stencilTestEnable = VK_FALSE;
depthStencil.front = {};
depthStencil.back = {};
VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
VkPipelineColorBlendStateCreateInfo colorBlending = {};
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlending.logicOpEnable = VK_FALSE;
colorBlending.logicOp = VK_LOGIC_OP_COPY;
colorBlending.attachmentCount = 1;
colorBlending.pAttachments = &colorBlendAttachment;
colorBlending.blendConstants[0] = 0.0f;
colorBlending.blendConstants[1] = 0.0f;
colorBlending.blendConstants[2] = 0.0f;
colorBlending.blendConstants[3] = 0.0f;
createFrameBuffers ()
std::array<VkImageView, 2> attachments;
attachments[1] = depthImageView;
...
frameBufferInfo.pAttachments = attachments.data();
drawFrame()
std::array<VkClearValue, 2> clearValues;
clearValues[0].color = {0.25f, 0.25f, 0.5f, 1.0f}; // Purple
clearValues[1].depthStencil = { 1.0f, 0 };
renderPassBeginInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
renderPassBeginInfo.pClearValues = clearValues.data();
Texture.cpp (четыре вершины / индексы)
// Position // Color RGBA // UV Map
{{ 1.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f }},
{{ -1.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f }},
{{ -1.0f, -1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f }},
{{ 1.0f, -1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, { 1.0f, 0.0f }}
std::vector<uint32_t> indices = {
0, 1, 2, 2, 3, 0
};
Пара замечаний: текстура загружена .ktxGLI в формате VK_FORMAT_R8G8B8A8_UNORM, а шейдеры GLSL - это просто матрица проекции вида модели и сэмплер текстуры.
Есть идеи, что заставляет текстуры игнорировать другие текстурированные квадраты в прозрачных пикселях?
Спасибо!