- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试对图像阵列进行一些分层渲染,并在屏幕上显示其中一层。但无论我做什么,只有第一层被正确渲染和显示,每次我尝试显示第一层以外的另一层时,我除了黑屏什么也得不到。所以我尝试打包大部分必要的信息,希望有人能发现我的错误。
首先,我用这些参数创建了一个图像:
VkImageCreateInfo info{};
info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
info.imageType = VK_IMAGE_TYPE_2D;
info.format = VK_FORMAT_R8G8B8A8_UNORM;
info.extent = { WindowWidth, WindowHeight, 1 };
info.mipLevels = 1;
info.arrayLayers = 6;
info.samples = VK_SAMPLE_COUNT_1_BIT;
info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImage myImage = createImage(info);
我省略了整个内存分配和绑定(bind)体操,因为我认为它在这里不相关。
然后,我使用了两个 ImageView :- 具有整个 {0, 6} 层范围的一个,将用于几何着色器中的层渲染- 另一个只有一层,将用于在我选择的给定层获取数据
这是我创建它们的方式:
VkImageViewCreateInfo info{};
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
info.image = myImage;
info.viewType = VK_IMAGE_VIEW_TYPE_2D;
info.format = VK_FORMAT_R8G8B8A8_UNORM;
info.components = Identity;
info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
info.subresourceRange.baseMipLevel = 0;
info.subresourceRange.levelCount = 1;
info.subresourceRange.baseArrayLayer = 0;
info.subresourceRange.layerCount = 6;
VkImageView imageView6Layers = createImageView(info);
VkImageViewCreateInfo info2 = info;
info2.subresourceRange.baseArrayLayer = 1; // Target the layer 1 for example
info2.subresourceRange.layerCount = 1;
VkImageView imageView1Layer = createImageView(info2);
至此,我已经构建了两个渲染 channel 来划分流程:
首先使用第一个 ImageView ,使用几何着色器在一次绘制调用中渲染所有图像层
第二个从第二个 ImageView 中获取数据,并将它们输出到交换链图像
这是第一个渲染 channel (用于分层渲染):
// 6 layers image view
VkAttachmentDescription attachment{};
attachment.format = VK_FORMAT_R8G8B8A8_UNORM;
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference colorAttachment{};
colorAttachment.attachment = 0;
colorAttachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass{};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachment;
VkRenderPassCreateInfo info{};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.attachmentCount = 1;
info.pAttachments = &attachment;
info.subpassCount = 1;
info.pSubpasses = &subpass;
VkRenderPass renderPass6Layers = createRenderPass(info);
这是第二个渲染过程(获取数据,并将其输出到交换链图像):
VkAttachmentDescription attachments[2]{};
// Swapchain image
attachments[0].format = swpachainImageFormat;
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
// 1 layer image view
attachments[1].format = VK_FORMAT_R8G8B8A8_UNORM;
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
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_SHADER_READ_ONLY_OPTIMAL;
attachments[1].finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VkAttachmentReference colorAttachment{};
colorAttachment.attachment = 0;
colorAttachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference inputAttachment{};
inputAttachment.attachment = 1;
inputAttachment.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VkSubpassDescription subpass{};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachment;
subpass.inputAttachmentCount = 1;
subpass.pInputAttachments = &inputAttachment;
VkRenderPassCreateInfo info{};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.attachmentCount = 2;
info.pAttachments = attachments;
info.subpassCount = 1;
info.pSubpasses = &subpass;
VkRenderPass renderPass1Layer = createRenderPass(info);
然后是第一个子 channel 中使用的着色器:
顶点着色器:
#version 450
layout (location = 0) in vec3 iModelPos;
void main()
{
gl_Position = vec4(iModelPos, 1);
}
几何着色器:
#version 450
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
void main()
{
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < gl_in.length(); j++)
{
gl_Layer = i;
// Assume I have everything necessary to compute the matrix
gl_Position = PVM * gl_in[j].gl_Position;
EmitVertex();
}
EndPrimitive();
}
}
片段着色器:
#version 450
layout (location = 0) out vec4 oColor;
void main()
{
oColor = vec4(1,1,1,1);
}
第二个子 channel 中使用的着色器:
顶点着色器(简单地在整个屏幕上输出一个四边形):
#version 450
layout (location = 0) in vec3 iModelPos;
void main()
{
gl_Position = vec4(iModelPos, 1);
}
片段着色器(在图像层中获取数据):
#version 450
// Assume it's bound here
layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput ImageLayer;
layout (location = 0) out vec4 oColor;
void main()
{
oColor = subpassLoad(ImageLayer);
}
最后是我的 main 的样子:
int main(void)
{
/* ... */
{
VkCommandBufferBeginInfo info{};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(cmdBuffer, &info);
}
VkFramebuffer framebuffer6Layers{}
{
VkFramebufferCreateInfo info{};
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
info.renderPass = renderPass6Layers;
info.attachmentCount = 1;
info.pAttachments = &imageView6Layers;
info.width = WindowWidth;
info.height = WindowHeight;
info.layers = 6;
framebuffer6Layers = createFramebuffer(info);
}
{
VkClearValue clearValues = {0,0,0,1};
VkRenderPassBeginInfo info{};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.renderPass = renderPass6Layers;
info.framebuffer = framebuffer6Layers;
info.renderArea = { WindowWidth, WindowHeight };
info.clearValueCount = 1;
info.pClearValues = &clearValues;
vkCmdBeginRenderPass(cmdBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
}
/* binds */
vkCmdDraw(cmdBuffer, objectVertices.count(), 1, 0, 0);
vkCmdEndRenderPass(cmdBuffer);
vkEndCommandBuffer(cmdBuffer);
/* submit cmdBuffer and wait for rendering to finish */
{
VkCommandBufferBeginInfo info{};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(cmdBuffer, &info);
}
{
VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.image = myImage;
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 6;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1;
vkCmdPipelineBarrier(cmdBuffer,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
0,
0, nullptr,
0, nullptr,
1, &barrier);
}
VkFramebuffer framebuffer1Layer{};
{
VkImageView attachments[2]{};
attachments[0] = swapchainImageView;
attachments[1] = imageView1Layer;
VkFramebufferCreateInfo info{};
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
info.renderPass = renderPass1Layer;
info.attachmentCount = 2;
info.pAttachments = attachments;
info.width = WindowWidth;
info.height = WindowHeight;
info.layers = 1;
framebuffer1Layer = createFramebuffer(info);
}
{
VkClearValue clearValues = {0,0,0,1};
VkRenderPassBeginInfo info{};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.renderPass = renderPass1Layer;
info.framebuffer = framebuffer1Layer;
info.renderArea = { WindowWidth, WindowHeight };
info.clearValueCount = 1;
info.pClearValues = &clearValues;
vkCmdBeginRenderPass(cmdBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
}
/* binds */
vkCmdDraw(quadVertices.count(), 1, 0, 0);
vkCmdEndRenderPass(cmdBuffer);
vkEndCommandBuffer(cmdBuffer);
/* submit cmdBuffer, wait for rendering to finish and present the swapchain image */
/* ... */
}
我没有包括一些信息,比如帧缓冲区的创建。感觉自己已经给出了很多信息,希望有人能指点一下哪里不对,或者给点提示。
验证层正在运行,不会输出任何内容。
我发现出于某些原因,我实际上总是只创建一个层的帧缓冲区,这解释了为什么验证层从不提示。
为了在帧缓冲区中使用正确的层数,我将过程分为两个渲染过程,并在两者之间添加了一个图像屏障(参见上面编辑的过程)。然而,这并没有解决问题,当我尝试显示另一个图像层而不是第一个图像层时,我仍然有黑屏,而在显示第一个层时,结果是正确的。
验证层现在也没有提示,我按要求添加了帧缓冲区创建细节。
我尝试使用组合图像采样器统一代替输入附件,但没有成功。当我尝试显示第一层时它仍然有效,但我从其他层得到相同的黑屏。
我从第二个渲染过程中删除了附件并因此更新了内存屏障。
这是第二个渲染 channel 的更新:
// Swapchain image
VkAttachmentDescription attachment{};
attachment.format = swpachainImageFormat;
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
VkAttachmentReference colorAttachment{};
colorAttachment.attachment = 0;
colorAttachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass{};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachment;
VkRenderPassCreateInfo info{};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.attachmentCount = 1;
info.pAttachments = &attachment;
info.subpassCount = 1;
info.pSubpasses = &subpass;
VkRenderPass renderPass1Layer = createRenderPass(info);
这是新的片段着色器:
// Assume it's bound here
layout (set = 0, binding = 0) uniform sampler2D ImageLayer;
layout (location = 0) out vec4 oColor;
void main()
{
// Assume that I have the viewport from an uniform buffer.
const vec2 uv = gl_FragCoord.xy / Viewport;
oColor = texture(ImageLayer, uv);
}
uv 值是正确的,当我尝试输出 vec4(uv, 0, 1) 时,我在屏幕上得到了预期的颜色,对于我尝试显示的每个图像层:
黑色,红色,
绿色、黄色
这是图像屏障的变化:
barrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT;
还有一些更改,例如图像使用标志或描述符集布局,但我没有在此处包含它们。
最佳答案
我终于弄清楚出了什么问题。
layout (triangle_strip, max_vertices = 3) out;
我的几何着色器中的这条线导致了第三个顶点之后的其他顶点默默地丢弃。因此,我的着色器能够写入的唯一层是第一个层。
我已经解决了这样的问题:
布局(triangle_strip, max_vertices = 18);
我想在 6 层上绘制一个三角形(3 个顶点),因此 max_vertices = 3 x 6 = 18。
另一个问题在我的编辑 3 中解决了。我的帧缓冲区只创建了一层而不是所需的 6 层,这使得几何着色器静默专门写入第一层。似乎当您尝试在大于您在帧缓冲区中提供的层数的层上写入时,着色器会自动在层 0 上写入。
关于c++ - 使用几何着色器进行图层渲染似乎只输出图像数组的第一层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57651415/
我正在使用 OUTFILE 命令,但由于权限问题和安全风险,我想将 shell 的输出转储到文件中,但出现了一些错误。我试过的 #This is a simple shell to connect t
我刚刚开始学习 Java,我想克服在尝试为这个“问题”创建 Java 程序时出现的障碍。这是我必须创建一个程序来解决的问题: Tandy 喜欢分发糖果,但只有 n 颗糖果。对于她给第 i 个糖果的人,
你好,我想知道我是否可以得到一些帮助来解决我在 C++ 中打印出 vector 内容的问题 我试图以特定顺序在一个或两个函数调用中输出一个类的所有变量。但是我在遍历 vector 时收到一个奇怪的错误
我正在将 intellij (2019.1.1) 用于 java gradle (5.4.1) 项目,并使用 lombok (1.18.6) 来自动生成代码。 Intellij 将生成的源放在 out
编辑:在与 guest271314 交流后,我意识到问题的措辞(在我的问题正文中)可能具有误导性。我保留了旧版本并更好地改写了新版本 背景: 从远程服务器获取 JSON 时,响应 header 包含一
我的问题可能有点令人困惑。我遇到的问题是我正在使用来自 Java 的 StoredProcedureCall 调用过程,例如: StoredProcedureCall call = new Store
在我使用的一些IDL中,我注意到在方法中标记返回值有2个约定-[in, out]和[out, retval]。 当存在多个返回值时,似乎使用了[in, out],例如: HRESULT MyMetho
当我查看 gar -h 的帮助输出时,它告诉我: [...] gar: supported targets: elf64-x86-64 elf32-i386 a.out-i386-linux [...
我想循环遍历一个列表,并以 HTML 格式打印其中的一部分,以代码格式打印其中的一部分。所以更准确地说:我想产生与这相同的输出 1 is a great number 2 is a great
我有下面的tekton管道,并尝试在Google Cloud上运行。集群角色绑定。集群角色。该服务帐户具有以下权限。。例外。不确定需要为服务帐户设置什么权限。
当尝试从 make 过滤非常长的输出以获取特定警告或错误消息时,第一个想法是这样的: $ make | grep -i 'warning: someone set up us the bomb' 然而
我正在创建一个抽象工具类,该类对另一组外部类(不受我控制)进行操作。外部类在某些接口(interface)点概念上相似,但访问它们相似属性的语法不同。它们还具有不同的语法来应用工具操作的结果。我创建了
这个问题已经有答案了: What do numbers starting with 0 mean in python? (9 个回答) 已关闭 7 年前。 在我的代码中使用按位与运算符 (&) 时,我
我写了这段代码来解析输入文件中的行输入格式:电影 ID 可以有多个条目,所以我们应该计算平均值输出:**没有重复(这是问题所在) import re f = open("ratings2.txt",
我需要处理超过 1000 万个光谱数据集。数据结构如下:大约有 1000 个 .fits(.fits 是某种数据存储格式)文件,每个文件包含大约 600-1000 个光谱,其中每个光谱中有大约 450
我编写了一个简单的 C 程序,它读取一个文件并生成一个包含每个单词及其出现频率的表格。 该程序有效,我已经能够在 Linux 上运行的终端中获得显示的输出,但是,我不确定如何获得生成的显示以生成包含词
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
1.普通的输出: print(str)#str是任意一个字符串,数字··· 2.格式化输出: ?
我无法让 logstash 正常工作。 Basic logstash Example作品。但后来我与 Advanced Pipeline Example 作斗争.也许这也可能是 Elasticsear
这是我想要做的: 我想让用户给我的程序一些声音数据(通过麦克风输入),然后保持 250 毫秒,然后通过扬声器输出。 我已经使用 Java Sound API 做到了这一点。问题是它有点慢。从发出声音到
我是一名优秀的程序员,十分优秀!