Vulkan着色器介绍(1)_weixin_38498942的博客-程序员宅基地_vulkan着色器语言

技术标签: Adreno GPU  

一、简介
与之前的图像API不同,Vulkan中的着色器代码必须以二进制字节码的格式使用,而不是像GLSL和HLSL这样具有比较好的可读性的语法。此字节格式称为SPIR-V,它可以与Vulkan和OpenCL一同使用,这是一种可以编写图形和计算着色器的格式。

二、Vulkan着色器
使用二进制字节码格式的优点之一是使得GPU厂商编写将着色器代码转换为本地代码的编译器复杂度减少了很多。同时Khronos发布了与厂商无关的编译器,它将GLSL编译成SPIR-V,该编译器用于验证着色器代码是否符合标准,并生成与Vulkan功能运行的SPRIR-V二进制文件,除此之外还可以将此编译器作为库在运行时编译生成SPRI-V。
GLSL是具有C风格语法的着色器语言,在程序中需要定义编写main函数作为入口。GLSL不会使用输入参数和返回值作为输出,而是使用全局变量来处理输入和输出。如OpenGL一般,我们需要编写一个vertex shader和一个fragment shader,最后会生成两个SPIR-V二进制文件,最后加载到程序中。
顶点着色器:
顶点着色器处理每一个顶点数据。它的属性,如世界坐标、颜色、法线和纹理UV坐标作为输入,输出的是最终的clip coordinates裁剪坐标和需要传递到片元着色器的属性,包括颜色和纹理UV坐标。这些值会在光栅化阶段进行内插值,以产生平滑的过度。
裁剪坐标clip coordinate是一个来此顶点的着色器的思维向量,随后通过矢量最后一个分量进行整体归一化操作,这些归一化的设备坐标最终会映射到缓冲范围为[-1,1]坐标系统。
我们一般可以通过将其输出为裁剪坐标直接输出归一化的设备坐标,顶点着色器的坐标与最后一个分量设置为1。通常情况下顶点坐标数据是存储在一个顶点缓冲区中,但是在vulkan中创建一个顶点缓冲区并填充数据的过程不是直接的。所以我们一般会置后这些步骤,直到我们满意的看到效果出现在屏幕上。同时我们需要做一些非正统的事情:将坐标直接包含在顶点着色器的内部:
#version 450
#extension GL_ARB_separate_shader_object:enable

out gl_PerVertex{
vec4 gl_position;
};

vec2 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变量包含了当前顶点的索引信息。通常是顶点缓冲区的索引,但是在这里我们硬编码到顶点数据的集合中。每个顶点的位置从常量数组中访问。内置的gl_Position变量作为输出。最后Vulkan中使用shader,需要确保GL_ARG_separate_shader_objects扩展开启。

片元着色器:
由顶点着色器的位置数据形成的三角形用片段着色器填充屏幕上的区域中。片段着色器针对一个或者多个framebuffer帧缓冲区的每个片元产生具体的颜色和深度信息。一个简单的片段着色器为完成的三角形输出红色信息的代码如下:
#version 450
#extension GL_ARB_separate_shader_objects:enable

layout(location = 0) out vec4 outColor;

void main(){
outColor = vec4(1.0,0.0,0.0,1.0);
}
fragment shader中的main函数与vertex shader中的main函数类似,会为每一个片元调用处理,颜色的信息在GLSL中是4个分量组成的矢量,包括R,G,B和Alpha通道,值域收敛在[0,1]范围内。不像顶点着色器的gl_Position,它没有内置的变量为当前片元输出颜色信息。在这里必须为framebuffer定义输出变量,layout(location = 0)修饰符明确framebuffer的索引。

顶点数组颜色:
当我们在顶点着色器中包含一个颜色数组,与位置信息的数组一样:
vec3 clolors[3] = vec3[](
vec3(1.0,0.0,0.0),
vec3(0.0,1.0,0.0),
vec3(0.0,0.0,1.0)
);
接下来我们需要将每个顶点的颜色传递到片段着色器中,从而输出经过插值后的颜色信息到framebuffer中。为顶点着色器添加输出颜色支持,在main函数中定义如下:
layout (location = 0)out vec3 fragColor;

void main(){
gl_Position = vec4(positions[gl_VertexIndex],0.0,1.0);
fragColor = colors[gl_VertexIndex];
}
下一步,我们需要将片段着色器的输入匹配顶点着色器的输出:
layout(location = 0)in vec3 fragColor;

void main(){
outColor = vec4(fragColor,1.0);
}
输入的变量不一定要同名,他们将通过location索引指令链接在一起。main函数中修改将要输出的颜色alpha值,fragColor将会为三个顶点所属的片元自动进行内插值,形成平滑的颜色过度。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_38498942/article/details/103785957

智能推荐

#uni-app# 组件复用_楚君君的博客-程序员宅基地_uniapp 组件复用

