VulkanTutorial(17`Loading models, Mipmaps)

Loading models

我们将使用tinyobjloader库从OBJ文件加载顶点和索引,它速度快,易于集成,因为它是一个像stb_image一样的单一文件库
因为我们没有学习光照,使用照明烘焙的纹理
在程序中添加两个新的配置变量来定义模型和纹理路径:
并更新createTextureImage 以使用此路径变量加载纹理数据

Loading vertices and indices

模型加载和简单的图形没什么太大区别,主要就是vertices and indices的变更
我们现在要从模型文件中加载顶点和索引,所以你现在应该删除全局顶点和索引数组。将它们替换为非常量容器作为类成员
因为这次的索引很多,因此将索引的类型从uint16_t改为uint32_t,也不要忘记更改vkCmdBindIndexBuffer中的类型

LoadObj

包含tiny_obj_loader.h文件
添加新的loadModel函数,通过
if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, MODEL_PATH.c_str()))
加载模型路径,获取所有的顶点和索引数据,放到刚刚的vertices and indices数据结构中
OBJ文件由位置、法线、纹理坐标和面组成

  • attrib容器包括attrib.vertices、attrib.normals和attrib.texcoords的属性
  • shapes包含所有单独的面(每个面有三个顶点),每个面由一个顶点数组组成,每个顶点包含位置、法线和纹理坐标属性的索引
  • materials材质
  • err字符串包含错误
  • warn字符串包含加载文件时发生的警告

我们要循环所有的shapes对象,以便循环所有的对象网格索引shape.mesh.indices,以便查找attrib数组中的实际顶点属性:
shape.mesh.indices其中包含vertex_index、normal_index和texcoord_index成员的索引(首个顶点索引,3个顶点依次递增),还需要将索引乘以3(因为存储顺序可能是x0, x1, x2, y0, y1, y2, z0, z1, z2…
但是还有一个问题,OBJ格式假设一个坐标系,其中垂直坐标为0表示图像的底部,但是到Vulkan中,其中0表示图像的顶部,因此通过翻转纹理坐标的垂直分量来解决此问题
在这里插入图片描述

Mipmaps

多级贴图 / 多级渐远纹理,每个新图像的宽度和高度都是前一个图像的一半,Mipmap用作细节级别或LOD(细节级别)的一种形式。远离相机的物体将从较小的mip图像中采样其纹理。使用较小的图像可提高渲染速度并避免摩尔纹等伪影

miplevels

首先指定miplevels的级别数量,这个值是根据图像的尺寸计算,在stbi_load获得了(texWidth, texHeight)之后计算
mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(texWidth, texHeight)))) + 1;
max函数选择最大的维度。log2函数计算该维度可以被2整除的次数。floor函数处理最大维度不是2的幂的情况。1,使得原始图像具有mip级别
我们需要更改mip Image、mip ImageView和transitionImageLayout函数,将miplevels作为参数,并更改内部info的levelCount成员,以及所有调用这些函数的地方(对textureImage使用mipLevels ,对depthimage使用1)
这样image缓冲中就可以存储所有mip级别图像

Generating Mipmaps

我们的暂存stagingBuffer只能通过vkCmdCopyBufferToImage填充miplevels== 0 的纹理层,对于其他级别需要调用vkCmdBlitImage(位块传输)命令执行复制、缩放和筛选操作,以便将数据传输到纹理图像的每一层
我们现在打算从miplevels==0级别的纹理传输到其他级别图像中,因此要指定VK_IMAGE_USAGE_TRANSFER_SRC_BIT 标志
我们依旧要考虑图像转换时的布局,但这次不再是一个图像转换,要考虑miplevels个图像转换,因此我们需要编写更多的vkCmdPipelineBarrier命令转换每个图像以便被着色器使用,
删除现有到 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL的transitionImageLayout过渡,编写新的生成mipmaps的函数
对于VkImageMemoryBarrier结构体的部分成员,每次转换都保持不变,因此不需要放在for中,subresourceRange.miplevel、oldLayout、newLayout、srcallbackMask和dstallback Mask将针对每个转换进行更改(i从1开始)

实例

我们举例miplevels == 0时:
首先通过vkCmdPipelineBarrier命令将布局转换为VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,它可以等待从上一个vkCmdBlitImage命令或从vkCmdCopyBufferToImage填充(转换为源可以填充DST)
接下来创建VkImageBlit

  • 源mip级别是i - 1,目的地mip级别是i
  • srcOffsets数组的两个元素决定了数据将从哪个3D区域进行位块传输,{ mipWidth, mipHeight, 1 };
  • dstOffsets确定数据将被传输到的区域,dstOffsets[1]的X和Y维度被除以2,因为每个mip级别是前一级别大小的一半 { mipWidth > 1 ? mipWidth / 2 : 1, mipHeight > 1 ? mipHeight / 2 : 1, 1 };
  • 其中Z维度必须为1,因为2D图像的深度为1

使用vkCmdBlitImage命令传输数据,srcImage和dstImage的布局分别为SRC和DST(刚才转换的布局),最后一个参数时filter过滤选项
再次使用vkCmdPipelineBarrier命令将布局转换为VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,以便供着色器使用
在每次循环结束,我们将当前的mip维度除以2,除法之前检查每个维度,以确保维度永远不会小于1
在for结束之前,我们再插入一个vkCmdPipelineBarrier转换为 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 。这不是由循环处理的,因为最后一个mip级别永远不会被blitted。

Linear filtering support

使用vkCmdBlitImage内置函数来生成所有的mip级别不能保证在所有平台上都支持它,需要图像格式支持线性过滤
vkGetPhysicalDeviceFormatProperties获取图像格式(包括3种linearTilingFeatures、optimalTilingFeatures和bufferFeatures),对线性过滤功能的支持可以使用 optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT 检查

Sampler

当VkImage缓冲保存mipmap数据时,VkSampler控制渲染时如何读取该数据允许我们指定,修改VkSamplerCreateInfo结构体成员
如果mipmapMode为 VK_SAMPLER_MIPMAP_MODE_NEAREST,则采样一个mip级别,如果mipmap模式为VK_SAMPLER_MIPMAP_MODE_LINEAR,则采样的两个mip级别,并将结果线性混合
如果对象靠近相机,则使用magFilter作为滤镜。如果对象距离相机较远,则使用minFilter
mipLodBias允许我们强制Vulkan使用比正常情况下更低的lod和level
samplerInfo.minLod = static_cast< float >(mipLevels / 2);
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

DAO模式的理解

目录 DAO模式 含义 DAO模式 的理解 分层思维 分层含义 分层目的 dao层 dao包&#xff08;对接的是操作数据库的接口&#xff09; dao包下lmpl 包&#xff08;dao包中接口的实现类&#xff09; 补充 1 你创建的实体类需要和数据库中建的表一一对应。 总结 DAO模式 含义…

大健康零售行业帮助中心的构建与客户服务优化

在大健康零售行业&#xff0c;客户服务的质量直接影响着企业的品牌形象和市场竞争力。随着数字化转型的推进&#xff0c;构建一个高效、智能的帮助中心成为了提升客户服务和满意度的关键。本文将分析大健康零售行业如何通过构建帮助中心来优化客户服务&#xff0c;并提升客户满…

【JWT】Asp.Net Core中JWT刷新Token解决方案

Asp.Net Core中JWT刷新Token解决方案 前言方案一:当我们操作某个需要token作为请求头的接口时,返回的数据错误error.response.status === 401,说明我们的token已经过期了。方案二:实现用户无感知的刷新token值,我们希望当响应返回的数据是401身份过期时,响应阻拦器自动帮我…

Error: error:0308010C:digital envelope routines::unsupported

目录 1、前言2、详细问题3、解决方法3.1、nodejs版本降级3.2、针对openssl设置环境变量3.3、在package.json命令里添加设置 4、效果 1、前言 2024年11月某一天&#xff0c;升级了电脑上的nodejs版本&#xff1a;v22.11.0。 本来运行正常的Vue项目&#xff0c;在运行时突然就报…

win10@win10 配置openssh服务

1.下载离线包&#xff1a;https://github.com/PowerShell/Win32-OpenSSH/releases 2.然后管理员打开powershell&#xff0c;cd到这个安装包放置的目录中来&#xff0c;输入以下命令&#xff1a;powershell.exe -ExecutionPolicy Bypass -File install-sshd.ps1 此时要注意pow…

优化SEO关键词提升网站曝光度的有效策略

内容概要 在当今数字营销领域&#xff0c;SEO关键词优化的重要性愈发凸显。有效的关键词优化不仅关乎搜索引擎排名&#xff0c;还直接影响到网站的曝光度与流量来源。首先&#xff0c;明确目标受众在搜索引擎中使用的关键词是提高网站能见度的基石。正确的关键词可以帮助网站吸…

Git 不要只会 pull 和 push,搞上 5 个提升效率的命令!

文章目录 Git 不要只会 pull 和 push&#xff0c;搞上 5 个提升效率的命令&#xff01;1. git stash —— 暂存修改&#xff0c;快速切换分支2. git cherry-pick —— 单独拣选特定提交3. git rebase —— 整理提交历史&#xff0c;让提交记录更清晰4. git reset —— 恢复到指…

ONLYOFFICE 快速部署教程:让你的私有云盘也可以预览和编辑 Office 文档

ONLYOFFICE Docs (原 ONLYOFFICE Document Server) 是一款强大的开源在线办公套件&#xff0c;包含用于文本、电子表格和演示文稿的查看器和编辑器&#xff0c;完全兼容 Office Open XML 格式&#xff08;.docx、.xlsx、.pptx&#xff09;&#xff0c;并支持实时协作编辑。本文…

【ESP32】ESP-IDF开发 | 低功耗管理+RTC唤醒和按键唤醒例程

1. 简介 ESP32支持5种低功耗模式&#xff0c;低功耗管理单元包括调压器、功耗控制器、电源开关单元、电源域隔离单元 (Isolation Cell) 等部分。 1.1 RTC单元 RTC单元是ESP32低功耗管理的核心&#xff0c;可用于管理低功耗模式的进入和退出&#xff0c;控制时钟源、PLL、电源开…

SQLite的BLOB数据类型与C++二进制存储学习记录

一、BLOB数据类型简介 Blob&#xff08;Binary Large Object&#xff09;是一种用于存储二进制数据的数据类型&#xff0c;在数据库中常用于存储图片、音频和视频等大型&#xff08;大数据量&#xff09;的二进制数据[1-2]。需要注意的是&#xff0c;SQLite中BLOB类型的单对象最…

如何利用低代码平台进行创业?开启你的数字化转型之旅

在当今这个飞速发展的数字化时代&#xff0c;低代码开发已经成为企业加速业务流程、提升运营效率的关键手段之一。它不仅简化了软件开发过程&#xff0c;使得非技术人员也能参与到应用程序的构建中来&#xff0c;还为企业和个人提供了更加灵活、高效的创业路径。本文将探讨如何…

从0开始深度学习(28)——序列模型

序列模型是指一类特别设计来处理序列数据的神经网络模型。序列数据指的是数据中的每个元素都有先后顺序&#xff0c;比如时间序列数据&#xff08;股票价格、天气变化等&#xff09;、自然语言文本&#xff08;句子中的单词顺序&#xff09;、语音信号等。 1 统计工具 前面介绍…

Xcode无线真机调试

文章目录 Xcode无线真机调试前提条件无线真机调试 Xcode无线真机调试 前提条件 iPhone和Xcode连接在同一WIFI下&#xff1b;或 Xcode通过iPhone的IP地址进行连接&#xff1b;Xcode版本支持无线调试功能&#xff1b; 无线真机调试 首次使用&#xff0c;需要通过数据线连接MAC…

暴雨讲堂|AI算力芯片王者GPGPU是什么?

在AI飞速发展的这几年&#xff0c;市场上涌现一大批诸如DPU、NPU、TPU、IPU等“XPU”的新概念&#xff0c;是真的存在不同的架构&#xff0c;还是只是一些厂商营销出来的噱头&#xff1f;事实上&#xff0c;从CPU的发展角度来看&#xff0c;这些XPU都不是真正的处理器。相反&am…

行车记录打不开?原因分析与数据恢复全攻略

行车记录遭遇困境 行车记录仪&#xff0c;作为现代驾驶中的重要设备&#xff0c;不仅能够帮助我们记录行车过程&#xff0c;还能在关键时刻提供有力的证据。然而&#xff0c;当行车记录突然打不开时&#xff0c;这无疑给车主们带来了不小的困扰。行车记录打不开&#xff0c;可…

SpringMVC总结 我的学习笔记

SpringMVC总结 我的学习笔记 一、SpringMVC简介1.MVC2.SpringMVC概述3. SpringMVC中的核心组件4.SpringMVC核心架构流程 二、SpringMVC框架实例具体实现使用注解实现 四、数据处理及跳转1.结果跳转方式2.处理器方法的参数与返回值处理提交数据数据显示到前端 五、RestFul风格1.…

云计算基础1

声明 学习视频来自B站UP主泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 云计算基础概念 一、云计算的定义 云计算是一种资源交付和使用模式&#xff0c;指通过网络获得应用所需的…

Guava限流神器:RateLimiter使用指南

1. 引言 可能有些小伙伴听到“限流”这个词就觉得头大&#xff0c;感觉像是一个既复杂又枯燥的话题。别急&#xff0c;小黑今天就要用轻松易懂的方式&#xff0c;带咱们一探RateLimiter的究竟。 想象一下&#xff0c;当你去超市排队结账时&#xff0c;如果收银台开得越多&#…

被复线远传节点机JR-IPAM-1600

产品描述 JR-IPAM-1600J是一款被复线远传节点机&#xff0c;通过传统双绞线电缆&#xff08;被复线\网线\对数电缆\矿用电缆等&#xff09;&#xff0c;用户就可以快速组成一个高速的传输网、局域网。它具有传输速率高、运行稳定、快速安装部署的特点&#xff0c;设备特有的AU…

【React】React 生命周期完全指南

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 React 生命周期完全指南一、生命周期概述二、生命周期的三个阶段2.1 挂载阶段&a…