Vulkan着色器的GLSL创建、编译、加载、创建流程

2023-05-16

Vulkan没有指定官方的着色器编程语言,而是采用SPIR-V二进制中间格式进行表示。开发人员一般需要基于某种着色器编程语言开发着色器,之后再编译为SPIR-V格式。可以选用GLSL着色器编程语言进行开发。

       大型游戏场景中,一般预先将着色器编译为SPIR-V格式保存在文件中,程序运行时直接加载SPIR-V数据,提高效率。

       着色器的预编译和调用过程如面流程所示:

 

一、着色器源代码预编译

       首先编辑好GLSL的着色器文件,后缀依次为:顶点着色器-.vert、片元着色器-.frag、细分控制着色器-.tesc、细分执行着色器-.tese、几何着色器-.geom、计算着色器-.comp。之后使用Vulkan SDK中的glslang validator命令对着色器源代码进行编译。

glslangvalidator -V commonTexLight.vert -o commonTexLight.vert.spv

       其中,V参数代表得到SPIR-V格式的数据,o代表输出文件的路径。

       以下两个文件给出了vert着色器和frag着色器的GLSL源代码文件内容:

//给定了所用GLSL的版本
#version 400

//Vulkan中想使用着色器进行开发,需要开启这两个扩展
#extension GL_ARB_separate_shader_objects : enable//启动GL_ARB_separate_shader_objects
#extension GL_ARB_shading_language_420pack : enable//启动GL_ARB_shading_language_420pack

//声明一致块myBufferVals,包含接收总变换矩阵的成员mvp
layout (std140,set = 0, binding = 0) uniform bufferVals {//一致块
    mat4 mvp;//总变换矩阵
} myBufferVals;

layout (location = 0) in vec3 pos;//传入的物体坐标系顶点位置
layout (location = 1) in vec3 color;//传入的顶点颜色
layout (location = 0) out vec3 vcolor;//传到片元着色器的顶点颜色

//定义了输出接口块
out gl_PerVertex {
	vec4 gl_Position;//顶点最终位置
};

//顶点着色器的主方法
void main() {
	//计算最终顶点位置:最终变换矩阵*物体坐标系下的顶点坐标
    gl_Position = myBufferVals.mvp * vec4(pos,1.0);
	//传递顶点颜色给片元着色器
    vcolor=color;
}
//给定了所用GLSL的版本
#version 400

//Vulkan中想使用着色器进行开发,需要开启这两个扩展
#extension GL_ARB_separate_shader_objects : enable//启动GL_ARB_separate_shader_objects
#extension GL_ARB_shading_language_420pack : enable//启动GL_ARB_shading_language_420pack

//定义两个颜色数据值
layout (location = 0) in vec3 vcolor;//顶点着色器传入的顶点颜色数据
layout (location = 0) out vec4 outColor;//输出到渲染管线的片元颜色值

//片元着色器的主方法
void main() {
	//将顶点着色器传递过来的颜色值输出,最后的1.0代表A通道
   outColor=vec4(vcolor.rgb,1.0);
}

二、用于加载着色器SPIR-V数据的结构体&

       结构体SpvDataStruct:存有两个成员,size用于存储SPIR-V数据的总字节数;data指向SPIR-V数据内存块首地址的指针。

       类FileUtil:具有loadSPV函数,加载SPIR-V文件。

typedef struct SpvDataStruct{//存储SPIR-V数据的结构体 
    int size;             //SPIR-V数据总字节数 
    uint32_t* data;      //指向SPIR-V数据内存块首地址的指针 
} SpvData; 

class FileUtil{ 
   public:  //此处省略了原有FileUtil类头文件中的成员方法声明 
   static SpvData& loadSPV(string fname);   //加载Assets文件夹下的SPIR-V数据 
}; 

 

三、FuleUtil中的loadSPV函数

       首先通过AAsetManager_open方法获得AAsset对象,之后通过AAset_getLength获取总字节数,然后构建了用于存储SPIR-V数据的结构体实例,最后加载数据。

