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.

Spatial 着色器

空间着色器(Spatial shaders)用于对 3D 物体进行着色。它们是 Godot 提供的最复杂的一类着色器。空间着色器具有高度的可配置性,拥有不同的渲染模式和多样的渲染选项(例如次表面散射、透光、环境光遮蔽、边缘光等)。开发者可以选择性地编写顶点、片段和光照处理函数,来控制物体的具体绘制方式。

渲染模式

渲染模式的可视示例见《标准 3D 材质与 ORM 3D 材质》。

渲染模式

描述

blend_mix

混合混合模式(Alpha 为透明度),默认。

blend_add

添加混合模式。

blend_sub

减法混合模式。

blend_mul

乘法混合模式。

blend_premul_alpha

预乘 Alpha 混合模式(完全透明时采用相加混合,完全不透明时采用常规混合)。

depth_draw_opaque

仅绘制不透明几何体的深度(不透明)。

depth_draw_always

始终绘制深度(不透明和透明)。

depth_draw_never

不绘制深度。

depth_prepass_alpha

对透明几何体进行不透明的深度预渲染。

depth_test_disabled

禁用深度测试。

默认深度测试

深度测试会丢弃那些位于其他像素后方的像素。而且,仅在 Forward+(正向+)渲染模式下,如果像素与另一个像素处于完全相同的深度,它也会被丢弃。

反向深度测试

如果当前像素位于其他像素的前方,深度测试就会将其丢弃。这种模式对制作模板(stencil)特效非常有用。

sss_mode_skin

适用于皮肤的次表面散射模式(会针对人类皮肤优化视觉效果,比如增强红色通道)。

cull_back

剔除背面(默认)。

cull_front

剔除正面。

cull_disabled

禁用剔除(双面)。

unshaded

结果只使用反照率。材质中不会发生照明/阴影,渲染更快。

wireframe

几何体使用线条进行绘制(这对故障排查非常有用)。当使用兼容渲染器(Compatibility renderer)时,你必须在网格(mesh)加载 之前 调用 RenderingServer.set_debug_generate_wireframes(true) ,线框渲染才会生效。在兼容渲染器中,线框模式总是会禁用背面剔除(backface culling);而在 Forward+ 和 Mobile 渲染器中,则会正常遵循(网格原本的)剔除模式。

debug_shadow_splits

绘制方向阴影时为不同的拆分使用不同的颜色(常用于排查故障)。

diffuse_burley

漫反射使用 Burley(迪士尼 PBS)(默认值)。

diffuse_lambert

漫反射使用 Lambert 着色。

diffuse_lambert_wrap

漫反射使用 Lambert 环绕着色(受粗糙度影响)。

diffuse_toon

漫反射使用卡通着色。

specular_schlick_ggx

直接光照镜面反射高光使用 Schlick-GGX(默认)。

specular_toon

直接光照镜面反射高光使用 Toon。

specular_disabled

禁用直接光照镜面反射高光。不影响反射光(请改用 SPECULAR = 0.0)。

skip_vertex_transform

VERTEXNORMALTANGENTBITANGENT 等需要在 vertex() 函数中手动变换。

world_vertex_coords

VERTEXNORMALTANGENTBITANGENT 等在世界空间中修改,而不是模型空间。

ensure_correct_normals

当网格应用了非均匀缩放时使用 (注意:目前尚未实现)

shadows_disabled

禁用着色器中的阴影计算。该着色器将不会接收阴影,但仍然可以投射阴影。

ambient_light_disabled

禁用环境光和辐射度图的收益.

shadow_to_opacity

光照会改变 alpha 值,阴影部分是不透明的,而没有阴影的地方是透明的。对于 AR 中将阴影堆叠到同一个相机流很有用。

vertex_lighting

使用基于顶点的光照,而不是逐像素光照。

particle_trails

当应用于粒子几何体时,启用拖尾效果。

alpha_to_coverage

Alpha 抗锯齿模式,详见此处

alpha_to_coverage_and_one

Alpha 抗锯齿模式,详见此处

fog_disabled

禁用接收基于深度的雾效或体积雾。这对于像粒子特效这类使用 blend_add (加法混合)的材质非常有用。

模板模式

备注

模板(Stencil)支持目前仍处于实验阶段,请自行承担使用风险。我们会尽可能避免破坏兼容性,但如果在 API 中发现了重大缺陷,它可能会在下一个次要版本中发生变动。

