Vulkan 学习笔记12—深度缓冲

一、3D几何体与深度问题
  1. Z坐标引入
    将2D几何体扩展为3D时,需在Vertex结构体中添加glm::vec3 pos表示三维位置,并更新顶点输入描述符格式为VK_FORMAT_R32G32B32_SFLOAT。顶点着色器需接收3D坐标并通过模型-视图-投影矩阵转换为裁剪坐标。

  2. 深度冲突问题
    当多个3D几何体未按深度排序时,后绘制的片段会覆盖先绘制的片段(如两个正方形因索引顺序导致显示错乱)。解决方案包括:

    • 按从后到前顺序排序绘制调用(适用于透明对象)
    • 使用深度测试和深度缓冲(更常用的方案)
二、深度缓冲实现
  1. 深度图像与视图创建

    • 深度附件基于图像,需手动创建图像、分配内存和视图。
    • 支持格式:
      • VK_FORMAT_D32_SFLOAT(32位浮点深度)
      • VK_FORMAT_D32_SFLOAT_S8_UINT(32位浮点深度+8位模板分量)
      • VK_FORMAT_D24_UNORM_S8_UINT(24位深度+8位模板分量)
        (模板分量用于 模板测试:与深度测试结合使用的附加测试。)
    • 通过findSupportedFormat函数查询设备支持的深度格式,优先选择包含深度模板附件功能的格式。
    VkFormat findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) {for (VkFormat format : candidates) {VkFormatProperties props;vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &props);if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features) {return format;} else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features) {return format;}}throw std::runtime_error("没找到支持的格式!");}
    
  2. 图像布局转换

    • 深度图像需从VK_IMAGE_LAYOUT_UNDEFINED转换为VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
    • 转换时需处理模板分量(若存在),并设置正确的访问掩码和管线阶段。
三、渲染通道与帧缓冲区配置
  1. 渲染通道修改

    • 添加深度附件描述:设置loadOpVK_ATTACHMENT_LOAD_OP_CLEARfinalLayout为深度附件最优布局。
    • 子通道引用深度附件,通过pDepthStencilAttachment字段绑定。
    • 子通道依赖关系需包含深度测试相关的管线阶段(如VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT)。
  2. 帧缓冲区更新

    • 每个帧缓冲区需包含颜色附件和深度附件视图,确保深度图像与交换链图像分辨率一致。
四、深度测试状态配置
  1. 深度模板状态结构体

    • depthTestEnable:启用深度测试,比较新片段与深度缓冲的深度值。
    • depthWriteEnable:允许通过测试的片段更新深度缓冲。
    • depthCompareOp:设置比较操作(如VK_COMPARE_OP_LESS,表示深度值更小的片段更近)。
  2. 清除值设置

    • 深度缓冲初始清除值设为1.0(代表最远深度),通过VkClearValue数组同时指定颜色和深度清除值。
五、窗口大小调整处理
  1. 资源重建逻辑
    • recreateSwapChain函数中,窗口大小变化时重新创建深度资源(图像、视图、帧缓冲区)。
    • 清理旧资源时需释放深度图像内存和视图。
六、关键代码要点
  • GLM投影矩阵配置:使用GLM_FORCE_DEPTH_ZERO_TO_ONE宏确保生成Vulkan兼容的0.0-1.0深度范围。
  • 模板分量处理:若格式包含模板分量(如D24_UNORM_S8_UINT),布局转换和渲染通道需同时处理深度和模板方面。
  • 管线阶段依赖:深度测试发生在VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,深度写入在VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT

通过上述步骤,可在Vulkan中实现正确的深度缓冲机制,解决3D几何体的渲染顺序问题,确保场景深度关系准确。

七、主要代码更新
  • VkContext 新增成员
struct VkContext {...VkImage depthImage;VkDeviceMemory depthImageMemory;VkImageView depthImageView;
}
  • 新增深度资源创建函数
void createDepthResources(VkContext* vkcontext) {VkFormat depthFormat = findDepthFormat(vkcontext->physicalDevice);createImage(vkcontext->physicalDevice,vkcontext->device,vkcontext->swapChainExtent.width,vkcontext->swapChainExtent.height,depthFormat,VK_IMAGE_TILING_OPTIMAL,VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,vkcontext->depthImage,vkcontext->depthImageMemory);vkcontext->depthImageView =createImageView(vkcontext->depthImage, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT, vkcontext->device);}

