着色器语言之变量类型
前言
在看shader程序的时候,会发现在变量类型的前面总是会有些不同的单词符号,包括了uniform,attribute,varing,in,out一系列;接下来对这些东西进行一个总结;
uniform
其实就是统一变量,统一变量通常保存在所谓的“常量存储”中,可以看作一个向量数组;
uniform变量是外部application程序传递给(顶点和片元)着色器的变量,所以需要在外部程序中通过glUniform*函数进行赋值,在GLSL语言中,其类似于C语言中的常量const,它不能被shader程序修改,也就是个只读变量,只能读,不能更改。
attribute
属性限定符attribute用来定义一些特殊的变量,这些变量的值可以由应用程序提供,通过OpenGL ES传递给顶点着色器程序。属性限定符只能被用于顶点着色器中,在其他任何类型的着色器程序中使用属性限定符都会编译错误。
使用属性限定符修饰的变量在顶点着色器中是只读的,它的值来自应用程序通过OpenGL ES API或者顶点数组的一部分传递给顶点着色器,其类型只能是float、vec2、vec3、vec4、mat2、mat3或者mat4。
可以通过glGetIntegerv()方法查询GL_MAX_VERTEX_ATTRIBUTE,其表示当前图形硬件支持的最大属性存储空间数量。
varying
易变量限定符提供了一种接口和功能,它在顶点着色器和片段着色器中建立起了某种联系。易变变量在每个顶点被设置一个值,然后在一个图元范围内被线性差值。如果采用单重采样,每个插值表示的是对应片段中心的值;如果采用多重采样,每个插值可能来自采样区域内任意一个像素点。
片段着色器可以读取易变变量的值,这个值是根据当前片段在图元中的位置被插值计算的。片段着色器不能对易变变量进行赋值。
记得,其在顶点和片段着色中必须使用相同的类型和名称,否则编译失败。
同样的,可以通过glGetIntegerv()方法查询GL_MAX_VARYING_VECTOES,其表示当前图形硬件支持的最大易变变量的数量。
in/out
在新的glsl语言中,变化了相关的属性-顶点输入变量用于指定顶点着色器中每个顶点的输入,用in关键字指定。同样输出使用out。
同时,在变量之前使用了layout限定符,这种情况下的布局限定符用于指定顶点属性的索引,如果没有指定,链接程序将自动为顶点输入变量分配位置。
插值限定符
-
在没有限定符时,默认的插值行为是执行平滑着色,也就是说,来自顶点着色器的输出变量在图元中线性差值,片段着色器接收线性插值之后的数值作为输入。这种线性插值即在前面加上smooth,如果要明确的指定的话。
-
但是除了前面的插值,还有一种插值-平面着色,在平面着色器中,图元中的值没有进行插值,而是将其中一个顶点视为驱动顶点,该顶点的值被用于图元中的所有片段。这种只需要在前面加上flat。
-
最后,还有一种,即在前面加上centroid,centroid关键字在插值器中添加另一个限定符。本质上,centroid关键字可用于强制插值发生在被渲染图元内部。
// 顶点着色器输出 smooth centroid out vec3 v_color; // 片段着色器输出 smooth centroid in vec3 v_color;
补充
在gl es中,才会使用精度限定符。。。
![](https://i.loli.net/2018/11/17/5beff4d639cbb.jpg)
关注公众号:数据结构与算法那些事儿,每天一篇数据结构与算法