模板操作(Stencil operations)是一系列允许以硬件加速的方式向高效缓冲区进行写入的操作。它通常被用来对场景的某些部分进行遮罩(Masking)处理,决定哪些该显示,哪些该隐藏。

一些最广为人知的用途包括:

  • 轮廓描边(Outlines):将需要描边的网格内部区域遮罩掉,以避免物体内部也出现描边。

  • X光透视(X-Ray):让网格模型能够显示在其他物体的后方。

  • 传送门(Portals):通过遮罩物体,来绘制那些在正常情况下“不可能存在”的(非欧几里得)几何结构。

备注

你只能在透明渲染通道(transparent pass)中读取模板缓冲区。任何尝试在不透明渲染通道(opaque pass)中读取的操作都会失败,因为目前还不支持这种行为。

需要注意的是,对于合成器特效(compositor effects),主渲染器的模板缓冲区是无法被复制到自定义纹理中的。

模板模式

描述

从模板缓冲区中读取数据。

将参考值写入模板缓冲区。

write_if_depth_fail

如果深度测试失败,则将参考值写入模板缓冲区。

始终通过比较

始终通过模板测试。

compare_equal

如果参考值(reference value)与模板缓冲区中的值相等,则通过模板测试。

compare_not_equal

如果参考值不等于模板缓冲区的值,则通过模板测试。

小于时通过比较

如果参考值小于模板缓冲区的值,则通过模板测试。

compare_less_or_equal

如果参考值小于或等于模板缓冲区的值,则通过模板测试。

大于时通过比较

如果参考值大于模板缓冲区的值,则通过模板测试。

大于或等于时通过比较

如果参考值大于或等于模板缓冲区的值,则通过模板测试。

内置

标记为 in (输入)的值是只读的。标记为 out (输出)的值可以被写入(赋值),但它们不一定包含有意义的初始值。标记为 inout (输入输出)的值会提供一个合理的默认值,并且可以被选择性地写入。采样器(Samplers)不能被写入,所以没有进行任何标记。

并非所有的内置变量在所有处理函数中都是可用的。如果你想从 fragment() 函数中访问顶点的内置变量,可以使用插值变量。同样的道理也适用于从 light() 函数中访问内置变量。

全局内置变量

全局的内置在所有地方均可用,包括自定义函数中。

内置

描述

in float TIME

自引擎启动以来的全局时间,以秒为单位。它每经过 3,600 秒就会重置循环一次(这个时长可以通过 rollover 设置来修改)。它受 time_scale (时间缩放/游戏速度)的影响,但不受暂停(pausing)的影响。如果你需要一个不受 time_scale 影响的 TIME 变量,可以添加你自己的 global shader uniform ,并在每一帧更新它。

in float PI

常量 PI (值为 3.141592 )。它是圆的周长与直径的比值,也是转半圈(180度)所包含的弧度数。

in float TAU

常量 TAU (值为 6.283185 )。它等同于 PI * 2 ,也就是一个完整圆周(整圈)所包含的弧度数。

in float E

常量 E (值为 2.718281 )。即欧拉数,自然对数的底数。

in bool OUTPUT_IS_SRGB

输出使用 sRGB 色彩空间时为 true(兼容渲染器中为 true,Forward+ 和移动渲染器中为 false)。

in float CLIP_SPACE_FAR

裁剪空间的远平面 z 值。在 Forward+(前向+)或 Mobile(移动端)渲染器中,它的值为 0.0 ;而在 Compatibility(兼容)渲染器中,它的值为 -1.0

在布尔值 IS_MULTIVIEW

当输出为立体(XR)时返回 true ,当输出为单目(普通平面)时返回 false

在布尔值 IN_SHADOW_PASS

当着色器正在阴影贴图(shadow mapping)渲染通道中进行渲染时,返回 true ;否则返回 false 。这可以让你在阴影贴图中的物体呈现出与常规渲染时不同的外观。

顶点内置

顶点数据( VERTEXNORMALTANGENTBITANGENT )是以模型空间(也称为局部空间)的形式呈现的。如果没有对它们进行写入(修改)操作,这些数值将保持原样不做改动,随后会被转换到视图空间,以便在 fragment() (片段)函数中使用。

它们可以选择性地以世界空间的形式呈现,只需使用 world_vertex_coords 渲染模式即可。

用户可以禁用内置的modelview变换(以后仍会发生投影), 并通过以下代码手动完成:

shader_type spatial;
render_mode skip_vertex_transform;

void vertex() {
    VERTEX = (MODELVIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
    NORMAL = normalize((MODELVIEW_MATRIX * vec4(NORMAL, 0.0)).xyz);
    BINORMAL = normalize((MODELVIEW_MATRIX * vec4(BINORMAL, 0.0)).xyz);
    TANGENT = normalize((MODELVIEW_MATRIX * vec4(TANGENT, 0.0)).xyz);
}

如果没有被修改,其他的内置变量(比如 UVUV2COLOR 等)也会直接传递给 fragment() (片段)函数。

用户可以通过内置变量 POSITION 来重写(覆盖)模型的视图和投影变换。只要在着色器的任何地方对 POSITION 进行了写入操作,它就一定会被采用。因此,用户就必须自己负责确保 POSITION 始终拥有一个可接受的有效值。当使用了 POSITION 时, VERTEX 的值会被忽略,并且引擎默认的投影过程也不会发生。不过,最终传递给片段着色器(fragment shader)的顶点值,依然来自于 VERTEX

对于实例化(Instancing), INSTANCE_CUSTOM 变量包含了实例的自定义数据。当使用粒子系统时,这些信息通常是:

  • x:旋转角度,单位为弧度。

  • y:生命周期的阶段(0.01.0)。

  • z:动画帧。

这让你能轻松地基于默认粒子材质,将 Shader(着色器)适配到粒子系统上。在编写自定义粒子 Shader 时,你可以随心所欲地利用这个值。

内置

描述

in vec2 VIEWPORT_SIZE

视口大小(单位为像素)。

in mat4 VIEW_MATRIX

世界空间到视图空间变换。

in mat4 INV_VIEW_MATRIX

视图空间到世界空间的变换。

in mat4 MAIN_CAM_INV_VIEW_MATRIX

用于绘制当前视口的摄像机,从视图空间到世界空间的变换。

in mat4 INV_PROJECTION_MATRIX

裁剪空间到视图空间的变换。

in vec3 NODE_POSITION_WORLD

节点的位置,使用世界空间。

in vec3 NODE_POSITION_VIEW

节点的位置,使用视图空间。

in vec3 CAMERA_POSITION_WORLD

摄像机在世界空间(world space)中的位置。当处于多视图(multiview)或立体(stereo)渲染模式时,它代表的是双眼之间的中心点。

in vec3 CAMERA_DIRECTION_WORLD

相机的方向,使用世界空间。

in uint CAMERA_VISIBLE_LAYERS

剔除当前渲染阶段中相机不渲染的图层。

in int INSTANCE_ID

实例化的实例 ID。

in vec4 INSTANCE_CUSTOM

实例自定义数据(主要用于粒子)。

in int VIEW_INDEX

我们正在渲染的视图。对于单视图(非多视图)或左眼视图,使用 VIEW_MONO_LEFT0),对于右眼视图使用 VIEW_RIGHT1)。

in int VIEW_MONO_LEFT

单视图或左眼视图的常量,恒为 0

in int VIEW_RIGHT

右眼视图常量,恒为 1

in vec3 EYE_OFFSET

当前正在渲染的(单只)眼睛在视图空间下的位置偏移量。仅适用于多视图(Multiview)渲染。

inout vec3 VERTEX

模型空间中的顶点位置。如果使用了 world_vertex_coords 则使用世界空间。

in int VERTEX_ID

顶点缓冲区中当前顶点的索引。

inout vec3 NORMAL

模型空间中的法线。如果使用了 world_vertex_coords 则使用世界空间。

inout vec3 TANGENT

模型空间中的切线。如果使用了 world_vertex_coords 则使用世界空间。

inout vec3 BINORMAL

模型空间中的副法线。如果使用了 world_vertex_coords 则使用世界空间。

out vec4 POSITION

如果在任何分支中被写入(赋值),它将覆盖裁剪空间中的最终顶点位置。

inout vec2 UV

UV主通道.

inout vec2 UV2

UV2辅助通道.

inout vec4 COLOR

来自顶点的颜色。每个通道的值限制在 0.01.0 之间,精度为每通道 8 位(即 256 个可能的层级)。支持 Alpha 通道(透明度)。超出允许范围的值会被钳制(强制限制在范围内),并且由于精度限制,数值可能会被舍入。如果需要更高的精度,请使用 CUSTOM0-CUSTOM3 来传递数据。

