GLSL 内置函数

cross()

返回两个三维向量的叉积:一个同时垂直于两者的新向量。常用于构造法线和坐标系。

函数签名

vec3 cross(vec3 x, vec3 y)

参数

x
第一个三维向量。
y
第二个三维向量。

返回值

一个同时垂直于 x 和 y 的 vec3,长度为 length(x) * length(y) * 两者夹角的正弦。

在线示例

修改右侧代码,左侧预览会实时更新。

工作原理

cross(a, b) 构造第三个向量,它垂直于 a 和 b 所在的平面:

cross(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0)) // vec3(0.0, 0.0, 1.0)

顺序很重要,cross(b, a) 的方向正好相反。在右手坐标系中,右手四指从 a 弯向 b,拇指指的就是结果的方向。

示例不用任何网格就给一个起伏的表面打了光。它在每个像素构造两个沿表面延伸的向量(一个沿 x、一个沿 y,按坡度倾斜),cross 得到同时垂直于两者的向量,也就是表面法线。再用 dot 计算光照,起伏就显现出来了。

常见用法

  • 表面和三角形的法线:normalize(cross(edge1, edge2))。
  • 相机坐标系:已知前方方向和上方向,right = normalize(cross(forward, up)),up = cross(right, forward)。
  • 判断在哪一侧:在二维里,cross(a, b).z 的正负表示 b 在 a 的左边还是右边。

常见错误

  • 对 vec2 或 vec4 使用。cross 只有 vec3 版本。
  • 顺序写反,法线被翻转,表面看起来像是从背后被照亮。
  • 对两个平行向量做叉积。结果是零向量,再归一化就会得到 NaN。

相关函数