VulkanTutorial(8·Shader modules)

Shader modules

与早期的API不同,Vulkan中的着色器代码必须以字节码格式指定,而不是人类可读的语法,如GLSL和HLSL。这种字节码格式称为SPIR-V它是一种可用于编写图形和计算着色器的格式

使用像SPIR-V这样简单的字节码格式,不会面临其他供应商的驱动程序因语法错误而拒绝您的代码的风险,

SPIR-V二进制文件,并不意味着我们需要手工编写,Khronos已经发布了他们自己的独立于供应商的glslangValidator.exe编译器,该编译器将GLSL编译为SPIR-V

但我们将使用Google的glslc.exe,glslc的优点是它使用与GCC和Clang等知名编译器相同的参数格式,并且这两个工具都已包含在Vulkan SDK中,因此您无需下载任何额外的内容。

GLSL是一种具有C风格语法的着色语言。用它编写的程序有一个main函数,GLSL使用全局变量来处理输入和输出,而不是使用参数作为输入和返回值作为输出,该语言包括内置的矢量和矩阵处理功能

Vertex shader

顶点着色器处理每个传入的顶点。它将其属性,如position, color, normal and texture coordinates作为输入。输出是clip coordinate裁剪坐标中的最终位置以及需要传递给片段着色器的属性,这些值然后将被光栅化器在片段上插值以产生 smooth平滑的梯度

clip coordinate裁剪坐标(单位立方体)是来自顶点着色器的四维向量,随后通过将整个向量除以其最后一个分量w来将其转换为规范化的设备坐标(单位正方形)->屏幕坐标(长方形)

左边时帧缓冲坐标(像素坐标),右边时标准化设备坐标,它和opengl 不同,y坐标是相反的,z坐标的范围仅是0---1

对于我们的第一个三角形,我们将直接指定三个顶点的位置作为归一化的设备坐标

通常情况下,这些坐标或者其他顶点属性将存储在顶点缓冲区中,但在Vulkan中创建顶点缓冲区并填充数据并非易事

文件

在vs中新建.vert和.frag的后缀名文件(可以任意取)

首先指明#version的glsl版本

创建元素数量为3的vec2二维向量类型的位置数组,和颜色数组

每个顶点都会调用main()函数,内置的gl_VertexIndex变量包含当前顶点的索引,我们通过positions[gl_VertexIndex]去从数组访问顶点的位置,

并传入w分量,通过内置变量gl_Position用作vertex shader的输出

需要通过out将顶点颜色属性传给fragment shader,并在fragment shader中in匹配输入(不必同名只要location索引一致就行)

#version 450

layout(location = 0) out vec3 fragColor;

vec2 positions[3] = vec2[](
    vec2(0.0, -0.5),
    vec2(0.5, 0.5),
    vec2(-0.5, 0.5)
);

vec3 colors[3] = vec3[](
    vec3(1.0, 0.0, 0.0),
    vec3(0.0, 1.0, 0.0),
    vec3(0.0, 0.0, 1.0)
);

void main() {
    gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
    fragColor = colors[gl_VertexIndex];
}

fragment shader

 用fragment 填充屏幕上的区域,在这些fragment上调用fragment shader以产生frambuffer的color and depth

main函数会为每个片段调用,就像顶点着色器main函数会为每个顶点调用一样

没有内置变量来输出当前计算的颜色(GLSL中的颜色是4分量向量),必须为每个frambuffer指定自己的输出变量,比如这里的outColor

其中layout(location = 0)布局修饰符指定frambuffer的索引

fragColor的值将自动为三个顶点之间的片段插值,从而产生平滑的颜色渐变

#version 450

layout(location = 0) in vec3 fragColor;

layout(location = 0) out vec4 outColor;

void main() {
    outColor = vec4(fragColor, 1.0);
}

 编译为SPIR_V字节码

我们现在将使用glslc程序将这些代码编译成SPIR-V字节码

首先创建一个bat文件(批处理文件),并将它放在你的shader文件夹下,

在其中写入,保存后,双击运行,至此我们的目录下就编译完成了spv文件

这两个命令告诉glslc编译器读取GLSL源文件,并使用-o(输出)标志输出SPIR-V字节码文件

如果着色器包含语法错误,那么编译器将告诉您行号和问题

在命令行上编译着色器是最简单的选项之一,但是也可以用Vulkan SDK的libshaderc,这是一个用于从程序中将GLSL代码编译为SPIR-V的库

……/glslc.exe …….vert -o vert.spv
……/glslc.exe …….frag -o frag.spv
pause

加载SPIR-V到程序中

在是时候将它们加载到我们的程序中,以便在某个时候将它们插入graphics pipeline 

编写一个简单的readFile函数来从文件中加载二进制数据

对于输入流对象,我们指定两个标志

  • ate:从文件末尾开始阅读(我们可以使用读取位置来确定文件的tellg()大小并分配缓冲区)
  • binary:将文件读取为二进制文件(避免文本转换)

将读取的内容返回到由std::vector管理的字节数组中

static std::vector<char> readFile(const std::string& filename) {
    std::ifstream file(filename, std::ios::ate | std::ios::binary);//文件输入流

    if (!file.is_open()) {
        throw std::runtime_error("failed to open file!");
    }

    size_t fileSize = (size_t)file.tellg();
    std::vector<char> buffer(fileSize);//读取到的字节数组缓冲

    file.seekg(0);
    file.read(buffer.data(), fileSize);

    file.close();

    return buffer;
}

在createGraphicsPipeline调用函数来加载两个着色器的字节码、

创建Shader modules

在将SPIR-V的字节码传递到pipeline之前,我们必须将其包装在VkShaderModule对象中

同样遵守info和create,需要指定字节大小,和指向缓冲区的指针code.data(),

但字节码指针是uint32_t指针而不是char指针。因此,我们需要使用reinterpret_cast来强制转换指针

在createGraphicsPipeline调用,

Shader modules就像一个包装器,包装了char code,将SPIR-V字节码编译并链接到由GPU执行的机器码在图形管道创建之前不会发生,

一旦pipeline创建完成,我们就可以vkDestroyShaderModule  Shader modules,在createGraphicsPipeline所有指令后写

VkShaderModule createShaderModule(const std::vector<char>& code) {
    VkShaderModuleCreateInfo createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
    createInfo.codeSize = code.size();
    createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());

    VkShaderModule shaderModule;
    if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
        throw std::runtime_error("failed to create shader module!");
    }

    return shaderModule;
}

VkPipelineShaderStageCreateInfo

要实际使用着色器,我们需要通过VkPipelineShaderStagetInfo结构将它们分配给特定的管道阶段

第一步是告诉Vulkan着色器将在哪个管道阶段使用,每个可编程阶段都有一个枚举值,比如VK_SHADER_STAGE_VERTEX_BIT和VK_SHADER_STAGE_FRAGMENT_BIT

module是Shader modules

pname指明要调用的函数(入口点)

VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertShaderStageInfo.module = vertShaderModule;
vertShaderStageInfo.pName = "main";

VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
fragShaderStageInfo.module = fragShaderModule;
fragShaderStageInfo.pName = "main";

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

读数据工程之道:设计和构建健壮的数据系统23批量获取的考虑因素

1. 批量获取的考虑因素 1.1. 批量获取&#xff0c;通常是获取数据的一种便捷方式 1.1.1. 通过从源系统中抽取一个数据子集&#xff0c;根据时间间隔或累积数据的大小来获取数据 1.2. 基于时间间隔的批量获取在传统ETL的数据仓库中很普遍 1.2.1. 每天在非工作时间&#xff0…

Cyber​​Panel upgrademysqlstatus 远程命令执行漏洞(QVD-2024-44346)

0x01 产品简介 CyberPanel是一个开源的Web控制面板,它提供了一个用户友好的界面,用于管理网站、电子邮件、数据库、FTP账户等。CyberPanel旨在简化网站管理任务,使非技术用户也能轻松管理自己的在线资源。 0x02 漏洞概述 该漏洞源于upgrademysqlstatus接口未做身份验证和…

【形态学 - 击中-击不中变换(很多都讲得不直观不清楚,甚至是错的,我来个通俗易懂的)】

简单描述过程&#xff1a; 一般的目标匹配是&#xff0c;知道目标长什么样&#xff0c;用这个模板去匹配。这里还知道目标周围环境长什么样。 如何把环境的信息加进来用来帮助匹配呢。这个就是击中-击不中联合匹配了。 就是用亮图去匹配目标。 再用暗图去匹配背景。 两个联合起…

【蓝桥杯选拔赛真题78】python电话号码 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python电话号码 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python电话号码 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

单细胞数据分析(四):细胞亚型注释

文章目录 介绍加载R包导入数据细胞簇可视化细胞簇标记基因细胞识别输出结果系统信息介绍 单细胞细胞亚型注释是指在单细胞聚类分析后,对每个聚类得到的细胞群体进行生物学意义上的分类和识别的过程。这一步骤的目的是为了确定每个细胞群体对应的具体细胞类型或状态,从而更好…

CI/CD 的原理

一、CI/CD 的概念 CI/CD是一种软件开发流程&#xff0c;旨在通过自动化和持续的集成、测试和交付实现高质量的软件产品。 CI(Continuous Integration)持续集成 目前主流的开发方式是协同开发&#xff0c;即多位开发人员同事处理同意应用不同模块或功能。 如果企业在同一时间将…

常见大气校正模型及6S模型安装部署【20241028】

⛄常见大气校正模型 大气校正是遥感图像标准化处理的重要环节&#xff0c;消除太阳辐射传输过程中大气对于遥感图像的影响&#xff0c;提高影像的清晰度&#xff0c;获取地物真实的光谱信息。由于大气条件较为复杂&#xff0c;且随区域地理分布和观测时间是动态变化的&#xf…

map 和 set 的使用

文章目录 一.序列式容器和关联式容器二. set 系列的使用1. set 和 multiset 参考文档2. set 类介绍3. set 的构造和迭代器4. set 的增删查5. insert 和迭代器遍历使用样例6. find 和 erase 使用样例7. multiset 和 set 的差异 三. map 系列的使用1. map 和 multimap参考文档2. …

