VulkanTutorial(8·Shader modules)

news2024/11/29 0:33:53

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";

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

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

相关文章

详解PHP正则表达式中的转义操作

PHP正则表达式中的特殊字符和转义 在 PHP 正则表达式中&#xff0c;有许多特殊字符具有特定的意义。这些特殊字符通常用于定义匹配模式的一部分&#xff0c;或者改变匹配的行为。以下是 PHP 正则表达式中一些常用的特殊字符及其含义: .匹配除换行符之外的任何单个字符 ^在方括…

27.Redis哨兵架构

Redis哨兵高可用架构 Sentinel&#xff08;哨兵&#xff09;是一种特殊的 Redis 服务&#xff0c;其主要功能并非提供常规的读写服务&#xff0c;而是专门用于监控 Redis 实例节点。 1.在哨兵架构下&#xff0c;客户端&#xff08;client 端&#xff09;首次会从哨兵处找出 Re…

STM32G474硬件CRC7和软件CRC7校验

1、CRC7的多项式和初始值 #define CRC_Hardware_POLYNOMIAL_7B 0x09//硬件CRC多项式为0x09 //SD卡中的校验算法CRC7&#xff0c;生成多项式为x^7 x^3 1&#xff0c;由于bit7不存在&#xff0c;只有bit31和bit01&#xff0c;所以多项式为0x09#define CRC7_INIT_VALUE 0…

Java基础 —— IO流详解

IO流 在Java中&#xff0c;IO&#xff08;输入/输出&#xff09;流是用于在程序与外部世界&#xff08;如文件、网络、内存等&#xff09;之间传输数据的机制。IO流分为两大类&#xff1a;输入流&#xff08;InputStream/Reader&#xff09;和输出流&#xff08;OutputStream/…

【01初识】-初识 RabbitMQ

目录 学习背景1- 初识 MQ1-1 同步调用什么是同步调用&#xff1f;小结&#xff1a;同步调用优缺点 1-2 异步调用什么是异步调用&#xff1f;小结&#xff1a;异步调用的优缺点&#xff0c;什么时候使用异步调用&#xff1f; 1-3 MQ 技术选型 学习背景 异步通讯的特点&#xff…

STK与MATLAB互联——仿真导航卫星与地面用户间距离和仰角参数

文章目录 构建GPS星座创建单个PRN的GPS卫星创建GPS星座&#xff0c;并为其添加发射机 北斗星座构建搭建低轨铱星星座构建一颗轨道高度为800km/1000km/1200km的低轨卫星构建一颗轨道高度为800km/1000km/1200km的低轨卫星建立地面站&#xff0c;可见性分析确定地面站坐标分析单颗…

Excel菜单选项无法点击?两种原因及解决方法全解析

在使用Excel处理数据时&#xff0c;有时会遇到菜单选项无法点击的情况。这种问题会影响到正常的操作和编辑。出现这种情况的原因可能有多种&#xff0c;本文将介绍两种常见的原因&#xff0c;并提供相应的解决方法&#xff0c;帮助小伙伴们快速恢复菜单选项的正常使用。 原因一…

【银河麒麟高级服务器操作系统·实例分享】裸金属服务器开机失败分析及处理建议

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn 现象描述 裸金属物理服务器开机卡在EFI stub页面…

基于Spring Boot的在线摄影工作室开发指南

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理网上摄影工作室的相关信息成为必然。开发合…

UE5蓝图中整理节点的方法

UE5蓝图中整理节点的方法 第一种&#xff1a;子图 右键选中的节点&#xff0c;出现一个面板&#xff0c;点击 Collapse Nodes 既可折叠选中的所有节点 注意&#xff1a;子图不可以被复制使用。 双击子图可以查看节点&#xff0c;若不想折叠选中的节点为子图&#xff0c;右键点…

