当前位置: 首页 > news >正文

Vulkan-着色器及编译SPIR-V

1.着色器模块介绍

       Vulkan着色器代码一定要用字节码格式,而不是人类可读的语法如GLSL和HLSL。这个字节码就是SPIR-V,设计用于Vulkan和OpenCL。这是一个可以用于编写图形和计算着色器的格式,但是我们主要关注的是Vulkan的图形管线。使用字节码格式的优点之一是GPU厂商写的编译器将着色器代码转化为原生代码会非常简单。过去的经验表明,人类易读的语法如GLSL,某些GPU厂商是能很便捷地解读这些标准的。但是如果你碰巧写了不一般的着色器,那可能会导致厂家的着色器因为你的语法错误而拒绝执行,甚至更糟,就是能执行,却因为编译器bug得到的是错误的结果。直接用字节码格式就能避免这些问题。

       Khronos已经发行了他们自己的厂商无关的编译器,能够将GLSL编译到SPIR-V格式。这个编译器就是用来验证你的着色器都是和标准兼容的,它会产生一个SPIR-V的二进制输出,可以和你的程序一同发行。该编译器包含在LunarG SDK中了,也就是glslangValidator.exe,所以不用额外下载任何内容。

       GLSL是C语法风格的着色器语言,用它写的程序有一个main方法来让每个对象调用。没有用参数作为输入,返回一个值作为输出这种做法,GLSL使用了全局变量来处理输入和输出。该语言包含了许多特性以便于图形编程,比如内建的向量和矩阵原型。叉乘,矩阵-向量相乘,向量反射之类操作用的函数都包括在内。

        向量类型叫做vec,后面跟着一个数字表示元素个数。比如一个3D位置应该存储为vec3。可以用类似.x的方式获取其单独的组件,但是也可能会创建一个新的变量,比如vec3(1.0, 2.0, 3.0).xy就会得到一个vec2。向量的构造器也可以接受向量对象的组合以及标量值,比如vec3可以用vec3(vec2(1.0, 2.0), 3.0)构造。
2.着色器例子

        写一个顶点着色器和片段着色器,以便将三角形显示到屏幕上。下面两部分会介绍每一部分的GLSL代码,之后我会介绍如何产生两份SPIR-V二进制文件并加载到程序中。

2.1 定点着色器

顶点着色器处理每个到来的顶点,用其属性如世界坐标,颜色,法线和材质坐标等作为输入。输出是最终在裁剪坐标的位置和需要传递给片段着色器的属性,比如颜色和材质坐标。这些值会被片段着色器根据光栅器插值,产生平滑的梯度。

裁剪坐标是来自顶点着色器的四维向量,随后被通过最后一个元素除以整个向量转变成一个归一化设备坐标。这些归一化设备坐标是齐次坐标,将帧缓冲映射到纵横都是[-1, 1]的坐标系,如下:
 

我们第一个三角形不用任何变换,我们就直接明确三个点的位置作为归一化设备坐标,来创建如下的三角形:

直接输出归一化设备坐标,做法就是将他们作为裁剪坐标从顶点着色器输出,最后一个部分置为1。这样变换裁剪坐标到归一化设备坐标时候的除法操作就什么都保持不变。

通常这些坐标会存储在顶点缓冲中,但是创建顶点缓冲并填充数据在Vulkan中并非微不足道。因此我们决定先将其推迟,直到我们满足地看到三角形绘制到了屏幕上。同时我们还要做一些不太正统的东西:直接将坐标包含在顶点着色器中。代码如下

#version 450vec2 positions[3] = vec2[](vec2(0.0, -0.5),vec2(0.5, 0.5),vec2(-0.5, 0.5)
);void main() {gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
}

main方法是每个顶点都涉及的,内置的gl_VertexIndex变量包含了当前顶点的索引。这通常是顶点缓冲的索引,但是我们这儿它就是硬编码数组的顶点数据的索引。每个顶点的位置通过着色器的连续数组获取,且和虚拟z和w部分一起组成一个裁剪坐标的位置。内置变量gl_Position作为输出。
2.2 片段着色器

由来自顶点着色器的位置形成的三角形用片段来填充屏幕上的区域。片段着色器就在这些片段上执行来为帧缓冲产生一个颜色和深度。一个简单的为整个三角形输出红色的片段着色器。

#version 450
#extension GL_ARB_separate_shader_objects : enablelayout(location = 0) out vec4 outColor;void main() {outColor = vec4(1.0, 0.0, 0.0, 1.0);
}

main方法被每个片段调用,就和顶点着色器的main方法被每个顶点调用一样。GLSL的颜色是由4部分组成的向量,就是RGB和alpha通道,范围都是[0, 1]。不像是顶点着色器的gl_Position,没有内置变量为当前片段输出一个颜色。你必须为每个帧缓冲明确自己的输出变量,布局(location = 0)修改器明确了帧缓冲的索引。这里outColor写成红色,和索引为0的第一个帧缓冲连接起来。
3.编译着色器

在项目根目录创建一个shaders目录,存储我们的着色器代码。两份着色器分别是shader.vert和shader.frag,GLSL没有官方扩展名,但是这两个通常用于区分它们。

shader.vert如下所示:

#version 450
#extension GL_ARB_separate_shader_objects : enablelayout(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];
}

shader.frag如下:

#version 450
#extension GL_ARB_separate_shader_objects : enablelayout(location = 0) in vec3 fragColor;layout(location = 0) out vec4 outColor;void main() {outColor = vec4(fragColor, 1.0);
}

现在我们准备用glslangValidator将其编译成SPIR-V字节码:

glslc shader.vert -o vert.spv
glslc shader.frag -o frag.spv

这两条命令用-V标志调用了编译器,表明要求编译器将GLSL源文件编译成SPIR-V字节码。当你运行编译脚本的时候,就会发现两个SPIR-V二进制文件产生了,即vert.spv和frag.spv。这些名字直接来自shader类型,但是你可以进行重命名。Vulkan SDK包含了libshaderc,也就是将你的GLSL代码编译成SPIR-V的东西。
4.加载着色器

当前我们可以产生SPIR-V着色器了,是时候将其加载到我们的程序中了,然后在某个时刻将其插入到图形管线中。我们先要写一个简单的助手方法来从文件加载二进制数据:

readFile方法会从指定文件读取所有字节,返回std::vector管理的byte数组。我们用两个标记打开该文件:

ate:开始读的时候在文件末尾,就是说打开文件的时候定位到文件尾;

binary:以二进制文件读取文件(避免text转换)。

现在我们从createGraphicsPipeline调用该方法:

void createGraphicsPipeline() {
    auto vertShaderCode = readFile("shaders/vert.spv");
    auto fragShaderCode = readFile("shaders/frag.spv");
}

准备创建着色器模块,在开始将代码传递到管线之前,我们需要将其包装到VkShaderModule对象中,创建一个createShaderModule方法

相关文章:

Vulkan-着色器及编译SPIR-V

1.着色器模块介绍 Vulkan着色器代码一定要用字节码格式,而不是人类可读的语法如GLSL和HLSL。这个字节码就是SPIR-V,设计用于Vulkan和OpenCL。这是一个可以用于编写图形和计算着色器的格式,但是我们主要关注的是Vulkan的图形管线。使用字节码格…...

从MVC到DDD,该如何下手重构?

作者:付政委 博客:bugstack.cn 沉淀、分享、成长,让自己和他人都能有所收获!😄 大家好,我是技术UP主小傅哥。多年的 DDD 应用,使我开了技术的眼界! MVC 旧工程腐化严重,…...

论文阅读:基于隐马尔可夫模型的蛋白质多序列比对方法研究

