是什么导致在多边形的每个三角形上渲染纹理?
What causes textures to be rendered on each triangle of a polygon?
我正在尝试渲染带纹理的正方形,但看起来纹理没有像应有的那样进行插值。看起来它在我正方形的每个三角形上都得到了镜像。行为如下图所示。
请注意,我使用的是 this 教程。
我不知道从哪里开始修复我的代码。此外,当我尝试翻译我的图像布局时,出现此错误:"Cannot submit cmd buffer using image 0x25 with layout VK_IMAGE_LAYOUT_UNDEFINED when first use is VK_IMAGE_LAYOUT_TRANSFER_DST_BIT."
此外,我在第一次提交绘图命令缓冲区时收到此警告:"Cannot submit cmd buffer using image 0x25 with layout VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL when first use is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL."
这个警告会导致我的问题吗?此外,这是我的顶点及其纹理坐标。
vertices->setVertices({
{{-1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}},
{{1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
{{1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
{{-1.0f, 1.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}
});
vertices->setIndices({ 0, 1, 2, 2, 3, 0 });
更新:
这是我的图像转换代码:
void Util::transitionImageLayout(VkImage *image, VkFormat format,
VkImageLayout oldLayout, VkImageLayout newLayout,
VkCommandBuffer recordingBuffer) {
VkImageMemoryBarrier barrier = {};
VkImageSubresourceRange subresourceRange = {};
VkPipelineStageFlags sourceStage = {};
VkPipelineStageFlags dstStage = {};
if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
}
else {
throw std::invalid_argument("Layout transition not supported.");
}
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresourceRange.baseArrayLayer = 0;
subresourceRange.baseMipLevel = 0;
subresourceRange.layerCount = 1;
subresourceRange.levelCount = 1;
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.image = *image;
barrier.oldLayout = oldLayout;
barrier.newLayout = newLayout;
barrier.subresourceRange = subresourceRange;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vkCmdPipelineBarrier(recordingBuffer, sourceStage, dstStage, 0, 0, nullptr, 0, nullptr, 0, &barrier);
}
这是我复制缓冲区到图像的代码:
void Util::copyBufferToimage(VkCommandBuffer cmdBuffer, VkBuffer buffer,
VkImage *image, uint32_t width, uint32_t height) {
VkBufferImageCopy region{};
VkImageSubresourceLayers subresouce{};
subresouce.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresouce.baseArrayLayer = 0;
subresouce.mipLevel = 0;
subresouce.layerCount = 1;
region.bufferImageHeight = 0;
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.imageOffset = { 0, 0, 0 };
region.imageExtent = { width, height, 1 };
region.imageSubresource = subresouce;
vkCmdCopyBufferToImage(cmdBuffer, buffer, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
}
备注:
我已经尝试 运行 教程的 git 存储库中的项目,并且工作正常。他们没有收到警告。
问题出在我没有提供的顶点结构代码中。纹理坐标格式错误。应该是R32 G32
,我设置成R32 G32 B32 A32
.
static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions() {
std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions = {};
attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions[0].offset = offsetof(Vertex, position);
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[1].offset = offsetof(Vertex, color);
attributeDescriptions[2].binding = 0;
attributeDescriptions[2].location = 2;
attributeDescriptions[2].format = VK_FORMAT_R32G32B32A32_SFLOAT; //This is an error. I guess this has to do something with texCoord being a glm::vec2
attributeDescriptions[2].offset = offsetof(Vertex, texCoord);
return attributeDescriptions;
}
所以,关于纹理坐标的属性描述格式应该是
attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
现在我的多边形看起来像这样:
我正在尝试渲染带纹理的正方形,但看起来纹理没有像应有的那样进行插值。看起来它在我正方形的每个三角形上都得到了镜像。行为如下图所示。
请注意,我使用的是 this 教程。
我不知道从哪里开始修复我的代码。此外,当我尝试翻译我的图像布局时,出现此错误:"Cannot submit cmd buffer using image 0x25 with layout VK_IMAGE_LAYOUT_UNDEFINED when first use is VK_IMAGE_LAYOUT_TRANSFER_DST_BIT."
此外,我在第一次提交绘图命令缓冲区时收到此警告:"Cannot submit cmd buffer using image 0x25 with layout VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL when first use is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL."
这个警告会导致我的问题吗?此外,这是我的顶点及其纹理坐标。
vertices->setVertices({
{{-1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}},
{{1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
{{1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
{{-1.0f, 1.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}
});
vertices->setIndices({ 0, 1, 2, 2, 3, 0 });
更新:
这是我的图像转换代码:
void Util::transitionImageLayout(VkImage *image, VkFormat format,
VkImageLayout oldLayout, VkImageLayout newLayout,
VkCommandBuffer recordingBuffer) {
VkImageMemoryBarrier barrier = {};
VkImageSubresourceRange subresourceRange = {};
VkPipelineStageFlags sourceStage = {};
VkPipelineStageFlags dstStage = {};
if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
}
else {
throw std::invalid_argument("Layout transition not supported.");
}
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresourceRange.baseArrayLayer = 0;
subresourceRange.baseMipLevel = 0;
subresourceRange.layerCount = 1;
subresourceRange.levelCount = 1;
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.image = *image;
barrier.oldLayout = oldLayout;
barrier.newLayout = newLayout;
barrier.subresourceRange = subresourceRange;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vkCmdPipelineBarrier(recordingBuffer, sourceStage, dstStage, 0, 0, nullptr, 0, nullptr, 0, &barrier);
}
这是我复制缓冲区到图像的代码:
void Util::copyBufferToimage(VkCommandBuffer cmdBuffer, VkBuffer buffer,
VkImage *image, uint32_t width, uint32_t height) {
VkBufferImageCopy region{};
VkImageSubresourceLayers subresouce{};
subresouce.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresouce.baseArrayLayer = 0;
subresouce.mipLevel = 0;
subresouce.layerCount = 1;
region.bufferImageHeight = 0;
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.imageOffset = { 0, 0, 0 };
region.imageExtent = { width, height, 1 };
region.imageSubresource = subresouce;
vkCmdCopyBufferToImage(cmdBuffer, buffer, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
}
备注: 我已经尝试 运行 教程的 git 存储库中的项目,并且工作正常。他们没有收到警告。
问题出在我没有提供的顶点结构代码中。纹理坐标格式错误。应该是R32 G32
,我设置成R32 G32 B32 A32
.
static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions() {
std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions = {};
attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions[0].offset = offsetof(Vertex, position);
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[1].offset = offsetof(Vertex, color);
attributeDescriptions[2].binding = 0;
attributeDescriptions[2].location = 2;
attributeDescriptions[2].format = VK_FORMAT_R32G32B32A32_SFLOAT; //This is an error. I guess this has to do something with texCoord being a glm::vec2
attributeDescriptions[2].offset = offsetof(Vertex, texCoord);
return attributeDescriptions;
}
所以,关于纹理坐标的属性描述格式应该是
attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
现在我的多边形看起来像这样: