译者注:直译为***画布项目着色器***下文中将意译成2D着色器
画布项目着色器(CanvasItem shaders)2D着色器用于绘制Godot中的所有的2D元素,包括所有继承于CanvasItem的节点以及所有的GUI元素。
相对于3D着色器,2D着色器要简单一些,内置函数也比较少,但是2D和3D着色器的基础结构是相同的,都包顶点函数(vertex
),片元函数(fragment
)及光(light
)函数
blend_mix
Mix blend mode (alpha is transparency), default.blend_add
Additive blend mode.blend_sub
Subtractive blend mode.blend_mul
Multiplicative blend mode.blend_premul_alpha
Pre-multiplied alpha blend mode.blend_disabled
Disable blending, values (including alpha) are written as-is.unshaded
Result is just albedo. No lighting/shading happens in material.light_only
Only draw on light pass.skip_vertex_transform
VERTEX/NORMAL/etc need to be transformed manually in vertex function.
译者注:vertex built-in,fragment built-in 以及 light built-in根据其实际作用分别被意译为内置顶点属性,内置片元属性以及内置光属性,"属性"一词借用C#中的属性即property,其实就是getter和setter
内置顶点属性(vertex built-ins)当值注明为in
时,意味着只读,当值注明为out
时,意味着可以选择性地写入,但是并不一定提供一个有效值。当值注明为inout
时,它会提供一个有效的默认值,并且可以选择性地写入。采样器(sampler)不是可写对象,它们也没有被标记。
顶点数据(VERTEX)使用局部坐标表示(相对于摄像机的像素坐标),如果不改写的话,它们的值会原封不动地传递出去。
用户可以关闭内置***模型视图变换***(英文:modelview transform,注:但投影(projection)依然会发生),并使用如下代码手动实现:
shader_type canvas_item;
render_mode skip_vertex_transform;
void vertex() {
VERTEX = (EXTRA_MATRIX * (WORLD_MATRIX * vec4(VERTEX, 0.0, 1.0))).xy;
}
注意:WORLD_MATRIX
实际上是一个模型视图矩阵,它接受局部坐标的输入,然后将其变换到视图空间。
如果想要获取一个顶点的世界坐标,你必须按照如下方法传入一个自定义的uniform值:
material.set_shader_param("global_transform", get_global_transform())
然后在你的顶点着色器部分:
uniform mat4 global_transform;
varying vec2 world_position;
void vertex(){
world_position = (global_transform * vec4(VERTEX, 0.0, 1.0)).xy;
}
然后在顶点和片元函数中就都可以使用world_position
了。
诸如 UV
和 COLOR
等一些内置成员,如果不加修改的话也会被传入片元函数。例如,INSTANCE_CUSTOM
变量包含着实例的自定义数据。在粒子中,这些数据往往如下所示:
-
x: Rotation angle in radians.
-
y: Phase during lifetime (0 to 1).
-
z: Animation frame.
in mat4 WORLD_MATRIX
图片空间(Image space)到视图空间(view space)的变换in mat4 EXTRA_MATRIX
Extra transform.in mat4 PROJECTION_MATRIX
View space to clip space transform.in float TIME
Global time, in seconds.in vec4 INSTANCE_CUSTOM
Instance custom data.in bool AT_LIGHT_PASS
True if this is a light pass.inout vec2 VERTEX
Vertex, in image space.in vec2 TEXTURE_PIXEL_SIZE
Normalized pixel size of default 2D texture. For a Sprite with a texture of size 64x32px, TEXTURE_PIXEL_SIZE = vec2(1/64, 1/32)inout vec2 UV
UV.inout vec4 COLOR
Color from vertex primitive.inout float POINT_SIZE
Point size for point drawing.
内置片元属性(Fragment built-ins)
一些节点(例如:Sprite),会显示一个默认的纹理。然而当给这些节点添加了自定义片元函数以后,纹理的查找则需要手动来完成。在内置属性COLOR
中,Godot并没有提供纹理的颜色。如果想在这些节点中读取纹理颜色,需要如下方法:
COLOR = texture(TEXTURE, UV);
这和法线贴图有所不同,如果一个节点添加了法线贴图,则Godot可以默认使用它并且把它赋值给内置的NORMAL
属性。如果你使用了一个本用于3D的法线贴图,它将呈现为翻转状态。如果你想在自己的Shader中使用它你需要把它赋值给NORMALMAP
属性,Godot会把它转换成2D模式并重写NORMAL
属性
NORMALMAP = texture(NORMAL_TEXTURE, UV).rgb;
内置片元属性描述in vec4 FRAGCOORDFragment coordinate, pixel adjusted.inout vec3 NORMALNormal read from NORMAL_TEXTURE. Writable.out vec3 NORMALMAPConfigures normal maps meant for 3D for use in 2D. If used, overwrites NORMAL.inout float NORMALMAP_DEPTHNormalmap depth for scaling.in vec2 UVUV from vertex function.inout vec4 COLORColor from vertex function and output fragment color. If unused, will be set to TEXTURE color.in sampler2D TEXTUREDefault 2D texture.in sampler2D NORMAL_TEXTUREDefault 2D normal texture.in vec2 TEXTURE_PIXEL_SIZENormalized pixel size of default 2D texture. For a Sprite with a texture of size 64x32px, TEXTURE_PIXEL_SIZE = vec2(1/64, 1/32)
in vec2 SCREEN_UVScreen UV for use with SCREEN_TEXTURE.in vec2 SCREEN_PIXEL_SIZESize of individual pixels. Equal to inverse of resolution.in vec2 POINT_COORDCoordinate for drawing points.in float TIMEGlobal time in seconds.in bool AT_LIGHT_PASSTrue if this is a light pass.in sampler2D SCREEN_TEXTUREScreen texture, mipmaps contain gaussian blurred versions.
内置光属性(Light built-ins)
相对于3D着色器,2D着色器光函数的工作方式有所不同。在2D着色器中,光函数会在物体被绘制的时候调用一次,然后对场景中每一个触及到这个物体的光都调用一次。如果你不希望任何光影响到某一个物体可以使用unshaded
渲染模式。如果你只希望一个物体被光覆盖的地方可见,那么可以使用light_only
渲染模式。
当一个着色器(所属的物体)处于光照中时,内置光属性AT_LIGHT_PASS
的值将为true
vec2(1/64, 1/32)
in vec2 SCREEN_UVSCREEN_TEXTURE Coordinate (for using with screen texture).in vec2 POINT_COORDUV for Point Sprite.in float TIMEGlobal time in seconds.inout vec2 LIGHT_VECVector from light to fragment, can be modified to alter shadow computation.inout float LIGHT_HEIGHTHeight of Light. Only effective when normals are used.inout vec4 LIGHT_COLORColor of Light.in vec2 LIGHT_UVUV for Light texture.out vec4 SHADOW_COLORShadow Color of Light.inout vec4 LIGHTValue from the Light texture and output color. Can be modified. If not used, the light function is ignored.