跳转至

GLSL变量修饰符

修饰符 描述
const 常量值必须在声明是初始化。它是只读的不可修改的。
attribute 表示只读的顶点数据,只用在顶点着色器中。数据来自当前的顶点状态或者顶点数组。它必须是全局范围声明的,不能再函数内部。一个attribute可以是浮点数类型的标量,向量,或者矩阵。不可以是数组或则结构体
uniform 一致变量。在着色器执行期间一致变量的值是不变的。与const常量不同的是,这个值在编译时期是未知的是由着色器外部初始化的。一致变量在顶点着色器和片段着色器之间是共享的。它也只能在全局范围进行声明。
varying 顶点着色器的输出。例如颜色或者纹理坐标,(插值后的数据)作为片段着色器的只读输入数据。必须是全局范围声明的全局变量。可以是浮点数类型的标量,向量,矩阵。不能是数组或者结构体。
centorid varying 在没有多重采样的情况下,与varying是一样的意思。在多重采样时,centorid varying在光栅化的图形内部进行求值而不是在片段中心的固定位置求值。
invariant (不变量)用于表示顶点着色器的输出和任何匹配片段着色器的输入,在不同的着色器中计算产生的值必须是一致的。所有的数据流和控制流,写入一个invariant变量的是一致的。编译器为了保证结果是完全一致的,需要放弃那些可能会导致不一致值的潜在的优化。除非必要,不要使用这个修饰符。在多通道渲染中避免z-fighting可能会使用到。
in 用在函数的参数中,表示这个参数是输入的,在函数中改变这个值,并不会影响对调用的函数产生副作用。(相当于C语言的传值),这个是函数参数默认的修饰符
out 用在函数的参数中,表示该参数是输出参数,值是会改变的。
inout 用在函数的参数,表示这个参数即是输入参数也是输出参数。

in、out

着色器的输入、输出,使得着色器之间可以进行数据交换与传递。

例:

  1. 顶点着色器

    #version 330 core
    layout (location = 0) in vec3 position; // position变量的属性位置值为0
    
    out vec4 vertexColor; // 为片段着色器指定一个颜色输出
    
    void main()
    {
        gl_Position = vec4(position, 1.0); // 注意我们如何把一个vec3作为vec4的构造器的参数
        vertexColor = vec4(0.5f, 0.0f, 0.0f, 1.0f); // 把输出变量设置为暗红色
    }
    

  2. 片元着色器

    #version 330 core
    in vec4 vertexColor; // 从顶点着色器传来的输入变量(名称相同、类型相同)
    
    out vec4 color; // 片段着色器输出的变量名可以任意命名,类型必须是vec4
    
    void main()
    {
        color = vertexColor;
    }
    

uniform与attribute

GLSL中uniform变量与attribute变量:uniform变量与顶点着色器中使用的属性attribute变量不同

  1. uniform变量:类似于全局变量,在整个着色器程序中都可见
  2. attribute变量:属性变量首先进入顶点着色器,如果要传递给片元着色器,需要在顶点着色器中定义输出变量,以此输出到片元着色器

varing与flat

在GLSL中,varyingflat都用于从顶点着色器传递数据到片元着色器,不同之处在于它们的插值方式不同。

共同点:

  • 都可以用于从顶点着色器向片元着色器传递数据。
  • 都需要在顶点着色器中声明,并在片元着色器中使用,且变量名需相同。

不同点:

  • varying变量会在图元中进行插值计算,生成一个平滑的过渡效果,而flat变量则不会进行插值计算,保持在整个图元中具有相同的属性值
  • varying变量可以是任意类型的(标量、向量或矩阵),而flat变量只能是标量或向量

参考文章

  1. OpenGL3:高级篇 GLSL