Occlusion Queries
prepare
- loadAssets: 加载模型(茶壶, 遮挡平面, 球)
- setupQueryPool
- vkCreateQueryPool: 创建一个查询池
- prepareUniformBuffers
- createBuffer: Vertex shader, Teapot, Sphere
- updateUniformBuffers
- uboVS.visible = (passedSamples[0] > 0) ? 1.0f : 0.0f;
- 需要将查询结果存入UniformBuffers
- setupDescriptorSetLayout
- preparePipelines:
- vkCreateGraphicsPipelines: Solid rendering pipeline
- vkCreateGraphicsPipelines: 画遮挡pass
- vkCreateGraphicsPipelines: 绘制, 开启blend
- setupDescriptorPool
- setupDescriptorSets
- buildCommandBuffers
- loop
- vkBeginCommandBuffer
- vkCmdResetQueryPool: 必须在renderpass之前初始化
- vkCmdBeginRenderPass
- vkCmdSetViewport
- scissor
- vkCmdSetScissor
- 遮挡计算pass
- vkCmdBindPipeline:
- vkCmdBindDescriptorSets
- draw: Occluder 遮挡物先绘制
- draw: Teapot
- draw: Sphere
- 显示可见性pass
- vkCmdClearAttachments
- 茶壶
- vkCmdBindPipeline
- vkCmdBindDescriptorSets
- draw
- Sphere
- vkCmdBindDescriptorSets
- draw
- 遮挡物
- vkCmdBindPipeline
- vkCmdBindDescriptorSets
- draw
- vkCmdEndRenderPass
- vkEndCommandBuffer
- loop
render
- draw
- updateUniformBuffers
- getQueryResults
- vkGetQueryPoolResults: 绑定为uniform写入可见性的Samples,在updateUniformBuffers写入
shader
- 绘制遮挡shader没有特殊操作,应该是vulkan根据深度信息自动计算遮挡
- 绘制物体阶段根据uniform 的visible参数判断是否被遮挡
小结
遮挡处理在游戏中应用比较多。工业使用场景感觉还是很少。本节主要讲了QueryPool的使用方法。以后可以开发一下这个池的应用场景。
Pipeline Statistics
prepare
- loadAssets: 加载模型
- setupQueryPool: 创建用于统计的QueryPool
- VkQueryPoolCreateInfo
- VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT
- VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT
- VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT
- VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT
- VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT
- VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT
- VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT
- VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT
- vkCreateQueryPool: 创建查询池
- VkQueryPoolCreateInfo
- prepareUniformBuffers
- updateUniformBuffers
- setupDescriptorSetLayout
- preparePipelines:
- VkPipelineRasterizationStateCreateInfo: 设置面剔除方法
- 开启blend: blendEnable = VK_TRUE;
- 开启discard: rasterizerDiscardEnable = VK_TRUE;
- 开启wireframe模式: polygonMode = VK_POLYGON_MODE_LINE;
- vkCreateGraphicsPipelines: 如果细分开启, shaderStages新增两维用于存放细分阶段shader
- setupDescriptorPool
- setupDescriptorSets
- buildCommandBuffers
- loop
- vkBeginCommandBuffer
- vkCmdResetQueryPool: 必须在renderpass之前初始化
- vkCmdBeginRenderPass
- vkCmdSetViewport
- vkCmdSetScissor
- vkCmdBeginQuery
- vkCmdBindPipeline
- vkCmdBindDescriptorSets
- vkCmdBindVertexBuffers
- vkCmdBindIndexBuffer
- loop
-vkCmdPushConstants - vkCmdEndQuery
- drawUI
- vkCmdEndRenderPass
- vkEndCommandBuffer
- loop
render
- draw
- getQueryResults
- vkGetQueryPoolResult
- getQueryResults
shader
- VS: 正常渲染流程
- TESE: 细分写入阶段
- layout (triangles) in;
- 设置细分顶点位置
- 输出更新的细分顶点的其他属性
- TESC: 细分输出阶段
#version 450 layout (vertices = 3) out; layout (location = 0) in vec3 inNormal[]; layout (location = 1) in vec3 inColor[]; layout (location = 2) in vec3 inViewVec[]; layout (location = 3) in vec3 inLightVec[]; layout (location = 0) out vec3 outNormal[3]; layout (location = 1) out vec3 outColor[3]; layout (location = 2) out vec3 outViewVec[3]; layout (location = 3) out vec3 outLightVec[3]; void main(void) { if (gl_InvocationID == 0) { gl_TessLevelInner[0] = 2.0; gl_TessLevelOuter[0] = 1.0; gl_TessLevelOuter[1] = 1.0; gl_TessLevelOuter[2] = 1.0; } gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; outNormal[gl_InvocationID] = inNormal[gl_InvocationID]; outColor[gl_InvocationID] = inColor[gl_InvocationID]; outViewVec[gl_InvocationID] = inViewVec[gl_InvocationID]; outLightVec[gl_InvocationID] = inLightVec[gl_InvocationID]; }
- FS: 正常渲染阶段
- 注意
- 细分最大支持GL_MAX_PATCH_VERTICES
- 面片的顶点数量默认为3,小于3不产生任何几何图元
- gl_out保存细分后输出的面片
- 细分层次控制生成图元操作,gl_TessLevelInner 和 gl_TessLevelOuter
- gl_TessLevelInner : 表示细分面片的内部区域
- gl_TessLevelOuter: 表示细分面片的外部区域
- 三角形细分使用gl_TessLevelOuter 前三个值
- 三角形细分使用gl_TessLevelInner 第一个值
- 最大值应该只有四个值
- gl_TessLevelInner 和gl_TessLevelOuter数值的大小应该是绘制线的分段数量,越多细分面片越多
- gl_InvocationID应该表示当前是输出图元(PATCH)的id,是gl_out的索引
小结
本节依然介绍QueryPool的其他使用方法, 但是里面增加了细分的功能, 和一些常用渲染模式的设置. QueryPool的确实用性很强。