GLSL是学习webgl的必备的知识点,故整理这篇文章

前言

GLSL Shader Example,这是一份不错的练习例子。

1. 变量

1.1 基本类型

变量类型说明
bool布尔型标量数据类型
int/ivec2/ivec3/ivec4包含 1/2/3/4 个整型向量
float/vec2/vec3/vec4包含 1,2,3,4 个浮点型向量
sampler2D表示 2D 纹理
samplerCube表示立方体纹理
mat[2..3]表示 2x2 和 3x3 的矩阵
mat4表示 4x4 的矩阵
sampler1D用于内建的纹理函数中引用指定的 1D 纹理的句柄。只可以作为一致变量或者函数参数使用
sampler2D二维纹理句柄
sampler3D三维纹理句柄
samplerCubecube map 纹理句柄
sampler1DShadow一维深度纹理句柄
sampler2DShadow二维深度纹理句柄

1.2 内置变量

顶点着色器可用的内置变量如下表:

名称类型描述
gl_Colorvec4输入属性-表示顶点的主颜色
gl_SecondaryColorvec4输入属性-表示顶点的辅助颜色
gl_Normalvec3输入属性-表示顶点的法线值
gl_Vertexvec4输入属性-表示物体空间的顶点位置
gl_MultiTexCoordnvec4输入属性-表示顶点的第 n 个纹理的坐标
gl_FogCoordfloat输入属性-表示顶点的雾坐标
gl_Positionvec4输出属性-变换后的顶点的位置,用于后面的固定的裁剪等操作。所有的顶点着色器都必须写这个值。
gl_ClipVertexvec4输出坐标,用于用户裁剪平面的裁剪
gl_PointSizefloat点的大小
gl_FrontColorvec4正面的主颜色的 varying 输出
gl_BackColorvec4背面主颜色的 varying 输出
gl_FrontSecondaryColorvec4正面的辅助颜色的 varying 输出
gl_BackSecondaryColorvec4背面的辅助颜色的 varying 输出
gl_TexCoord[]vec4纹理坐标的数组 varying 输出
gl_FogFragCoordfloat雾坐标的 varying 输出

片段着色器的内置变量如下表:

名称类型描述
gl_Colorvec4包含主颜色的插值只读输入
gl_SecondaryColorvec4包含辅助颜色的插值只读输入
gl_TexCoord[]vec4包含纹理坐标数组的插值只读输入
gl_FogFragCoordfloat包含雾坐标的插值只读输入
gl_FragCoordvec4只读输入,窗口的 x,y,z 和 1/w
gl_FrontFacingbool只读输入,如果是窗口正面图元的一部分,则这个值为 true
gl_PointCoordvec2点精灵的二维空间坐标范围在(0.0, 0.0)到(1.0, 1.0)之间,仅用于点图元和点精灵开启的情况下。
gl_FragData[]vec4使用 glDrawBuffers 输出的数据数组。不能与 gl_FragColor 结合使用。
gl_FragColorvec4输出的颜色用于随后的像素操作
gl_FragDepthfloat输出的深度用于随后的像素操作,如果这个值没有被写,则使用固定功能管线的深度值代替

2. 修饰符

变量的声明可以使用如下的修饰符:

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

3. 数组

GLSL中只能使用一维数组。数组的类型可以是一切基本类型或者结构体。声明方式如下:

vec4 transMatrix[4];

vec4 affineMatrix[4] = {0, 1, 2, 3};

vec4 rotateMatrix = affineMatrix;

4. 结构体

struct rotateMatrix {
  float x;

  float y;

  float z;

  float coeff[8];
}

struct positionInfo {
  vec2 coord;

  float value;

  rotateMatrix matrix;
}

5. 控制结构

5.1 循环

for (int s = 0; s < 7; s++) {
vec2 r;
r = vec2(cos(uv.y * i0 - i4 + time / i1), sin(uv.x * i0 - i4 + time / i1)) / i2;
r += vec2(-r.y, r.x) * 0.3;
uv.xy += r;

i0 *= 1.93;
i1 *= 1.15;
i2 *= 1.7;
i4 += 0.05 + 0.1 * time * i1;
}

5.2 控制语句

与js一致,注意没有switch语句,且if过多会消耗性能。

if(express) {

}

6. 函数

6.1 自定义函数

float noise(in vec2 pt) {

  return snoise(pt) * 0.5 + 0.5;

}

6.2 内置函数

  • 常用函数
语法说明
genType abs (genType x)x的绝对值
genType sign (genType x)判断x是正数、负数,还是零
genType floor (genType x)返回不大于x的最大整数
genType ceil (genType x)返回不小于x的最小整数
genType fract (genType x)返回x的小数部分,即x-floor(x)
genType mod (genType x, genType y)返回x – y * floor (x/y)
genType min (genType x, genType y)返回x和y的较小值
genType max (genType x, genType y)返回x和y的较大值
genType clamp (genType x, genType minVal, genType maxVal)min (max (x, minVal), maxVal),如果minVal > maxVal,则返回undefined
genType mix (genType x, genType y, genType a)返回x (1−a) + y a

参考文章


看见了
840 声望13 粉丝

前端开发,略懂后台;