本文来自chatpaper Basic Information: • Title: Research on Protein Multiple Sequence Alignment Method Based on Hidden Markov Model (基于隐马尔可夫模型的蛋白质多序列比对方法研究) • Authors: Zhan Qing • Affiliation: Harbin Institute of Technology (哈尔滨工…...

Vim同时打开多个文件

分屏模式 在 Vim 中,可以同时打开多个文件并使用分屏模式来查看它们。以下是一些常见的方法和命令: 在启动 Vim 时打开多个文件 使用 -o 选项打开文件并水平分屏: vim -o file1.txt file2.txt使用 -O 选项打开文件并垂直分屏: v…...

SpringCloudStreamkafka接收jsonarray字符串失败

文章目录 场景现象问题处理 场景现象 kafka作为消息队列,作为前端设备数据到后端消费的渠道,也被多个不同微服务消费一个服务与前端边缘计算设备建立socket消息,接收实时交通事件推送,再将事件发送到kafka里面。此处使用的是Spri…...

面向对象特性分析大全集

面向对象特性分析 先进行专栏介绍 面向对象总析前提小知识分类浅析封装浅析继承浅析多态面向对象编程优点abc 核心思想实际应用总结 封装概念详解关键主要目的核心思想优点12 缺点12 Java代码实现封装特性 继承概念详解语法示例关键主要目的核心思想优点12 缺点12 Java代码实现…...

【数据结构】队列和栈

大家中秋节快乐,玩了好几天没有学习,今天分享的是栈以及队列的相关知识,以及栈和队列相关的面试题 1.栈 1.1栈的概念及结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作…...

WordPress主题开发( 十)之—— 条件标签函数(上)

这里写目录标题 什么是条件标签函数?条件标签函数的使用场景使用条件标签函数的注意事项常用的条件标签函数主页示例:is_front_page() 示例:管理后台is_admin() 示例:单个文章页面is_single() 示例:is_single(17) 示例:is_single(Hello World) 示例:is_single(hello…...

vue学习-10vue整合SpringBoot跨域请求

在Vue.js应用整合Spring Boot后端时,需要处理跨域请求。跨域请求通常发生在前端应用运行在不同的域名或端口上时,而后端服务运行在不同的域名或端口上。以下是一种处理跨域请求的常见方式: 后端(Spring Boot)配置 在…...

ElasticSearch - 基于 JavaRestClient 查询文档(match、精确、复合查询,以及排序、分页、高亮)

目录 一、基于 JavaRestClient 查询文档 1.1、查询 API 演示 1.1.1、查询基本框架 DSL 请求的对应格式 响应的解析 1.1.2、全文检索查询 1.1.3、精确查询 1.1.4、复合查询 1.1.5、排序和分页 1.1.6、高亮 一、基于 JavaRestClient 查询文档 1.1、查询 API 演示 1.1.…...

简易实现通讯录(2.0)

这篇文章是在上期实现的通讯录基础上,增加了自动增容的功能,也解决了一开始通讯录自动开辟一个空间,可能会浪费空间,或者是信息过多无法增容的痛点,由于我们使用的是malloc这类函数来开辟空间,我们也需要来…...

Jasypt 实现自定义加解密

如下文章已经讲解了, Jasypt 是什么,怎么集成 Jasypt,怎么使用 Jasypt。 Jasypt 开源加密库使用教程_jasyptstringencryptor-CSDN博客Jasypt 加密框架概述1、Jasypt Spring Boot 为 spring boot 应用程序中的属性源提供加密支持,…...

Leetcode 554. 砖墙

文章目录 题目代码&#xff08;9.25 首刷自解&#xff09; 题目 Leetcode 554. 砖墙 代码&#xff08;9.25 首刷自解&#xff09; class Solution { public:int leastBricks(vector<vector<int>>& wall) {unordered_map<int, int> mp;int count 0;for…...

Python 内置函数详解 (3) 进制转换

近期在外旅游,本篇是出发前定时发布的,不完整,旅游回来后再补充。 Python 内置函数 Python3.11共有75个内置函数,其来历和分类请参考:Python 新版本有75个内置函数,你不会不知道吧_Hann Yang的博客-CSDN博客 函数列表 abs aiter all …...

SPSS列联表分析

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件可在个人主页—…...

聊聊并发编程——并发容器和阻塞队列

目录 一.ConcurrentHashMap 1.为什么要使用ConcurrentHashMap&#xff1f; 2.ConcurrentHashMap的类图 3.ConcurrentHashMap的结构图 二.阻塞队列 Java中的7个阻塞队列 ArrayBlockingQueue&#xff1a;一个由数组结构组成的有界阻塞队列。 LinkedBlockingQueue&#xf…...

我庄严承诺终生不去承德旅游

虽然人微言轻&#xff0c;但也要尽一份力。 在此&#xff0c;我庄严承诺&#xff1a; 如果承德相关机构不返还那名"灵活就业人员"105.82万元的财产&#xff0c;并进行公开道歉。 我将终生不去承德旅游&#xff0c; 我将终生不买承德出产的任何产品。 我还将劝诫我…...

【python】python实现杨辉三角的三种方法

文章目录 1.杨辉三角介绍&#xff1a;2.方法一&#xff1a;迭代3.方法二&#xff1a;生成器4.方法三&#xff1a;递归 1.杨辉三角介绍&#xff1a; 杨辉三角是一种数学图形&#xff0c;由数字排列成类似三角形的形状。它的每个数值等于它上方两个数值之和。这个三角形的形状可以…...

GitHub 基本操作

最近要发展一下自己的 github 账号了&#xff0c;把以前的项目代码规整规整上传上去&#xff0c;这里总结了一些经验&#xff0c;经过数次实践之后&#xff0c;已解决几乎所有基本操作中的bug&#xff0c;根据下面的操作步骤来&#xff0c;绝对没错了。&#xff08;若有其他问题…...

Docker和Docker compose的安装使用指南

一&#xff0c;环境准备 Docker运行需要依赖jdk&#xff0c;所以需要先安装一下jdk yum install -y java-1.8.0-openjdk.x86_64 二&#xff0c;Docker安装和验证 1&#xff0c;安装依赖工具 yum install -y yum-utils 2&#xff0c;设置远程仓库 yum-config-manager --add-r…...

51单片机控制电动机正反转,PWM调速,记录转动圈数。

今天的实验需要用到的材料有&#xff1a;51单片机最小系统&#xff0c;4X4的矩阵键盘&#xff0c;DC直流6V-12V带编码器电机&#xff0c;L298N模块&#xff0c;一个led小灯。下面把产品截图展示一下&#xff1a; 单片机就不展示了&#xff0c;都一样&#xff0c;下面是接线图&a…...

JAVA学习(方法的定义和调用)

一、方法的定义和调用 1、关键词&#xff1a;static表示静态方法&#xff0c;如没有返回值使用void&#xff0c;方法名前使用类型&#xff0c;例如int、float等&#xff1b; /*** 测试方法的定义和调用*/public class TestMethod {public static void main(String[] args) {a…...

Linux(CentOS/Ubuntu)——安装nginx

如果确定你的系统是基于CentOS或RHEL&#xff0c;可以使用以下命令&#xff1a; ①、安装库文件 #安装gcc yum install gcc-c#安装PCRE pcre-devel yum install -y pcre pcre-devel#安装zlib yum install -y zlib zlib-devel#安装Open SSL yum install -y openssl openssl-de…...

26962-2011 高频电磁场综合水处理器技术条件

声明 本文是学习GB-T 26962-2011 高频电磁场综合水处理器技术条件. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了高频电磁场综合水处理器(以下简称处理器)的术语和定义、分类和型号、结构型式、 要求及检验、标志、包装和贮运…...

图扑软件受邀亮相 IOTE 2023 国际物联网展

IOTE 2023 国际物联网展&#xff0c;作为全球物联网领域的盛会&#xff0c;于 9 月 20 日 - 22 日在中国深圳拉开帷幕。本届展会以“IoT构建数字经济底座”为主题&#xff0c;由深圳市物联网产业协会主办&#xff0c;打造当前物联网最新科技大秀。促进物联网与各行业深度融合&a…...

C语言文件操作与管理

一、为什么使用文件 在我们前面练习使用结构体时&#xff0c;写通讯录的程序&#xff0c;当通讯录运行起来的时候&#xff0c;可以给通讯录中增加、删除数据&#xff0c;此时数据是存放在内存中&#xff0c;当程序退出的时候&#xff0c;通讯录中的数据自然就不存在了&#xff…...

蓝桥等考Python组别八级005

第一部分&#xff1a;选择题 1、Python L8 &#xff08;15分&#xff09; 运行下面程序&#xff0c;输出的结果是&#xff08; &#xff09;。 i 1 while i < 4: print(i, end ) i 1 1 2 30 1 2 31 2 3 40 1 2 3 4 正确答案&#xff1a;C 2、Python L8 &#…...

JUnit介绍

JUnit是用于编写和运行可重复的自动化测试的开源测试框架&#xff0c; 这样可以保证我们的代码按预期工作。JUnit可广泛用于工业和作为支架(从命令行)或IDE(如Eclipse)内单独的Java程序。 JUnit提供&#xff1a; 断言测试预期结果。 测试功能共享通用的测试数据。 测试套件轻…...

(高阶) Redis 7 第16讲 预热/雪崩/击穿/穿透 缓存篇

面试题 什么是缓存预热/雪崩/击穿/穿透如何做缓存预热如何避免或减少缓存雪崩穿透和击穿的区别?穿透和击穿的解决方案出现缓存不一致时,有哪些修补方案缓存预热 理论 将需要的数据提前加载到缓存中,不需要用户使用的过程中进行数据回写。(比如秒杀活动数据等) 方案 1.…...

(三) gitblit管理员手册

(一)gitblit安装教程 (二) gitblit用户使用教程 (三) gitblit管理员手册 目录 权限管理创建仓库时创建用户普通用户 管理员用户访问限制和访问权限仓库创建权限分配 Teams普通组管理员组 参考资料 权限管理 创建仓库时 选择指定的人员查看,克隆,推送 不允许fork 对应Anonymo…...

网站加视频播放设计怎么做的/seo百度关键词优化

1、首先去(http://www.apachelounge.com/download/)下载一个合适的mod_fcgid 文件。 2、将解压后的文件改为mod_fcgid.dll 并复制到apache的module目录下面。3、打开httpd.conf文件&#xff0c;添加如下内容&#xff1a;1 LoadModule fcgid_module modules/mod_fcgid.so 2 &l…...

网站建设销售怎么样/淘宝推广费用一般多少

作为一个程序员来说&#xff0c;简历可谓是面试的时候一个加分砝码&#xff0c;往往有的面试者只在意自己的技术&#xff0c;其实这是非常不对的。简历对于一个面试者来说非常重要&#xff0c;他是第一个入口&#xff0c;也是面试官认识你的第一个途径。不管是对于刚毕业或者即…...

加强政府门户网站建设管理/企业营销推广怎么做

突发奇想&#xff0c;想写点东西。先说一下我的目标&#xff1a;我希望能够统一自己脑海中的知识&#xff0c;形成一个系统的框架&#xff0c;知道哪里是自己的薄弱&#xff0c;哪些是自己的长处和积累。然后懂得扬长避短&#xff0c;发挥自己的优势和价值。来应对复杂多变的社…...

公司网站建设哪家好/店铺在百度免费定位

MainController.class.php <?php namespace Home\Controller; use Think\Controller; class MainController extends Controller{function DB()//造操作方法{$m D("Info");//把数据显示在模型里面$attr $m->select();//调用方法查询所有的数据&#xff0c;返…...

现实有有哪里学做网站的/星乐seo网站关键词排名优化

利用matplotlib进行可视化 1、Matplotlib 基本介绍 Matplotlib 是一个在 python 下实现的类 matlab 的纯 python 的第三方库,旨在用 python实现matlab 的功能,是python下最出色的绘图库。其风格跟 matlab 相似&#xff0c;同时也继承了 python 的简单明了。要使用matplotlib得…...

热门视频素材/宁波网站seo诊断工具

在用eclipse开发时&#xff0c;经常遇到卡死的情况&#xff0c;其中一种就是右下角出现&#xff1a;“Remote System Explorer Operation”&#xff0c;解决方案如下&#xff1a; 第一步&#xff1a;Eclipse -> Preferences -> General -> Startup and Shutdown.不要勾…...