out float ROUGHNESS

顶点照明的粗糙度.

inout float POINT_SIZE

点渲染的点大小.

inout mat4 MODELVIEW_MATRIX

模型/局部空间到视图空间的变换(如果可能的话,请优先使用这个)。

inout mat3 MODELVIEW_NORMAL_MATRIX

in mat4 MODEL_MATRIX

模型/局部空间到世界空间的变换。

in mat3 MODEL_NORMAL_MATRIX

inout mat4 PROJECTION_MATRIX

视图空间向裁剪空间变换.

in uvec4 BONE_INDICES

in vec4 BONE_WEIGHTS

in vec4 CUSTOM0

来自顶点图元的自定义值。当使用额外的 UV 贴图时, xy 代表 UV3, zw 代表 UV4。

in vec4 CUSTOM1

来自顶点图元的自定义值。当使用额外的 UV 贴图时, xy 代表 UV5, zw 代表 UV6。

in vec4 CUSTOM2

来自顶点图元的自定义值。当使用额外的 UV 贴图时, xy 代表 UV7, zw 代表 UV8。

in vec4 CUSTOM3

来自顶点图元的自定义值。

out float Z_CLIP_SCALE

如果在任何分支中对其进行了写入(赋值),它会将顶点向相机方向进行缩放,以避免穿模到墙壁等物体里。当写入该值时,光照和阴影依然能正常工作,但如果缩放比例设置得过低,屏幕空间特效(如 SSAO 环境光遮蔽和 SSR 屏幕空间反射)可能会出现异常。尽量让该值保持在接近 1.0 的水平。

备注

MODELVIEW_MATRIX 结合了 MODEL_MATRIX (模型矩阵)和 VIEW_MATRIX (视图矩阵),在可能会出现浮点数精度问题的时候,使用它会更加稳妥。举个例子,如果物体距离世界原点非常远,当你分开使用 MODEL_MATRIXVIEW_MATRIX 时,就可能会遇到浮点数精度的问题。

备注

INV_VIEW_MATRIX 是在当前渲染通道(pass)中用来渲染物体的矩阵;而 MAIN_CAM_INV_VIEW_MATRIX 则是场景中主摄像机的矩阵。在阴影渲染通道(shadow pass)中, INV_VIEW_MATRIX 的视图是基于一个位于光源位置处的摄像机来设定的。

片段内置

Godot片段处理器函数的默认用法是设置对象的材质属性, 并让内置渲染器处理最终的阴影. 但是, 你无需使用所有这些属性, 如果你不写入它们,Godot将优化掉相应的功能.

内置

描述

in vec2 VIEWPORT_SIZE

视口大小(单位为像素)。

in vec4 FRAGCOORD

屏幕空间中像素中心的坐标。其中 xy 指定了该像素在窗口中的位置,坐标原点位于左上角 (0.0, 0.0) ,右下角为 (1.0, 1.0)z 则指定了片段的深度值。除非你在代码中显式地写入了 DEPTH 变量,否则 z 的值也会直接被当作该片段的最终深度输出值。

in bool FRONT_FACING

如果当前的面展示的是正面则为 true,否则为 false

in vec3 VIEW

片段位置到相机位置(在视图空间中)的归一化向量,该向量对于透视相机和正交相机而言是相同的。

in vec2 UV

来自 vertex() 函数的 UV。

in vec2 UV2

来自 vertex() 函数的 UV2。

in vec4 COLOR

来自 vertex() 函数的 COLOR。

in vec2 POINT_COORD

使用 POINT_SIZE 绘制点的点坐标。

in mat4 MODEL_MATRIX

模型/局部空间到世界空间的变换。

in mat3 MODEL_NORMAL_MATRIX

用于法线的 模型/局部空间 到 世界空间 的变换矩阵。默认情况下,它和 MODEL_MATRIX 是一样的;但如果物体进行了非均匀缩放,它就会被设定为 transpose(inverse(mat3(MODEL_MATRIX)))

in mat4 VIEW_MATRIX

世界空间到视图空间变换。

in mat4 INV_VIEW_MATRIX

视图空间到世界空间的变换。

in mat4 PROJECTION_MATRIX

视图空间向裁剪空间变换.

in mat4 INV_PROJECTION_MATRIX

裁剪空间到视图空间的变换。

in vec3 NODE_POSITION_WORLD

节点的位置,使用世界空间。