前言为什么需要组件复用,那是因为在实际开发里面,往往会有一些重复性的版块,这个时候为了减少代码的书写以及更高效地进行开发,我们就会用到组件复用提示:以下是本篇文章正文内容,下面案例可供参考下面的组件主要是排版相同的组件之间的复用,不涉及传值步骤:第一步:在目录——components里面,右键新建组件“test”第二步:在“test.Vue”组件里面,写出可复用组件的内容第三步:在需要用到复用组件的页面,进行引入、注册、使用复用组件引入:

redis mysql 整合demo_SpringBoot整合MyBatis并使用Redis作为缓存组件的Demo_Enzo 恩佐的博客-程序员宅基地

本博客 猫叔的博客,转载请申明出处Auth:HMStrange-TIAN e-mail:[email protected]历史文章安装流程1、安装docker & redis如果不清楚docker是什么,请查看docker的文档和简介,这里给出docker的安装过程1.1 安装虚拟机(如果有远程服务器的,请略过此步骤)本文推荐VMvare,尽管vmvare比较臃肿,但是对于新手比较...

python变量类型函数_python的数据类型和变量_weixin_39530269的博客-程序员宅基地

整数Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如:1,100,-8080,0,等等。计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff00,0xa5b4c3d2,等等。浮点数浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1....

005:C语言API示例【acos】_soft_and_hard_ware的博客-程序员宅基地

C语言API示例【acos】 函数名称:acos函数原型:double acos(double dValue)函数功能:获取反余弦值 函数示例:/*----------------------------------------------------------------------------------------------------*/#include

Linux查看物理CPU个数、核数、逻辑CPU个数_张伯毅的博客-程序员宅基地

# 总核数 = 物理CPU个数 X 每颗物理CPU的核数# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数# 查看物理CPU个数cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l# 查看每个物理CPU中core的个数(即核数)cat /proc/cpuinfo| grep "c...

随便推点

关于Android的一些设计_le4的博客-程序员宅基地

谈到应用程序设计,对设计师来说,Android就像是房间里的大象。很多设计师会更希望这是iOS,在那里所有任何人都只需要关心iPhone手机,iPad和App Store。然后没有人可以忽略Android,它目前已占据智能手机中最大的市场份额,且已经被广泛用于从平板电脑到电子阅读器等各种产品。总之,谷歌的Android平台正在迅速遍地开花,品牌厂商们很难不注意到。  让我们一起面对吧。Andr

c# 检测中英输入法_C# 切换中英文输入法_weixin_39941262的博客-程序员宅基地

在界面输入时,有时需要限定输入法。在不自定义正则表达式或者其它输入处理的情况下,切换中英文时与当前语言栏匹配,有以下的几种系统方案:InputLanguage方案1 /// 2 ///获取当前输入法3 /// 4 /// 5 private stringGetCultureType()6 {7 var currentInputLanguag...

struts2校验、ajax校验、javascript验证有何区别及联系?[email protected]的博客-程序员宅基地

struts2验证:Struts2的validate数据校验有两种方式:1.    Action中的validate()方法Struts2提供了一个Validateable接口,这个接口中只存在validate()方法,实现这个接口的类可直接被Struts2调用,ActionSupport类就实现了Vadidateable接口,但他的validate()方法是一个空方法,需要我们来重写。valid...

NotePad++更改背景颜色_weixin_34235105的博客-程序员宅基地

白色的编辑框看得眼睛不舒服,怎么样更改NotePad++的背景颜色使眼睛更舒服些?1.设置--语言格式设置2.设置背景色“背景色”一栏,选择背景色颜色   “使用全局背景色”一栏要打上√,否则无效参考网址:NotePad++更改背景颜色 ...

springCloud 之 Eureka注册中心高可用配置_zuixiaoyao_001的博客-程序员宅基地

  springCloud的eureka高可用配置方案思路是:几个服务中心之间相互注册,比如两个注册中心,A注册到B上,B注册到A上,如果是三个注册中心则是:A注册到BC上,B注册到AC上,C注册到AB上,这样就会在几个注册中心间进行同步,同时服务提供方向三个注册中心均注册,这样就会保证当一个服务注册中心宕机的时候,不影响整个系统的正常运行,从而保证了eureka的高可用。本博主在最后验...

iOS应用程序的脱壳实现原理浅析_weixin_34343689的博客-程序员宅基地

应用程序加载过程对于诸多逆向爱好者来说,给一个app脱壳是一项必做的事情。基于安全性的考虑,苹果对上架到appstore的应用都会进行加密处理,所以如果直接逆向一个从appstore下载的应用程序时,所能看到的“源代码”将非常的晦涩难懂。为了能看懂应用程序的“源代码”,就必须对应用程序进行解密,也就是所谓的脱壳。脱壳后的目的是可以分析应用程序的一些技术实现原理,或者利用一些漏洞进行攻击和测试。...