//加载Assets文件夹下的SPIR-V数据文件 
SpvData& FileUtil::loadSPV(string fname){  
    AAsset* asset =AAssetManager_open(aam,fname.c_str(),AASSET_MODE_STREAMING);  
    assert(asset); 
    size_t size = AAsset_getLength(asset);  //获取SPIR-V数据文件的总字节数 
    assert(size > 0);                       //检查总字节数是否大于0 
    SpvData spvData;                        //构建SpvData结构体实例 
    spvData.size=size;                      //设置SPIR-V数据总字节数 
    spvData.data=(uint32_t*)(malloc(size)); //分配相应字节数的内存 
    AAsset_read(asset, spvData.data, size); //从文件中加载数据进入内存 
    AAsset_close(asset);                    //关闭AAsset对象 
    return spvData;                         //返回SpvData结构体实例 
}

 

四、根据SPIR-V文件创建着色器

       首先利用FileUtil类中的loadSPV方法获取顶点、片元着色器的SPIR-V数据,之后分别构建顶点着色器、片元着色器模块创建信息结构体实例。

void ShaderQueueSuit_Common::create_shader(VkDevice& device){ 
    //加载顶点着色器数据
    SpvData spvVertData=FileUtil::loadSPV("shader/commonTexLight.vert.spv"); 
    //加载片元着色器数据                                                                
    SpvData spvFragData=FileUtil::loadSPV("shader/commonTexLight.frag.spv"); 
	 
    //此处省略了部分源代码
	
    VkShaderModuleCreateInfo moduleCreateInfo;       //准备顶点着色器模块创建信息 
    moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 
    moduleCreateInfo.pNext = NULL;                   //自定义数据的指针 
    moduleCreateInfo.flags = 0;                      //供将来使用的标志 
    moduleCreateInfo.codeSize = spvVertData.size;    //顶点着色器SPV数据总字节数 
    moduleCreateInfo.pCode = spvVertData.data;       //顶点着色器SPV数据 
	
    //此处省略了部分源代码 
	
    VkShaderModuleCreateInfo moduleCreateInfo;       //准备片元着色器模块创建信息 
    moduleCreateInfo.sType =VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;  
    moduleCreateInfo.pNext = NULL;                   //自定义数据的指针 
    moduleCreateInfo.flags = 0;                      //供将来使用的标志 
    moduleCreateInfo.codeSize = spvFragData.size;    //片元着色器SPV数据总字节数 
    moduleCreateInfo.pCode = spvFragData.data;       //片元着色器SPV数据 
    //此处省略了部分源代码
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vulkan着色器的GLSL创建、编译、加载、创建流程 的相关文章

随机推荐

  • 知识图谱笔记(小象学院课程)

    2018年寒假看小象学院课程的时候写的笔记 xff0c 一共写了10页 xff0c 记得比较乱 因为纸质笔记不容易保存 xff0c 所以把它扫成了PDF以备后用 希望大家能够指出不足和错误
  • 隐马尔可夫模型HHM重要公式推导

    我终于把HMM看完了 xff0c 这些笔记都是看的过程中自己对推导过程写的注释 xff0c 还有知识框架 原来卡尔曼和粒子滤波都是属于HMM模型里面的 笔记结构如下 xff1a 1 HMM简介 xff1a 知识体系 43 一个模型 43 两
  • MOT指标笔记《CLEAR Metrics-MOTA&MOTP》2008年·卡尔斯鲁厄大学

    搞了这么久的MOT xff0c 到头来发现最基本的MOTA和MOTP还没有搞懂 xff0c 实在有点说不过去 今天花了一上午的时间阅读2008年卡尔斯鲁厄大学的 Evaluating Multiple Object Tracking Per
  • 概率图模型-知识结构

    两周多 xff0c 终于把概率图模型这一章看完了 xff0c 由于只是看了知识框架 xff0c 很多具体细节都还不理解 内容真的是好多啊 xff0c 而且都是理论 xff0c 没有实践 希望日后用到的时候能回忆的起来这些内容吧
  • 软件工程概论-课后作业1

    需要网站系统开发需要掌握的技术 1 网页设计 xff1a Photoshop Flash max Dreamweaver 2 网站程序 xff1a Dreamweaver Visual Studio NET 会asp asp net php
  • 《强化学习》——CH2 多臂赌博机 笔记

  • 相机几何学——投影矩阵P的构成(实验报告版)

    最近在可视化WildTrack数据集 xff0c 由于要对棋盘格点进行映射和绘制 xff0c 涉及到了P矩阵的计算 现在对P的来源进行了系统的整理 xff0c 以备后忘 在最后对场地端点映射产生的问题进行了讨论 xff08 事情开始变得有意
  • 约束优化方法_2_——Frank-Wolfe方法

    Frank Wolfe方法属于约束优化中可行方向法的一种 上一篇博文对同类型的Zoutendijk可行性方法进行了介绍 xff0c 这一部分着重关注Frank Wolfe方法 Frank Wolfe方法的基本思想是 xff1a 每次迭代中使
  • 二次规划_1_——Lagrange方法

    二次规化是非线性规化中的一种特殊情形 xff0c 其目标函数是二次实函数 xff0c 约束是线性的 考试中会考到四种方法 xff0c 分别为 xff1a Lagrange方法 起作用集方法 直接消去法和广义消去法 前两种在教材上有详细描述
  • 二次规划_2_——起作用集方法

    这个算法很反人类 xff0c 迭代过程相当复杂 xff0c 最优化老师说 xff1a 明确地告诉你要考的 起作用集方法适用于消元法和Lagrange方法无法处理的不等式约束二次规化问题 其主要思想是 xff1a 以已知点为可行点 xff0c
  • 约束非线性优化:几何意义&对偶形式

    借助老师的PPT对约束非线性优化问题的几何意义 和对偶形式 进行阐述 一 几何意义 xff08 1 xff09 等式约束 考虑只有等式约束h x 的非线性优化问题 xff0c 形式为 xff1a 可视化结果如下图所示 xff0c 红色曲线为
  • 转载篇:优秀博文汇总

    1 Pytorch中堆网络语法 xff1a nn moduleList 和Sequential由来 用法和实例 写网络模型 https blog csdn net e01528 article details 84397174 2 CNN中
  • 批量归一化:Batch Normalization层 原理+Pytorch实现

    一 BN层概念明晰 BN层存在的意义 xff1a 让较深的神经网络的训练变得更加容易 BN层的工作内容 xff1a 利用小批量数据样本的均值和标准差 xff0c 不断调整神经网络中间输出 xff0c 使整个神经网络在各层的中间输出的数值更加
  • 模型量化——基础知识 & LSQ论文阅读

    感谢陈老师给的机会 xff0c 有幸能够参加2020年的DAC比赛 我在其中负责目标检测器的调试和量化 自己第一次接触量化这个任务 xff0c 很多东西都是一点一点学 一 量化基础 对于一个全精度的值 v v v xff0c 若量化步长为
  • python3安装tensorflow遇到的问题

    1 使用命令 xff1a sudo pip3 install upgrade https storage googleapis com tensorflow linux cpu tensorflow 1 1 0rc2 cp35 cp35m
  • argparse模块使用说明

    深度学习的工程中 xff0c py文件中的main函数一开始总会有大量的参数传入 xff0c 而通常使用的方法就是使用argparse通过命令行传入 xff0c 这篇博文旨在记录argparse的常用方法 一 语句简介 1 载入argpar
  • Tensorboard在网络训练中的Logger使用方法

    做为神经网络训练中最常用的可视化工具 xff0c Tensorboard经常在Pytorch和Tensorflow框架中做为可视化工具 但是其使用的确是有点繁琐 xff0c 所以开设了一个这样的专题 xff0c 用于总结见过的工程里面的数据
  • Pytorch训练流程

    调试了很久YOLO的标准Pytorch实现 xff0c 将Train代码进行了重新整理 xff0c 抽出了标准的Pytorch训练框架 现在整理下来 xff0c 以备后用 整理后的代码分为三个大部分 xff0c 每个大部分分为三个小部分 x
  • 初识Vulkan渲染管线

    目前参考 Vulkan规范 和 Vulkan开发实战详解 对渲染管线有了一个初步的认识 现结合中英文的渲染管线图进行笔记整理 中英文的渲染管线图分别如下所示 xff1a 绘制命令送入设备队列执行后 xff0c Vulkan将原始的物体顶点坐
  • Vulkan着色器的GLSL创建、编译、加载、创建流程

    Vulkan没有指定官方的着色器编程语言 xff0c 而是采用SPIR V二进制中间格式进行表示 开发人员一般需要基于某种着色器编程语言开发着色器 xff0c 之后再编译为SPIR V格式 可以选用GLSL着色器编程语言进行开发 大型游戏场