区块链可投会议CCF A--ICDE 2025 截止11.25 附2024录用数

Conference&#xff1a; IEEE International Conference on Data Engineering (ICDE) CCF level&#xff1a;CCF A Categories&#xff1a;Database/Data Mining/Content Retrieval Year&#xff1a;2025 Conference time&#xff1a; May 19-23, 2025 录用数&#xff1a;…

SLAM:未来智能科技的核心——探索多传感器融合的无限可

前言 作为2024年刚入学的研一新生&#xff0c;我初步选择了SLAM&#xff08;Simultaneous Localization and Mapping&#xff0c;即同时定位与地图构建&#xff09;作为我的研究方向。虽然在理论学习上已经有了一些基础&#xff0c;但目前的我并没有太多的实践经验。这让我在面…

Black Basta 勒索软件冒充 Microsoft Teams 的 IT 支持人员入侵网络

BlackBasta 勒索软件行动已将其社会工程攻击转移到 Microsoft Teams&#xff0c;伪装成公司帮助台联系员工以协助他们进行正在进行的垃圾邮件攻击。 Black Basta 是一个勒索软件行动&#xff0c;自 2022 年 4 月起活跃&#xff0c;并对全球数百起企业攻击负责。 2022 年 6 月…

Java语言-接口(下)

目录 1. 接口使用实例 1.1 给对象数组排序 1.2 Clonable接口和深拷贝 Cloneable 浅拷贝 深拷贝 1.3 抽象类和接口的区别 2. Object类 2.1 Object类的介绍 2.2 toString() 2.3 equals() 2.4 hashcode() 1. 接口使用实例 1.1 给对象数组排序 现有一个学生类&#…

Let‘s Verify Step by Step(openai-o1论文技术调研)

Let’s Verify Step by Step openai的经典论文&#xff0c;发布于2023年5月31日&#xff0c;为当前openai-o1奠定了技术基础&#xff0c;同时开源了PRM800K数据集&#xff0c;为开源社区贡献了十分宝贵的参考 paper原文链接 : https://arxiv.org/abs/2305.20050 论文概述 当前…

VUE, element-plus, table分页表格列增加下拉筛选多选框,请求后台

简介 为了方便表格查询时可以筛选列的值&#xff0c;需要给列增加筛选框&#xff08;多选框&#xff09;&#xff0c;element-plus提供了列的filter字段&#xff0c;但是基于表格数据的筛选&#xff0c;不会重新请求后台&#xff0c;而且当前表格数据有多少个条目&#xff0c;…

Makefile Npm

还是习惯强类型语法: typescript 不错 vue 非常好的模组 也是很好的学习模板 编译完才6MB 相当可以了 时代发展有点快 导入echarts 模块编译完才1.7MB 好用 <script> import {VaButton, VaInput} from "vuestic-ui";export default {components: {VaInput, VaB…

20241028在荣品PRO-RK3566开发板的预置Android13下用iperf3测试AP6256的WIFI网速

20241028在荣品PRO-RK3566开发板的预置Android13下用iperf3测试AP6256的WIFI网速 2024/10/28 18:17 荣品PRO-RK3566开发板作为服务器端&#xff1a; 笔记本电脑作为客户端。 接公司的网络。 在笔记本电脑的ubuntu20.04下&#xff0c;通过nethogs实测iperf3的发送速度大概是10MB…

Bi-LSTM-CRF实现中文命名实体识别工具(TensorFlow)

项目源码获取方式见文章末尾&#xff01; 回复暗号&#xff1a;13&#xff0c;免费获取600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 **《------往期经典推荐------》**项目名称 1.【MobileNetV2实现实时口罩检测tensorflow】 2.【卫星图像道路检测DeepLabV3P…

【ArcGIS Pro实操第4期】绘制三维地图

【ArcGIS Pro实操第4期】绘制三维地图 ArcGIS Pro绘制三维地图-以DEM高程为例参考 如何使用ArcGIS Pro将栅格数据用三维的形式进行表达&#xff1f;在ArcGIS里可以使用ArcScene来实现&#xff0c;ArcGIS Pro实现原理跟ArcScene一致。由于Esri未来将不再对ArcGIS更新&#xff0c…

Python酷库之旅-第三方库Pandas(174)

目录 一、用法精讲 801、pandas.Categorical类 801-1、语法 801-2、参数 801-3、功能 801-4、返回值 801-5、说明 801-6、用法 801-6-1、数据准备 801-6-2、代码示例 801-6-3、结果输出 802、pandas.Categorical.from_codes方法 802-1、语法 802-2、参数 802-3、…

2.5 塑性力学—应变状态

个人专栏—塑性力学 1.1 塑性力学基本概念 塑性力学基本概念 1.2 弹塑性材料的三杆桁架分析 弹塑性材料的三杆桁架分析 1.3 加载路径对桁架的影响 加载路径对桁架的影响 2.1 塑性力学——应力分析基本概念 应力分析基本概念 2.2 塑性力学——主应力、主方向、不变量 主应力、主…