Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

着色语言

前言

Godot 使用类似于 GLSL ES 3.0 的着色语言。支持大多数数据类型和函数,并且可能会随着时间的推移添加剩余的几种类型和函数。

如果您已经熟悉 GLSL,Godot 着色器迁移指南是一个帮助您从常规 GLSL 转换到 Godot 着色语言的资源。

数据类型

支持大多数GLSL ES 3.0数据类型:

类型

描述

void

Void数据类型, 只对不返回任何内容的函数有用.

bool

布尔数据类型,只能包含 truefalse

bvec2

布尔值的两个分量向量.

bvec3

布尔值的三分量向量.

bvec4

布尔值的四分量向量.

int

带正负的符号标量整数.

ivec2

有符号整数的双分量向量.

ivec3

有符号整数的三分量向量.

ivec4

有符号整数的四分量向量.

uint

无符号标量整数, 不能包含负数.

uvec2

无符号整数的两分量向量.

uvec3

无符号整数的三分量向量.

uvec4

无符号整数的四分量向量.

float

浮点标量.

vec2

浮点值的两分量向量.

vec3

浮点值的三分量向量.

vec4

浮点值的四分量向量.

mat2

2x2矩阵, 按主要顺序排列.

mat3

3x3矩阵, 在列的主要顺序.

mat4

4x4矩阵, 按主要顺序排列.

sampler2D

用于绑定2D纹理的采样器类型, 以浮点形式读取.

isampler2D

用于绑定2D纹理的采样器类型, 它们被读取为有符号整数.

usampler2D

用于绑定2D纹理的采样器类型, 读取为无符号整数.

sampler2DArray

用于绑定2D纹理数组的采样器类型, 以浮点数形式读取.

isampler2DArray

用于绑定2D纹理数组的采样器类型, 以有符号整数形式读取.

usampler2DArray

用于绑定2D纹理数组的采样器类型, 以无符号整数形式读取.

sampler3D

用于绑定3D纹理的采样器类型, 以浮点形式读取.

isampler3D

用于绑定3D纹理的采样器类型, 以有符号整数形式读取.

usampler3D

用于绑定3D纹理的采样器类型, 以无符号整数形式读取.

samplerCube

用于绑定立方体贴图的采样器类型,作为 float 读取。

samplerCubeArray

用于绑定立方体贴图数组的采样器类型,作为 float 读取。

转换

就像GLSL ES 3.0一样, 不允许在标量和相同大小但不同类型的向量之间进行隐式转换. 也不允许铸造不同大小的类型. 转换必须通过构造函数明确完成.

示例:

float a = 2; // invalid
float a = 2.0; // valid
float a = float(2); // valid

默认整数常量是有符号的, 所以转换为无符号总是需要强制类型转换:

int a = 2; // valid
uint a = 2; // invalid
uint a = uint(2); // valid

成员

向量类型的单个标量成员通过 "x" , "y" , "z" 和 "w" 成员访问. 另外, 使用 "r" , "g" , "b" 和 "a" 也可以, 而且是等效的. 使用最适合你的需求的方法.

对于矩阵,使用 m[column][row] 索引语法来访问每个标量,或者 m[idx] 按行索引来访问一个向量。例如,为了访问 mat4 中一个对象的 y 位置,使用 m[3][1]

构建

向量类型的构造必须始终通过:

// The required amount of scalars
vec4 a = vec4(0.0, 1.0, 2.0, 3.0);
// Complementary vectors and/or scalars
vec4 a = vec4(vec2(0.0, 1.0), vec2(2.0, 3.0));
vec4 a = vec4(vec3(0.0, 1.0, 2.0), 3.0);
// A single scalar for the whole vector
vec4 a = vec4(0.0);

构建矩阵类型需要与矩阵相同维度的向量. 你也可以使用 matx(float) 语法构建一个对角矩阵. 相应地, mat4(1.0) 是一个单位矩阵.

mat2 m2 = mat2(vec2(1.0, 0.0), vec2(0.0, 1.0));
mat3 m3 = mat3(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0));
mat4 identity = mat4(1.0);

Matrices can also be built from a matrix of another dimension. There are two rules:

1. If a larger matrix is constructed from a smaller matrix, the additional rows and columns are set to the values they would have in an identity matrix. 2. If a smaller matrix is constructed from a larger matrix, the top, left submatrix of the larger matrix is used.

mat3 basis = mat3(MODEL_MATRIX);
mat4 m4 = mat4(basis);
mat2 m2 = mat2(m4);

混写Swizzling

只要结果是另一种向量类型(或标量), 就可以以任何顺序获得组件的组合. 这一点展示起来比解释起来容易:

vec4 a = vec4(0.0, 1.0, 2.0, 3.0);
vec3 b = a.rgb; // Creates a vec3 with vec4 components.
vec3 b = a.ggg; // Also valid; creates a vec3 and fills it with a single vec4 component.
vec3 b = a.bgr; // "b" will be vec3(2.0, 1.0, 0.0).
vec3 b = a.xyz; // Also rgba, xyzw are equivalent.
vec3 b = a.stp; // And stpq (for texture coordinates).
float c = b.w; // Invalid, because "w" is not present in vec3 b.
vec3 c = b.xrt; // Invalid, mixing different styles is forbidden.
b.rrr = a.rgb; // Invalid, assignment with duplication.
b.bgr = a.rgb; // Valid assignment. "b"'s "blue" component will be "a"'s "red" and vice versa.

精度

可以为数据类型添加精度修饰符;将它们用于 uniform、变量、参数、varying:

lowp vec4 a = vec4(0.0, 1.0, 2.0, 3.0); // low precision, usually 8 bits per component mapped to 0-1
mediump vec4 a = vec4(0.0, 1.0, 2.0, 3.0); // medium precision, usually 16 bits or half float
highp vec4 a = vec4(0.0, 1.0, 2.0, 3.0); // high precision, uses full float or integer range (default)

对某些操作使用较低的精度可以加快相关的数学运算(以较低的精度为代价). 这在顶点处理器功能中很少需要(大部分时间都需要全精度), 但在片段处理器中经常需要.

一些架构(主要是移动架构)可以从中受益匪浅, 但也有缺点, 比如在不同精度之间转换的额外开销. 请参考目标架构的文档以获得更多信息. 在许多情况下, 移动驱动会导致不一致或意外的行为, 除非有必要, 最好避免指定精度.

数组

Arrays are containers for multiple variables of a similar type.

局部数组

局部数组在函数中声明. 它们可以使用所有允许的数据类型, 但采样器除外. 数组声明遵循C-style的语法. [const] + [precision] + typename + identifier + [array size].

void fragment() {
    float arr[3];
}

它们可以在开始时进行初始化, 例如:

float float_arr[3] = float[3] (1.0, 0.5, 0.0); // first constructor

int int_arr[3] = int[] (2, 1, 0); // second constructor

vec2 vec2_arr[3] = { vec2(1.0, 1.0), vec2(0.5, 0.5), vec2(0.0, 0.0) }; // third constructor

bool bool_arr[] = { true, true, false }; // fourth constructor - size is defined automatically from the element count

您可以在一个表达式中声明多个数组(即使大小不同):

float a[3] = float[3] (1.0, 0.5, 0.0),
b[2] = { 1.0, 0.5 },
c[] = { 0.7 },
d = 0.0,
e[5];

要访问一个数组元素, 请使用索引语法:

float arr[3];

arr[0] = 1.0; <