Skip to content

基本运算

运算符描述例子
+加法x = y + 2
-减法x = y - 2
*乘法x = y * 2
/除法x = y / 2
++自增x = ++y 或者 x = y++
--自减x = --y 或者 x = y--

赋值运算符

运算符描述例子
=赋值等于x = y
+=加等于x += y
-=减等于x -= y
*=乘等于x *= y
/=除等于x /= y

比较运算

运算符描述比较
==等于x == 8
!=不等于x != 8
>大于x > 8
<小于x < 8
>=大于或等于x >= 8
<=小于或等于x <= 8

逻辑运算符

运算符描述例子
&&true&&true=true;
| |
!!false=true;
^^异或false^^true=true; true^^true=false;(用处基本等于!=)

三元运算

GLSL
float f = 2 > 3 ? 1.0 : 2.0;
float f = 2 > 3 ? 1.0 : 2.0;

向量运算

向量可以与以下数据进行各种运算:单独数字向量矩阵

向量与常数:向量与常数进行加、减、乘、除就是向量各分量皆进行加、减、乘、除即可。

GLSL
// 加法
vec4 v1 = v + f; // = (x + f, y + f, z + f, w + f)
// 减法
vec4 v1 = v - f; // = (x - f, y - f, z - f, w - f)
// 乘法
vec4 v1 = v * f; // = (x * f, y * f, z * f, w * f)
// 除法
vec4 v1 = v / f; // = (x / f, y / f, z / f, w / f)
// 加法
vec4 v1 = v + f; // = (x + f, y + f, z + f, w + f)
// 减法
vec4 v1 = v - f; // = (x - f, y - f, z - f, w - f)
// 乘法
vec4 v1 = v * f; // = (x * f, y * f, z * f, w * f)
// 除法
vec4 v1 = v / f; // = (x / f, y / f, z / f, w / f)

向量与向量:向量与向量之间运算之后会返回一个新的向量,不过两个向量必须维度相同才能就行运算。

GLSL
// 加法
vec4 v3 = v1 + v2; // = (x1 + x2, y1 + y2, z1 + z2, w1 + w2)
// 减法
vec4 v3 = v1 - v2; // = (x1 - x2, y1 - y2, z1 - z2, w1 - w2)
// 乘法
vec4 v3 = v1 * v2; // = (v1 * v2, y1 * y2, z1 * z2, w1 * w2)
// 减法
vec4 v3 = v1 / v2; // = (x1 / x2, y1 / y2, z1 / z2, w1 / w2)
// 加法
vec4 v3 = v1 + v2; // = (x1 + x2, y1 + y2, z1 + z2, w1 + w2)
// 减法
vec4 v3 = v1 - v2; // = (x1 - x2, y1 - y2, z1 - z2, w1 - w2)
// 乘法
vec4 v3 = v1 * v2; // = (v1 * v2, y1 * y2, z1 * z2, w1 * w2)
// 减法
vec4 v3 = v1 / v2; // = (x1 / x2, y1 / y2, z1 / z2, w1 / w2)

注意:

向量的乘法是有三种的,还有两种是 点乘叉乘

GLSL
// 点乘
float v3 = dot(v1, v2);
// 叉乘
float v3 = cross(v1, v2);
// 点乘
float v3 = dot(v1, v2);
// 叉乘
float v3 = cross(v1, v2);

矩阵运算

矩阵与常数

矩阵与单个数字的运算(将其中的每一项分别和该数字进行运算)。

矩阵与矩阵的加法、减法、除法

相同索引位置的元素相加、相减、相除。

矩阵与向量相乘

  • 矩阵右乘向量

矩阵右乘向量的结果是向量,其中每个分量都是原向量中的对应分量,乘上矩阵对应行的每个元素的积的加和。这里要把向量当做 3 行 1 列的矩阵,矩阵的 3 × 3 的矩阵乘以 3 × 1 的矩阵,就是 3 × 1 向量。

GLSL
v3b = m3a * v3a 
// v3b.x = m3a[0].x * v3a.x + m3a[1].x * v3a.y + m3a[2].x * v3a.z
// v3b.y = m3a[0].y * v3a.x + m3a[1].y * v3a.y + m3a[2].y * v3a.z
// v3b.z = m3a[0].z * v3a.x + m3a[1].z * v3a.y + m3a[2].z * v3a.z
v3b = m3a * v3a 
// v3b.x = m3a[0].x * v3a.x + m3a[1].x * v3a.y + m3a[2].x * v3a.z
// v3b.y = m3a[0].y * v3a.x + m3a[1].y * v3a.y + m3a[2].y * v3a.z
// v3b.z = m3a[0].z * v3a.x + m3a[1].z * v3a.y + m3a[2].z * v3a.z
  • 矩阵左乘向量