in vec3 NODE_POSITION_VIEW

节点的位置,使用视图空间。

in vec3 CAMERA_POSITION_WORLD

摄像机在世界空间(world space)中的位置。当处于多视图(multiview)或立体(stereo)渲染模式时,它代表的是双眼之间的中心点。

in vec3 CAMERA_DIRECTION_WORLD

相机的方向,使用世界空间。

in uint CAMERA_VISIBLE_LAYERS

剔除当前渲染阶段中相机不渲染的图层。

in vec3 VERTEX

片段(即像素)在视图空间中的位置。它是 vertex() 函数输出的 VERTEX 值,经过面片顶点插值后,再转换到视图空间的结果。如果启用了 skip_vertex_transform ,它可能就不在视图空间了。

inout vec3 LIGHT_VERTEX

一个可写的 VERTEX 版本,可用于调整光照和阴影的效果,对其写入数据时不会改变片段的位置。

in int VIEW_INDEX

当前正在渲染的视图。用于在多视图(multiview)或立体(stereo)渲染中区分不同的视图。 VIEW_MONO_LEFT0 )代表单视图(非多视图)或左眼, VIEW_RIGHT1 )代表右眼。

in int VIEW_MONO_LEFT

单视图或左眼视图的常量,恒为 0

in int VIEW_RIGHT

右眼视图常量,恒为 1

in vec3 EYE_OFFSET

当前正在渲染的(单只)眼睛在视图空间下的位置偏移量。仅适用于多视图(Multiview)渲染。

sampler2D SCREEN_TEXTURE

在 Godot 4 中移除。请改用 sampler2Dhint_screen_texture

in vec2 SCREEN_UV

当前像素的屏幕 UV 坐标。

sampler2D DEPTH_TEXTURE

在 Godot 4 中移除。请改用 sampler2Dhint_depth_texture

out float DEPTH

自定义深度值(取值范围 [0.0, 1.0] )。如果在 Shader 的任意一个分支中写入了 DEPTH ,那么你就必须负责为 所有 其他分支设置 DEPTH 。否则,图形 API 会使其保持未初始化状态。

inout vec3 NORMAL

源自 vertex() 函数的法线,处于视图空间中。如果启用了 skip_vertex_transform ,它可能就不在视图空间了。

inout vec3 TANGENT

源自 vertex() 函数的切线,处于视图空间中。如果启用了 skip_vertex_transform ,它可能就不在视图空间了。

inout vec3 BINORMAL

源自 vertex() 函数的副法线,处于视图空间中。如果启用了 skip_vertex_transform ,它可能就不在视图空间了。

out vec3 NORMAL_MAP

如果你是从纹理中读取法线,而不是直接使用 NORMAL ,请在这里(切线空间)设置法线。蓝色通道会被忽略,因为它会在引擎内部被重新计算出来。这种做法可以让使用了 RGTC 压缩的法线贴图正常工作。

out float NORMAL_MAP_DEPTH

NORMAL_MAP 中的深度。默认为 1.0

输出 vec3 NORMAL_MAP

在这里(切线空间)设置弯曲法线贴图,以启用 bent normals (弯曲法线)功能。这主要用于改善高光遮蔽(specular occlusion)的效果,并且需要你专门制作一张弯曲法线贴图。蓝色通道会被忽略,因为它会在引擎内部被重新计算出来。这种做法可以让使用了 RGTC 压缩的弯曲法线贴图正常工作。

out vec3 ALBEDO

反照率(默认为白色)。基础颜色。

out float ALPHA

Alpha(取值范围 [0.0, 1.0] )。如果对其进行读取或写入操作,该材质将会进入透明渲染管线。

out float ALPHA_SCISSOR_THRESHOLD

如果在任何分支中对其进行了写入(赋值),透明度(Alpha)低于特定数值的像素将会被丢弃。

out float ALPHA_HASH_SCALE

在使用 Alpha Hash 透明模式时的 Alpha 哈希缩放值。默认值为 1.0 。数值越高,抖动图案中可见的像素就越多。

out float ALPHA_ANTIALIASING_EDGE

启用 Alpha 覆盖抗锯齿的阈值下限。默认值为 0.0 。需要启用 alpha_to_coverage 渲染模式。为了使其生效,该值应设置为低于 ALPHA_SCISSOR_THRESHOLD (Alpha 裁切阈值)。

out vec2 ALPHA_TEXTURE_COORDINATE

