引言Godot 使用的了一种非常接近GLSL ES 3.0的着色器语言,并且支持其绝大多数的数据类型和函数尚未完全支持的部分也会逐渐增加进去。如果你对GLSL熟悉的话可以直接阅读 《Godot Shader Migration Guide》 以帮助你从标准GLSL过渡到Godot Shader。数据类型支持绝大多数GLSL ES 3.0数据类型:类型描述void空类型bool布尔型bvec22维布尔bvec33维布尔bvec44维布尔int有符号整型ivec22维整型ivec33维整型ivec44维整型uint无符号整型uvec22维无符号整型uvec33维无符号整型uvec44维无符号整型mat22维矩阵mat33维矩阵mat44维矩阵sampler2D2维采样 用于绑定2维材质以float形式读取isampler2D2维整型采样 用于绑定2维材质以int形式读取usampler2D2维无符号整型采样 用于绑定2维材质以uint形式读取samplerCude3维采样 用于绑定3维立方贴图以float形式读取类型转换(Casting)和GLSL ES 3.0一样无论是标量(Scalar)还是向量(Vector)即使维度(size)相同,但如果类型不同也是无法进行隐式(implicit)类型转换。如果连维度都不同则更加不能够隐式转换。所有的类型转换必须是显式(explicit)的且基于构造函数来实现。例子float a 2; // 非法 float a 2.0; // 合法 float a float(2); // 合法默认的整型是有符号的因此要赋值给无符号整型也需要进行类型转换int a 2; // 合法 uint a 2; // 非法 uint a uint(2); // 合法成员变量(Members)向量中的分量值可以使用“x”, “y”, “z” 或者“w”来访问同时也可已使用“r”, “g”, “b” 和“a”来访问二者是等效的。哪一个更加直观方便就可以使用哪一个。对于矩阵(matrices),可以使用m[row][colum]的形式访问其每一个元素或者以m[idx]的形式使用行索引(row index)访问一个行向量。例如访问一个mat4(4x4的矩阵)中的位置y,我们可以这样做m[3][1]。构造(Constructing)构造向量类型可以按照如下例子传参数:// 传递所需数量的分量参数 vec4 a vec4(0.0, 1.0, 2.0, 3.0); // 传递互补的 向量 及/或 标量 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); // 也可以为整个向量传一个值 vec4 a vec4(0.0);构造矩阵要求向量的维度和矩阵维精度(Precision)度相同当然你也可以使用matx(float)的形式构造一个对角矩阵(diagonal matrix),例如mat4(1.0)代表一个4维单位矩阵(identity matrix)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);矩阵可以由不同维度的矩阵创建但是要注意两个原则:如果用一个小维度矩阵创建一个大维度矩阵那么剩余的部分将由大维度矩阵的单位矩阵相对应值填充如果用一个大维度矩阵创建一个小维度矩阵那么将截取大维度矩阵左上角的子矩阵mat3 basis mat3(WORLD_MATRIX); mat4 m4 mat4(basis); mat2 m2 mat2(m4);混写(Swizzling)(注:Swizzling直译是旋转在此处的意译取网上的一种翻译混写)混写是指可以获取向量分量任意顺序的组合只要(组合的)结果依然是向量或者标量举个例子更好理解vec4 a vec4(0.0, 1.0, 2.0, 3.0); vec3 b a.rgb; // 用vec4的分量“混写”构造一个vec3 vec3 b a.ggg; // 依然合法; 用vec4的单一分量“混写”构造一个vec3 vec3 b a.bgr; // 分量的顺序是无关紧要的 vec3 b a.xyz; // 用xyzw依然等效 float c b.w; // 非法, 因为作为vec3的b中不包含w分量.精度(Precision)可以对uniform, variable, argument 以及 varying等数据添加精度修改器(modifier):lowp vec4 a vec4(0.0, 1.0, 2.0, 3.0); // 低精度, 每分量8字节并映射到0-1区间 mediump vec4 a vec4(0.0, 1.0, 2.0, 3.0); // 中等精度,每分量16字节或半长浮点精度 highp vec4 a vec4(0.0, 1.0, 2.0, 3.0); // 高精度 全长浮点精度或整型值域(默认)对于某些运算以损失精度为代价使用较低精度可以换取一些数学运算方面的提速。注意:在顶点处理函数(vertex processor function)几乎不会这样做(此时一般都采用高精度)但是在片元处理器中使用较低精度是很有效的。记住以移动设备为主的一些架构在这个机制上收益匪浅但也存在一些约束(主要是不同精度间的转换也存在一些计算量)。请阅读针对目标架构的相关文档获取更多信息。不过说实话移动设备的驱动Bug很多所以要避免麻烦的话请使用简单的shader而不要指定精度除非你真的需要。运算符(Operators)Godot 着色器语言支持和GLSL ES 3.0一样的运算符集。下面是按照优先级(precedence)排序的运算符列表:优先级类目运算符1 (最高)括号(parenthetical grouping)()2一元运算符(unary), -, !, ~3乘法类(multiplicative)/, *, %4加法类(additive), -5按位移动(bit-wise shift), 6逻辑(relational), , , 7相等(equality), !8按位与(bit-wise and)9逻辑异或(bit-wise exclusive or)^10按位或(bit-wise inclusive or)|11逻辑与(logical and)12 (最低)逻辑或(logical inclusive or)||分支控制(Flow control)Godot着色器语言支持大多数常见的过程控制形式:// if and else if (cond) { } else { } // for loops for (int i 0; i 10; i) { } // while while (true) { }注意:在现代GPU中死循环是可以存在的并且它可能会冻结你的程序(包括编辑器)。Godot无法保护你远离死循环所以请小心不要犯这种错误。丢弃(Discarding)在片元(fragment)和光处理函数中可以使用discard关键字。它将意味着片元被弃用。函数(Functions)在Godot着色器中可以使用如下语法定义函数:ret_type func_name(args) { return ret_type; // if returning a value } // 来个更具体的例子: int sum2(int a, int b) { return a b; }注意:当一个函数B要调用函数A时函数A一定在函数B之前。函数的参数可以有特殊限定符(qualifier):in: 只读out只写inout引用型例如:void sum2(int a, int b, inout int result) { result a b; }变元(Varyings)从顶点处理器函数(vertex processor function)向片元处理器函数(fragment processor function)传递参数时会用到变元。在顶点处理器中每一个初始顶点(primitive vertex)会被设置变元。在片元处理器中变元的值是对每一个像素的插值()interpolated。shader_type spatial; varying vec3 some_color; void vertex() { some_color NORMAL; // Make the normal the color. } void fragment() { ALBEDO some_color; }插值限定符(Interpolation qualifiers)某些值会在着色器管线(shading pipeline)中被插值。你可以使用插值限定符来修正这些插值是如何进行的。shader_type spatial; varying flat vec3 our_color; void vertex() { our_color COLOR.rgb; } void fragment() { ALBEDO our_color; }有两种可用的插值限定符:限定符描述flat不插值smooth以透视修正(perspective-correct)的方式插值。 此值为默认值。Uniform变量(程序)向着色器传递值是可以实现的。这些值被称为uniform变量它们对于整个着色器来说是全局的(global)。当一个着色器被指派给一个材质后uniform变量会作为可编辑参数显示在材质的编辑器上。注意:uniform变量无法由内而外写入shader_type spatial; uniform float some_value;你可以在编辑器中的材质栏中设置uniform变量也可以通过GDScriptmaterial.set_shader_param(some_value, some_value)注意:set_shader_param的第一个参数是shader中uniform变量的变量名它必须和shader中的uniform名字严格匹配否则将不会被识别。除void以外的任何GLSL类型都可以作为一个uniform变量。特别地Godot提供了一种可选的着色器提示(shader hint)来使编译器理解这个uniform变量的用途。shader_type spatial; uniform vec4 color : hint_color; uniform float amount : hint_range(0, 1); uniform vec4 other_color : hint_color vec4(1.0);着色器提示的列表如下:类型提示Descriptionvec4hint_color作为颜色使用int, floathint_range(min,max [,step] )作为范围使用sampler2Dhint_albedo作为慢反射颜色使用默认为白色sampler2Dhint_black_albedo作为慢反射颜色使用默认为黑色sampler2Dhint_normal作为法线贴图使用sampler2Dhint_white作为值使用默认为白色sampler2Dhint_black作为值使用默认为黑色sampler2Dhint_aniso作为流向图(flowmap)使用默认向右GDScript使用不同的数据类型体系所以当从GDScript传递变量到shader时Godot会自动转换类型。下面是二者的类型对照表:GDScript typeGLSL typeboolboolintintfloatfloatVector2vec2Vector3vec3Colorvec4Transformmat4Transform2Dmat4**注意:**在GDScript设置uniform变量的时候如果二者的类型不匹配godot不会抛出任何异常。只是你的着色器会产生一些未预期的行为。因为Godot的3D 引擎使用的是线性色彩空间(linear color space),所以有必要知道用来充当颜色的纹理(比如慢反射色)需要被设置为sRGB-linear。Uniform变量也可以指定默认值:shader_type spatial; uniform vec4 some_vector vec4(0.0); uniform vec4 some_color : hint_color vec4(1.0);译者注:以下部分内容涉及大量数学专业名词能力有限不确保翻译准确建议大家以英文版为准内置函数(Built-in functions)Godot提供大量的内置函数这些函数的形式和GLSL ES 3.0一致。函数的参数及返回值可以是标量也可以是向量。注意:在文档Differences between GLES2 and GLES3 doc 可以查到GLES2所不支持的函数列表。函数描述vec_typeradians( vec_type )将角度转为弧度vec_typedegrees( vec_type )将弧度转为角度vec_typesin( vec_type )正弦vec_typecos( vec_type )余弦vec_typetan( vec_type )正切vec_typeasin( vec_type )反正弦vec_typeacos( vec_type )反余vec_typeatan( vec_type )反正切vec_typeatan( vec_type x, vec_type y )Arc-Tangent to convert vector to anglevec_typesinh( vec_type )双曲正弦vec_typecosh( vec_type )双曲余弦vec_typetanh( vec_type )双曲正切vec_typeasinh( vec_type )反双曲正弦vec_typeacosh( vec_type )反双曲余弦vec_typeatanh( vec_type )反双曲正切vec_typepow( vec_type, vec_type )幂运算vec_typeexp( vec_type )e基指数vec_typeexp2( vec_type )2基指数vec_typelog( vec_type )e基(自然)对数vec_typelog2( vec_type )2基对数vec_typesqrt( vec_type )平方根vec_typeinversesqrt( vec_type )平方根倒数vec_typeabs( vec_type )绝对值vec_int_typeabs( vec_int_type )绝对值vec_typesign( vec_type )Signvec_int_typesign( vec_int_type )Signvec_typefloor( vec_type )向下取整vec_typeround( vec_type )四舍五入vec_typeroundEven( vec_type )四舍五入到临近偶数(Round nearest even)vec_typetrunc( vec_type )截断vec_typeceil( vec_type )向上取整vec_typefract( vec_type )取小数部分vec_typemod( vec_type, vec_type )取余vec_typemod( vec_type, float )取余vec_typemodf( vec_type x, out vec_type i )Fractional of x, with i has integer partvec_scalar_typemin( vec_scalar_type a, vec_scalar_type b )最小值vec_scalar_typemax( vec_scalar_type a, vec_scalar_type b )最大值vec_scalar_typeclamp( vec_scalar_type value, vec_scalar_type min, vec_scalar_type max )约束至最大值与最小值之间vec_typemix( vec_type a, vec_type b, float c )线性插值 (Scalar Coef.)vec_typemix( vec_type a, vec_type b, vec_type c )线性插值 (Vector Coef.)vec_typemix( vec_type a, vec_type b, bool c )线性插值 (Bool Selection)vec_typemix( vec_type a, vec_type b, vec_bool_type c )线性插值 (Bool-Vector Selection)vec_typestep( vec_type a, vec_type b )b[i] a[i] ? 0.0 : 1.0vec_typestep( float a, vec_type b )b[i] a ? 0.0 : 1.0vec_typesmoothstep( vec_type a, vec_type b, vec_type c )艾米插值vec_typesmoothstep( float a, float b, vec_type c )艾米插值vec_bool_typeisnan( vec_type )当标量或者向量分量为nan时返回truevec_bool_typeisinf( vec_type )当标量或者向量分量为inf时返回truevec_int_typefloatBitsToInt( vec_type )将Float按字节复制成Int, 不做类型转换vec_uint_typefloatBitsToUint( vec_type )将Float按字节复制成UInt, 不做类型转换vec_typeintBitsToFloat( vec_int_type )将Int按字节复制成Float, 不做类型转换vec_typeuintBitsToFloat( vec_uint_type )将UInt按字节复制成Float, 不做类型转换floatlength( vec_type )向量长度floatdistance( vec_type, vec_type )向量间距离floatdot( vec_type, vec_type )点积(Dot Product)vec3cross( vec3, vec3 )叉积(Cross Product)vec_typenormalize( vec_type )标准化成UInt长度vec3reflect( vec3 I, vec3 N )反射vec3refract( vec3 I, vec3 N, float eta )折射vec_typefaceforward( vec_type N, vec_type I, vec_type Nref )If dot(Nref, I) 0, return N, otherwise –Nmat_typematrixCompMult( mat_type, mat_type )Matrix Component Multiplicationmat_typeouterProduct( vec_type, vec_type )矩阵外积mat_typetranspose( mat_type )转置矩阵floatdeterminant( mat_type )矩阵行列式mat_typeinverse( mat_type )逆矩阵vec_bool_typelessThan( vec_scalar_type, vec_scalar_type )Bool vector cmp on int/uint/float vectorsvec_bool_typegreaterThan( vec_scalar_type, vec_scalar_type )Bool vector cmp on int/uint/float vectorsvec_bool_typelessThanEqual( vec_scalar_type, vec_scalar_type )Bool vector cmp on int/uint/float vectorsvec_bool_typegreaterThanEqual( vec_scalar_type, vec_scalar_type )Bool vector cmp on int/uint/float vectorsvec_bool_typeequal( vec_scalar_type, vec_scalar_type )Bool vector cmp on int/uint/float vectorsvec_bool_typenotEqual( vec_scalar_type, vec_scalar_type )Bool vector cmp on ! int/uint/float vectorsboolany( vec_bool_type )有任何一个分量为true则值为trueboolall( vec_bool_type )所有分量均为trueboolnot( vec_bool_type )所有分量均为falseivec2textureSize( sampler2D_type s, int lod )获取纹理大小ivec2textureSize( samplerCube s, int lod )获取立方映射(cubemap)的大小vec4_typetexture( sampler2D_type s, vec2 uv [, float bias] )Perform a 2D texture readvec4_typetexture( samplerCube s, vec3 uv [, float bias] )Perform a Cube texture readvec4_typetextureProj( sampler2D_type s, vec3 uv [, float bias] )Perform a texture read with projectionvec4_typetextureProj( sampler2D_type s, vec4 uv [, float bias] )Perform a texture read with projectionvec4_typetextureLod( sampler2D_type s, vec2 uv, float lod )Perform a 2D texture read at custom mipmapvec4_typetextureLod( samplerCube s, vec3 uv, float lod )Perform a Cube texture read at custom mipmapvec4_typetextureProjLod( sampler2D_type s, vec3 uv, float lod )Perform a texture read with projection/lodvec4_typetextureProjLod( sampler2D_type s, vec4 uv, float lod )Perform a texture read with projection/lodvec4_typetexelFetch( sampler2D_type s, ivec2 uv, int lod )用整数坐标获取一个纹理影像元件(texel)vec_typedFdx( vec_type )用局部差分对x求导vec_typedFdy( vec_type )用局部差分对y求导vec_typefwidth( vec_type )x和y的绝对导数之和
郑州网站建设
网页设计
企业官网