矩阵左乘也是可以,但是结果与右乘不同,可以将向量想象成 1 × 3 的矩阵,乘以 3 × 3 的矩阵,就是 1 × 3 的向量。

GLSL
v3b = v3a * m3a  
// v3b.x = v3a.x * m3a[0].x + v3a.y * m3a[0].y + v3a.z * m3a[0].z
// v3b.y = v3a.x * m3a[1].x + v3a.y * m3a[1].y + v3a.z * m3a[1].z
// v3b.z = v3a.x * m3a[2].x + v3a.y * m3a[2].y + v3a.z * m3a[2].z
v3b = v3a * m3a  
// v3b.x = v3a.x * m3a[0].x + v3a.y * m3a[0].y + v3a.z * m3a[0].z
// v3b.y = v3a.x * m3a[1].x + v3a.y * m3a[1].y + v3a.z * m3a[1].z
// v3b.z = v3a.x * m3a[2].x + v3a.y * m3a[2].y + v3a.z * m3a[2].z

矩阵与矩阵相乘

就是线性代数中的矩阵相乘。

(M x N) 矩阵与 (N x P) 矩阵相乘,得到 (M x P) 矩阵。

计算的结果矩阵第 i 行第 j 列的元素,是矩阵 A 的第 i 行与矩阵 B 的第 j 列的元素相乘和。

GLSL
m3c = m3a * m3b  
// m3c[0].x = m3a[0].x * m3b[0].x + m3a[1].x * m3b[0].y + m3a[2].x * m3b[0].z
// m3c[1].x = m3a[0].y * m3b[0].x + m3a[1].x * m3b[0].y + m3a[2].x * m3b[0].z
// m3c[2].x = m3a[0].x * m3b[0].x + m3a[1].x * m3b[0].y + m3a[2].x * m3b[0].z

// m3c[0].y = m3a[0].y * m3b[0].x + m3a[1].y * m3b[0].y + m3a[2].y * m3b[0].z
// m3c[1].y = m3a[0].y * m3b[0].x + m3a[1].y * m3b[0].y + m3a[2].y * m3b[0].z
// m3c[2].y = m3a[0].y * m3b[0].x + m3a[1].y * m3b[0].y + m3a[2].y * m3b[0].z

// m3c[0].z = m3a[0].z * m3b[0].x + m3a[1].z * m3b[0].y + m3a[2].z * m3b[0].z
// m3c[1].z = m3a[0].z * m3b[0].x + m3a[1].z * m3b[0].y + m3a[2].z * m3b[0].z
// m3c[2].z = m3a[0].z * m3b[0].x + m3a[1].z * m3b[0].y + m3a[2].z * m3b[0].z
m3c = m3a * m3b  
// m3c[0].x = m3a[0].x * m3b[0].x + m3a[1].x * m3b[0].y + m3a[2].x * m3b[0].z
// m3c[1].x = m3a[0].y * m3b[0].x + m3a[1].x * m3b[0].y + m3a[2].x * m3b[0].z
// m3c[2].x = m3a[0].x * m3b[0].x + m3a[1].x * m3b[0].y + m3a[2].x * m3b[0].z

// m3c[0].y = m3a[0].y * m3b[0].x + m3a[1].y * m3b[0].y + m3a[2].y * m3b[0].z
// m3c[1].y = m3a[0].y * m3b[0].x + m3a[1].y * m3b[0].y + m3a[2].y * m3b[0].z
// m3c[2].y = m3a[0].y * m3b[0].x + m3a[1].y * m3b[0].y + m3a[2].y * m3b[0].z

// m3c[0].z = m3a[0].z * m3b[0].x + m3a[1].z * m3b[0].y + m3a[2].z * m3b[0].z
// m3c[1].z = m3a[0].z * m3b[0].x + m3a[1].z * m3b[0].y + m3a[2].z * m3b[0].z
// m3c[2].z = m3a[0].z * m3b[0].x + m3a[1].z * m3b[0].y + m3a[2].z * m3b[0].z

求转置、求逆

GLSL
mat4 m0 = mat4(1.0);
// 转置
mat4 m1 = transpose(m0);
// 求逆
mat4 m2 = inverse(m0);
mat4 m0 = mat4(1.0);
// 转置
mat4 m1 = transpose(m0);
// 求逆
mat4 m2 = inverse(m0);

结构体的运算

结构体的成员可以参与其自身类型支持的任何运算,但是结构体本身只支持两种运算:赋值(=)和比较(== 和 !=)。

运算符运算描述
=赋值赋值和比较运算符不适用于含有数组与纹理成员的结构体
==,!=比较赋值和比较运算符不适用于含有数组与纹理成员的结构体

当且仅当两个结构体变量所对应的所有成员都相等时,== 运算符才会返回 true。