用于 Alpha 覆盖抗锯齿(alpha-to-coverage antialiasing)的纹理坐标。需要启用 alpha_to_coverage 渲染模式。通常将其设置为 UV * vec2(albedo_texture_size) ,其中 albedo_texture_size 是反照率纹理(albedo texture)以像素为单位的尺寸。

输出浮点型变量 PREMUL_ALPHA_FACTOR (预乘 Alpha 因子)

预乘 Alpha 因子。仅在使用了 render_mode blend_premul_alpha; (渲染模式:预乘 Alpha 混合)时生效。当使用带有预乘 Alpha 混合的 着色 (shaded) 材质并需要与光照进行交互时,应当对该参数进行写入。对于 无着色(unshaded) 材质,则不需要这样做。

out float METALLIC

金属度(范围为 [0.0, 1.0] )。

out float SPECULAR

高光/镜面反射(修改此值在物理上并不准确)。默认值为 0.5 。设为 0.0 时会禁用反射。

out float ROUGHNESS

粗糙度(范围为 [0.0, 1.0] )。

out float RIM

边缘光强度(取值范围为 [0.0, 1.0] )。如果使用了该参数,Godot 就会计算边缘光效果。边缘光的大小取决于 ROUGHNESS (粗糙度)。

out float RIM_TINT

边缘光色调,取值范围从 0.0 (白色)到 1.0 (反照率/固有色)。如果使用了该参数,Godot 就会计算边缘光效果。

out float CLEARCOAT

在现有高光之上,额外叠加的一小块高光光斑。如果使用,Godot 将计算clearcoat层。

out float CLEARCOAT_GLOSS

clearcoat的光泽度。如果使用了该参数,Godot 就会计算clearcoat效果。

out float ANISOTROPY

用于根据切线空间扭曲镜面反射斑点。

out vec2 ANISOTROPY_FLOW

失真方向, 与流程图一起使用.

out float SSS_STRENGTH

次表面散射的强度。如果使用了该参数,次表面散射效果就会被应用到物体上。

out vec4 SSS_TRANSMITTANCE_COLOR

次表面散射透射的颜色。如果使用了该参数,次表面散射透射效果就会被应用到物体上。

out float SSS_TRANSMITTANCE_DEPTH

次表面散射透射的深度。数值越高,该效果就能穿透到物体的更深处。

out float SSS_TRANSMITTANCE_BOOST

如果该值设置得高于 0.0 ,会增强次表面散射的透射率。这使得即使在直接被光照亮的表面上,该效果也能显现出来

inout vec3 BACKLIGHT

背光的颜色(其作用类似于直射光,但即便物体表面的法线稍微背对光源,也能接收到这种光照)。如果使用了该参数,背光效果就会被应用到物体上。它可以被用作一种更节省性能的次表面散射(Subsurface Scattering)近似模拟。

out float AO

环境光遮蔽(Ambient Occlusion)的强度。配合预烘焙的 AO 贴图使用。

out float AO_LIGHT_AFFECT

环境光遮蔽(Ambient Occlusion)对直射光的影响程度(取值范围为 [0.0, 1.0] ,默认值为 0.0 )。

out vec3 EMISSION

自发光颜色(可以超过 (1.0, 1.0, 1.0) 以实现高动态范围 HDR 效果)。

out vec4 FOG

如果在任何分支中对其进行了写入(赋值),最终的像素颜色将会根据 FOG.a (雾效的透明度/浓度)与 FOG.rgb (雾效的颜色)进行混合。

out vec4 RADIANCE

如果在任何分支中对其进行了写入(赋值),环境贴图的光照强度(radiance)将会根据 RADIANCE.a (透明度/混合系数)与 RADIANCE.rgb (自定义的光照颜色)进行混合。

out vec4 IRRADIANCE

如果在任何分支中对其进行了写入(赋值),环境贴图的辐照度(irradiance)将会根据 IRRADIANCE.a (Alpha通道/混合系数)与 IRRADIANCE.rgb (自定义的辐照度颜色)进行混合。

备注

因为写入 ALPHA 而经过透明管线的着色器可能受到透明排序问题的影响。更多信息及解决方法请阅读3D 渲染限制页面的透明排序章节

内置灯光

编写光照处理函数是完全可选的。你可以通过使用 unshaded (无光照)渲染模式来跳过 light() 函数。如果没有编写任何光照函数,Godot 将会根据你在 fragment() 函数中设置的材质属性,自动为你计算光照(具体计算方式受渲染模式影响)。

