译者注:直译为***画布元素着色器***下文中将意译成2D着色器
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 FRAGCOORD | Fragment coordinate, pixel adjusted. |
inout vec3 NORMAL | Normal read from NORMAL_TEXTURE. Writable. |
out vec3 NORMALMAP | Configures normal maps meant for 3D for use in 2D. If used, overwrites NORMAL. |
inout float NORMALMAP_DEPTH | Normalmap depth for scaling. |
in vec2 UV | UV from vertex function. |
inout vec4 COLOR | Color from vertex function and output fragment color. If unused, will be set to TEXTURE color. |
in sampler2D TEXTURE | Default 2D texture. |
in sampler2D NORMAL_TEXTURE | Default 2D normal texture. |
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)
|
in vec2 SCREEN_UV | Screen UV for use with SCREEN_TEXTURE. |
in vec2 SCREEN_PIXEL_SIZE | Size of individual pixels. Equal to inverse of resolution. |
in vec2 POINT_COORD | Coordinate for drawing points. |
in float TIME | Global time in seconds. |
in bool AT_LIGHT_PASS | True if this is a light pass. |
in sampler2D SCREEN_TEXTURE | Screen texture, mipmaps contain gaussian blurred versions. |
内置光属性(Light built-ins)
相对于3D着色器,2D着色器光函数的工作方式有所不同。在2D着色器中,光函数会在物体被绘制的时候调用一次,然后对场景中每一个触及到这个物体的光都调用一次。如果你不希望任何光影响到某一个物体可以使用unshaded
渲染模式。如果你只希望一个物体被光覆盖的地方可见,那么可以使用light_only
渲染模式。
当一个着色器(所属的物体)处于光照中时,内置光属性AT_LIGHT_PASS
的值将为true
内置光属性 | 描述 |
---|---|
in vec4 FRAGCOORD | Fragment coordinate of pixel center. Origin at lower left. |
in vec3 NORMAL | Input Normal. Although this value is passed in, normal calculation still happens outside of this function. |
in vec2 UV | UV from vertex function, equivalent to the UV in the fragment function. |
in vec4 COLOR | Input Color. This is the output of the fragment function with final modulation applied. |
sampler2D TEXTURE | Current texture in use for CanvasItem. |
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)
|
in vec2 SCREEN_UV | SCREEN_TEXTURE Coordinate (for using with screen texture). |
in vec2 POINT_COORD | UV for Point Sprite. |
in float TIME | Global time in seconds. |
inout vec2 LIGHT_VEC | Vector from light to fragment, can be modified to alter shadow computation. |
inout float LIGHT_HEIGHT | Height of Light. Only effective when normals are used. |
inout vec4 LIGHT_COLOR | Color of Light. |
in vec2 LIGHT_UV | UV for Light texture. |
out vec4 SHADOW_COLOR | Shadow Color of Light. |
inout vec4 LIGHT | Value from the Light texture and output color. Can be modified. If not used, the light function is ignored. |