🌙 GLSL
GLSL全称是 Graphics Library Shader Language
(图形库着色器语言),是着色器使用的语言。 它有一些不同于JavaScript的特性,主要目的是为栅格化图形提供常用的计算功能。 GLSL语言结构类似于C语言,支持向量、矩阵、函数等基本数据类型和操作符,同时也支持控制结构、循环结构、条件结构等基本的程序结构。
🌙 变量限定符
限定符赋给变量特殊的含义:
const
: 用于声明非可写的编译时常量变量attribute
:用于经常更改的信息,只可以再顶点着色器中使用uniform
:用于不经常更改的信息,用于顶点着色器和片元着色器varying
:用于从顶点着色器
传递到片段着色器
的插值信息
🌙 变量声明
在GLSL中,变量需要先进行声明才能使用,声明方式与C语言相似,如下:
// 声明一个整型变量
int a;
// 声明一个浮点型变量
float b;
// 声明一个vec3类型的变量
vec3 c;
1
2
3
4
5
6
2
3
4
5
6
🌙 常量
在GLSL中,可以使用关键字"const"来定义常量。常量的定义必须在函数外部进行,且在编译时就确定其值,不能在运行时修改。常量可以是标量、矢量、矩阵或其他数据类型。例如:
const float PI = 3.14159;
const vec3 GRAVITY = vec3(0.0, -9.8, 0.0);
const mat4 IDENTITY_MATRIX = mat4(1.0);
1
2
3
2
3
GLSL中有几种不同类型的常量,包括:
- 数值常量:表示数值的常量,可以是整数或浮点数。例如:
- 整数常量:10, -5, 1000
- 浮点数常量:3.14, -2.5, 1.0e-6
- 布尔常量:表示真或假的常量。只有两个可能的值:true和false。
- 字符串常量:由一系列字符组成的常量。在GLSL中,字符串常量需要用双引号括起来。例如:"Hello, World!"
- 矢量常量:表示多个数值组成的常量。矢量常量可以是二维、三维或四维的。例如:
- 二维矢量常量:vec2(1.0, 2.0)
- 三维矢量常量:vec3(1.0, 2.0, 3.0)
- 四维矢量常量:vec4(1.0, 2.0, 3.0, 4.0)
- 矩阵常量:表示多个矢量组成的常量。矩阵常量可以是2x2、3x3或4x4的。例如:
- 2x2矩阵常量:mat2(1.0, 2.0, 3.0, 4.0)
- 3x3矩阵常量:mat3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)
- 4x4矩阵常量:mat4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0)
这些常量可以在GLSL程序中使用,并在执行期间保持不变。
🌙 数据类型
数据类型是编程语言中用于定义变量的属性和操作的分类。在GLSL中,常见的数据类型包括:
- 基本数据类型:
- 整数类型:int、uint。
- 浮点数类型:float、double。
- 布尔类型:bool。
- 向量类型:
- 2D 向量:vec2。
- 3D 向量:vec3。
- 4D 向量:vec4。
- 矩阵类型:
- 2x2 矩阵:mat2。
- 3x3 矩阵:mat3。
- 4x4 矩阵:mat4。
- 纹理类型:
取样器--用于纹理采样:
- sampler1D 访问一个一维纹理
- sampler2D 访问一个二维纹理
- sampler3D 访问一个三维纹理
- samplerCube 访问一个立方体纹理
- sampler1DShadow 访问一个带对比的一维深度纹理
- sampler2DShadow 访问一个带对比的二维深度纹理
- 其他类型:
- 结构体类型:struct, 结构体可以包含任意基础类型、向量类型、矩阵类型、数组类型和其他结构体类型。
struct dirlight{ vec3 direction; vec3 color; };
1
2
3
4- 数组类型:数组大小可以是常量或动态, 包含任意基础类型、向量类型、矩阵类型。
- 空类型:void。 这些数据类型具有不同的大小、精度和用途,可以根据需求选择适当的类型来存储和操作数据。
🌙 数据类型转换
在GLSL中,数据类型的转换不支持隐士类型转换,需要显示地通过类型函数来转换:
- 浮点数到整数:
float f = 3.14; int i = int(f); // 使用int()函数显式将浮点数转换为整数
1
2 - 整数到浮点数:
int i = 10;
float f = float(i); // 使用float()函数显式将整数转换为浮点数
1
2
2
- 整数到布尔值:
int i = 1;
bool b = bool(i); // 使用bool()函数显式将整数转换为布尔值(非零值转换为true,0转换为false)
1
2
2
需要注意的是,某些转换可能会导致数据丢失或精度损失,因此需要确保转换后的值的行为和正确性。
🌙 运算符
运算符是用于执行特定操作的符号或符号组合。在GLSL中,常见的运算符包括:
- 算术运算符:
- 加法:+
- 减法:-
- 乘法:*
- 除法:/
- 取余:%
- 关系运算符:
- 相等:==
- 不等:!=
- 大于:>
- 小于:<
- 大于等于:>=
- 小于等于:<=
- 逻辑运算符:
- 逻辑与:&&
- 逻辑或:||
- 逻辑非:!
- 赋值运算符:
- 简单赋值:=
- 加法赋值:+=
- 减法赋值:-=
- 乘法赋值:*=
- 除法赋值:/=
- 取余赋值:%=
- 位运算符:
- 按位与:&
- 按位或:|
- 按位异或:^
- 左移:<<
- 右移:>>
这些运算符可以用于执行各种数学、逻辑和位操作,以实现不同的计算和功能。
🌙 控制流
GLSL的控制流 与C++非常类似,可以使用for while
以及do-while
实现循环,也可以使用if
和if-else
进行选择
🌙 常用的内置变量
变量 | output还是input | 说明 |
---|---|---|
highp vec4 gl_Position | output | 用在顶点着色器,顶点坐标信息 |
mediump float gl_PointSize | output | 用在顶点着色器,需要绘制点的大小,(只在gl.POINTS模式下有效) |
mediump vec4 gl_FragCoord ; | input | 用在片元着色器,当前点的位置 |
bool gl_FrontFacing ; | input | 用在片元着色器,是否为正面片元 |
mediump vec2 gl_PointCoord ; | input | 用在片元着色器,经过插值计算后的纹理坐标 |
mediump vec4 gl_FragColor ; | output | 用在片元着色器,此像素点的颜色 |
mediump vec4 gl_FragData[n] | output | 用在片元着色器,当前片点的颜色,使用glDrawBuffers数据数组 |
🌙 常见的GLSL内置变量和函数
- sin(x): 正弦函数。
- cos(x): 余弦函数。
- tan(x): 正切函数。
- asin(x): 反正弦函数。
- acos(x): 反余弦函数。
- atan(y, x): 反正切函数,返回角度。
- pow(x, y): 计算幂。
- sqrt(x): 计算平方根。
- length(x): 返回向量的长度。
- normalize(x): 返回长度为1的向量。
- dot(x, y): 计算点积。
- cross(x, y): 计算叉积。