在 vkInit 函数中调用

// 创建命令池
{...
}// 创建深度资源
createDepthResources(vkcontext);// 创建帧缓冲
...

在重建交换链函数中调用

 void recreateSwapChain(VkContext* vkcontext) {int width = 0, height = 0;glfwGetFramebufferSize(vkcontext->window, &width, &height);while (width == 0 || height == 0) {glfwGetFramebufferSize(vkcontext->window, &width, &height);glfwWaitEvents();}vkDeviceWaitIdle(vkcontext->device);cleanupSwapChain(vkcontext);createSwapChain(vkcontext);createImageViews(vkcontext);createDepthResources(vkcontext); // 创建深度资源createFramebuffers(vkcontext);}

重新构建项目运行效果:
在这里插入图片描述

当前代码分支:10_depth_buffer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/87783.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/87783.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AWS EC2使用SSM会话管理器连接

&#x1f9e9; 前提条件 已创建并运行中的 Amazon EC2 实例&#xff08;Amazon Linux 2023&#xff09; 拥有管理员权限的 AWS 账户 已连接到实例&#xff08;例如通过 EC2 Instance Connect&#xff09; 第一步&#xff1a;手动安装 SSM Agent Amazon Linux 2023 默认未安…

Llama 4 模型卡及提示格式介绍

以下是Llama 4支持的特殊标记和标签的完整列表: 通用标记 <|begin_of_text|>:指定提示符的开始。 <|end_of_text|>:模型将停止生成更多标记。此标记仅由预训练的模型生成。 <|header_start|>…<|header_end|>:这些标记包含特定消息的角色。可能的…

flutter bloc 使用详细解析

源码地址 flutter_bloc 是基于 BLoC&#xff08;Business Logic Component&#xff09;模式的 Flutter 状态管理库&#xff0c;它封装了 bloc package&#xff0c;帮助我们更清晰地组织业务逻辑与 UI 的分离。核心思想是 事件驱动 和 状态响应。 &#x1f9e0; 原理简介 1. 核…

c++ 语言在无人机应用开发中的应用

C 语言在无人机应用开发中扮演着核心角色&#xff0c;特别是在对性能、实时性、资源利用效率和底层硬件控制有严格要求的领域。以下是其主要应用领域&#xff1a; 飞控系统 (Flight Control System - FCS) 核心功能&#xff1a; 这是无人机的大脑。C 用于实现核心的导航、制导与…

Uniapp本地存储(uni.setStorage)全面解析与实践指南

在移动应用开发中&#xff0c;本地存储是不可或缺的核心功能之一。作为跨平台开发框架&#xff0c;Uniapp提供了一套完善的本地存储解决方案&#xff0c;使开发者能够轻松实现数据的持久化存储。本文将深入探讨Uniapp本地存储的方方面面&#xff0c;从基础使用到高级技巧&#…

n8n教程:5分钟部署+自动生AI日报并写入飞书多维表格

哈喽&#xff0c;大家好&#x1f44f; 我是阿星&#xff01; 最近n8n太火了。什么是n8n&#xff1f;有点像扣子和dify的综合体。 简单来说就是替你打工的「自动化工作流」 我们今天就从部署&#x1f449;搭建第一个工作流。用它实现自动抓取新闻并分类。 教程有点长&#x…

禾纳 AET3152AP 电源MOS IC完全替代TDM3307 替代TDM2307泰德电子料 国产芯片

禾纳半导体的电源管理芯片AET3152AP不含卤素和锑&#xff0c;符合Rohs标准&#xff0c;应用在交换机切换&#xff0c;便携式/台式机中的电源管理等&#xff0c;可pin to pin替代TDM3307或TDM2307. AET3152AP 封装为PDFN3030 &#xff0c;最小包装数为5000pcs AET3152AP工作温…

专题:2025信创产业新发展+AI趋势数字化研究报告|附30+份报告PDF汇总下载

原文链接&#xff1a;https://tecdat.cn/?p42711 本报告汇总解读聚焦信创产业核心发展脉络&#xff0c;以数据驱动视角剖析技术演进与市场变革。信创产业作为国家数字安全与技术自主可控的核心载体&#xff0c;正经历从“可用”到“好用”的关键跃迁。 本报告洞察基于《亿欧智…

电子电气架构 --- 分区电子电气架构如何支持软件定义汽车

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

【简单】344.反转字符串

题目描述 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 示例 1&#xff1a; 输入&#xff1a;s ["h&quo…

CVE-2025-24813源码分析与漏洞复现(Tomcat 路径等效漏洞与反序列化RCE)

漏洞概述 漏洞名称&#xff1a;Tomcat 路径等效漏洞反序列化远程代码执行&#xff08;RCE&#xff09; CVE 编号&#xff1a;CVE-2025-24813 CVSS 评分&#xff1a;9.8 影响版本&#xff1a; 9.0.0.M1 ≤ Tomcat ≤ 9.0.9810.1.0-M1 ≤ Tomcat ≤ 10.1.3411.0.0-M1 ≤ Tomcat…

深入解析:如何实时获取Socket接收缓冲区的数据量

在网络编程中&#xff0c;精确掌握接收缓冲区的数据状态是优化性能的关键。本文将揭秘如何跨平台获取socket接收缓冲区的可读数据量&#xff0c;并分析实际应用中的注意事项。 一、核心API&#xff1a;操作系统级数据探针 1. Windows平台方案 #include <winsock2.h>// …

Edge卸载应用

Edge安装应用后&#xff0c;出现在开始菜单&#xff0c;不能卸载。

Cursor Rules 的核心定位与作用

Cursor Rules 是 AI 编程工具 Cursor IDE 中的核心功能&#xff0c;用于约束 AI 生成代码的行为&#xff0c;确保其符合项目规范、编码风格或特定技术需求。它本质上是一套持久化、可复用的指令集&#xff0c;会动态插入到 AI 模型的上下文提示中&#xff0c;指导其生成代码的逻…

多线程爬虫优化:快速爬取并写入CSV

在数据驱动的时代&#xff0c;爬虫技术已成为获取网络数据的重要手段。然而&#xff0c;随着数据量的不断增加&#xff0c;单线程爬虫的效率逐渐难以满足需求。多线程爬虫通过并行处理&#xff0c;能够显著提升爬取速度&#xff0c;同时将数据快速写入CSV文件&#xff0c;为后续…

Deepseek+墨刀,1min快速生成流程图!

想要了解快速了解产品逻辑&#xff0c;可以用ds墨刀快速生成流程图~ deepseek链接&#xff1a;https://www.deepseek.com/ 墨刀在线&#xff1a;https://modao.cc/brand 如何操作呢&#xff1f; 1.打开deepseek&#xff0c;输入以下咒语&#xff0c;让AI用Mermaid语法绘制流…

LangChain4j流式调用、消息注解与会话记忆

我们先用AiService工具类把调用ai大语言模型的代码写出来。因为AiService工具类中整合有记忆、Rag知识库、tools工具等&#xff0c;我们直接配置调用即可。 我用的是qwen-plus模型。 引入依赖&#xff1a; <dependency><groupId>dev.langchain4j</groupId>…

NtfsWriteLog函数分析之OpenAttributeTableDump

第一部分&#xff1a; NtfsWriteLog( IrpContext, Vcb->MftScb, //注意&#xff1a;Vcb->MftScb NULL, OpenAttributeTableDump, …

DCM4CHEE ARCHIVE LIGHT 源代码解析(2)-STOWRS

系列文章目录 DCM4CHEE ARCHIVE LIGHT 源代码解析(1)-前言DCM4CHEE ARCHIVE LIGHT 源代码解析(2)-STOWRS文章目录 系列文章目录概述一、背景资料1、RESTful服务2、传输存储规范3、服务连接策略4、响应消息状态二、业务分析1、对象关系2、项目结构3、业务流程三、代码解析1、w…

Java中间件简介:构建现代软件的“隐形桥梁”

Java中间件简介&#xff1a;构建现代软件的“隐形桥梁” 在软件开发的世界里&#xff0c;中间件&#xff08;Middleware&#xff09;是一个既熟悉又神秘的存在。它不像数据库那样直接存储数据&#xff0c;也不像前端那样与用户交互&#xff0c;但它却是现代软件架构中不可或缺…