喜讯丨江苏省医药行业协会·中药饮片专业委员会2024年度三届五次会员代表大会暨《江苏中药饮片》通讯员年度表彰大会圆满举行

2024年10月25日&#xff0c;江苏省医药行业协会中药饮片专业委员会三届五次&#xff08;2024年度&#xff09;会员代表大会暨《江苏中药饮片》通讯员年度表彰大会在苏州香格里拉大酒店隆重召开。 江苏省药品监督管理局、药品生产监管局、江苏省医药行业协会、江苏省食品药品监督…

git push到远程怎么回退

git push到远程服务器想继续修改&#xff0c;你必须要回退然后在此提交。而且需要保留本地的修改文件。 下面给你一些git命令&#xff0c;回退很简单。 按照下面的流程操作就行&#xff1a; 1.查看提交历史 首先&#xff0c;使用git log命令查看提交历史。可以使用以下命令显…

回溯法 | 无限个for循环?

文章目录 起因实现 优化 起因 回溯算法&#xff0c;寻找问题的所有解或最优解 最开始遇到这样一个问题&#xff0c;认为可以用几个for循环暴力解决&#xff0c;然而仔细观察后发现&#xff0c;针对不同的输入&#xff0c;我需要的for循环的个数不一样&#xff0c;只能使用递归…

react18中react-thunk实现公共数据仓库的异步操作

redux及react-redux都只能实现数据的同步修改更新&#xff0c;有点类似于vue中的mutation&#xff0c;只能做同步操作&#xff0c;异步的话不用actions来实现。由于在项目始终不可避免要实现的异步数据的更新&#xff0c;这明显不够用了。是时候引入我们的异步中间件redux-thun…

原生js实现拖拽上传(拖拽时高亮上传区域)

文章目录 drop相关事件说明-MDN演示代码&#xff08;.html) drop相关事件说明-MDN 演示 代码&#xff08;.html) <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"…

最新XL换脸术!EcomID,更像更强,结合InstantID和PuLID优点,200万训练集,6.6显存占用,ComfyUI

由阿里妈妈最新开源的换脸工具&#xff1a;EcomID&#xff0c;结合了InstantID和PuLID优点&#xff0c;以获得更好的背景一致性、面部关键点控制、更真实的面部以及更高的相似度。旨在从单个ID参考图像生成定制的保ID图像&#xff0c;优势在于很强的语义一致性&#xff0c;同时…

情感咨询小程序的市场需求大吗?

情感咨询小程序的市场需求较大&#xff0c;主要体现在以下几个方面&#xff1a; 情感问题普遍存在5&#xff1a; 恋爱关系困扰&#xff1a;在恋爱过程中&#xff0c;人们经常会遇到诸如沟通不畅、争吵频繁、信任危机等问题。例如&#xff0c;年轻人在恋爱初期可能会因为不了解…

技术分享 | 大语言模型增强灰盒模糊测试技术探索

大语言模型凭借其庞大的参数规模&#xff0c;能够通过无监督学习从海量文本中获取知识&#xff0c;从而不仅能够深刻理解文本语义&#xff0c;还能准确识别文本的格式和结构。凭借对不同数据结构的深度理解&#xff0c;大语言模型已在众多领域得到广泛应用。其中&#xff0c;尤…

Cmake Error:could not find any instance of Visual Studio.

出现以下错误 解决方案&#xff1a; 安装visual stuido 2017。 检查是否安装“使用C的桌面开发” 检查是否安装了扩展开发 点开“单个组件”是否安装了以下组件 编辑计算机环境变量&#xff0c;

linux查看文件命令

查看文件命令 显示命令 cat 语法&#xff1a;cat 【选项】 文件 选项 命令含义n显示行号包括空行b显示行号不包括空行s压缩空行为一行A显示隐藏字符 cat -n 文件&#xff1a;显示行号包括空行 cat -b 文件 cat -s 文件 cat -A 文件 more和less是 分页查看 tac和rev都…