light() 函数会在每一个像素上,针对每一盏灯各调用一次。它是在一个针对每种光源类型的循环中被调用的。

下面是一个使用兰伯特(Lambertian)光照模型的自定义 light() 函数示例:

void light() {
    if (LIGHT_IS_AREA) {
        // Area light GGX shading.
        DIFFUSE_LIGHT += LIGHT_AREA_DIFFUSE_MULTIPLIER * ATTENUATION * LIGHT_COLOR;
        SPECULAR_LIGHT += LIGHT_AREA_SPECULAR_MULTIPLIER * ATTENUATION * LIGHT_COLOR * SPECULAR_AMOUNT;
    } else {
        // Used for all other light types (directional, omni, spot).
        DIFFUSE_LIGHT += clamp(dot(NORMAL, LIGHT), 0.0, 1.0) * ATTENUATION * LIGHT_COLOR / PI;
    }
}

如果你想把这些光照加在一起,请使用 += 运算符将光线添加到 DIFFUSE_LIGHT 函数中,不要覆盖它。

警告

如果启用了 vertex_lighting (顶点光照)渲染模式,或者在项目设置中开启了 Rendering > Quality > Shading > Force Vertex Shading ,那么 light() 函数将不会被执行。(在移动平台上,该选项默认是开启的。)

内置

描述

in vec2 VIEWPORT_SIZE

视口大小(单位为像素)。

in vec4 FRAGCOORD

屏幕空间中像素中心的坐标。其中 xy 指定了该像素在窗口中的位置,坐标原点位于左上角 (0.0, 0.0) ,右下角为 (1.0, 1.0)z 则指定了片段的深度值。除非你在代码中显式地写入了 DEPTH 变量,否则 z 的值也会直接被当作该片段的最终深度输出值。

in mat4 MODEL_MATRIX

模型/局部空间到世界空间的变换。

in mat4 INV_VIEW_MATRIX

视图空间到世界空间的变换。

in mat4 VIEW_MATRIX

世界空间到视图空间变换。

in mat4 PROJECTION_MATRIX

视图空间向裁剪空间变换.

in mat4 INV_PROJECTION_MATRIX

裁剪空间到视图空间的变换。

in vec3 NORMAL

法向量, 在视图空间中.

in vec2 SCREEN_UV

当前像素的屏幕 UV 坐标。

in vec2 UV

来自 vertex() 函数的 UV。

in vec2 UV2

来自 vertex() 函数的 UV2。

in vec3 VIEW

视图向量, 在视图空间中.

in vec3 LIGHT

光照向量,处于观察空间(View Space)中。

in vec3 LIGHT_COLOR

Light color 乘以 light energy 再乘以 PI (圆周率)得出。之所以要乘以 PI ,是因为基于物理的渲染(PBR)光照模型在计算中通常会包含一个除以 PI 的步骤。

in float SPECULAR_AMOUNT

对于 OmniLight3DSpotLight3D ,数值为 2.0 乘以 light_specular ;对于 DirectionalLight3D ,数值固定为 1.0

in bool LIGHT_IS_DIRECTIONAL

如果当前的渲染通道(pass)属于 DirectionalLight3D,则返回 true

in float ATTENUATION

基于距离或阴影的衰减。

in vec3 ALBEDO

基础反照率。

in vec3 BACKLIGHT

in float METALLIC

Metallic(金属度)。

in float ROUGHNESS

粗糙度.

out vec3 DIFFUSE_LIGHT

漫射光效果.

out vec3 SPECULAR_LIGHT

镜面反射光效果。

out float ALPHA

Alpha(取值范围 [0.0, 1.0] )。如果在任何分支中对其进行了写入(赋值),该材质就会走透明渲染管线。

备注

因为写入 ALPHA 而经过透明管线的着色器可能受到透明排序问题的影响。更多信息及解决方法请阅读3D 渲染限制页面的透明排序章节

透明材质无法投射阴影,也不会出现在 hint_screen_texture (屏幕纹理提示)和 hint_depth_texture (深度纹理提示)这两种 uniform(统一变量)中。这进而导致透明材质无法出现在屏幕空间的反射或折射效果中。此外,透明材质上也看不到 SDFGI (有向距离场全局光照)产生的锐利反射(只能看到模糊/粗糙的反射效果)。