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.
Checking the stable version of the documentation...
2D 燈光和陰影
前言
預設情況下,Godot 中的 2D 場景採用無光照著色,看不到燈光和陰影。雖然算繪速度很快,但無陰影的場景看起來會很平淡。Godot 提供了可以使用即時 2D 照明和陰影的功能,可以大大增強專案的層次感。
無 2D 燈光或陰影,場景採用無光照著色
已啟用 2D 光源 (無陰影)
已啟用 2D 光源與陰影
節點
完整的二維照明設定涉及多個節點:
CanvasModulate 用於使場景變暗
PointLight2D (用於全向或點光源)
DirectionalLight2D (用於日光或月光)
其他會接收光照的 2D 節點,例如 Sprite2D 或 TileMapLayer。
CanvasModulate 用於指定一種顏色作為“環境”基色,從而使場景變暗。這是任何 2D 燈光都 無法 到達區域的最終照明顏色。如果沒有 CanvasModulate 節點,由於 2D 燈光只會照亮現有的無陰影外觀(看起來完全亮了),最終場景看起來會過於明亮。
Sprite2D 節點 用來顯示光斑、背景以及陰影投射器的貼圖。
PointLight2Ds 用來照亮場景。光通常的工作方式是透過在場景的其餘部分疊加選定的貼圖來模擬光照。
LightOccluder2D 節點 用來告訴著色器場景的哪些部分會投射陰影。這些遮蔽物可以放置為獨立節點,或可以成為一個 TileMapLayer 節點的一部分。
陰影只會出現在被 點光源 2D 覆蓋的區域,其方向基於 光源 的中心。
備註
背景色 不會 接收任何光照。如果要在背景上投射燈光,則需要為背景新增視覺化表示,例如 Sprite2D。
Sprite2D 的 Region 屬性有助於快速建立重複的背景紋理,但要記住在 Sprite2D 屬性中將 Texture > Repeat 設定為 Enabled 。
點光源
點光源(也稱位置光源)是 2D 照明中最常見的元素。點光源可用於表示火把、火、射彈等發出的光。
PointLight2D 提供了以下屬性,可在屬性檢視器中進行調整:
紋理: 用作光源的紋理。紋理的大小決定光源的大小。紋理可以有一個 alpha 通道,這在使用 Light2D 的 Mix 混合模式時非常有用,但在使用 Add (預設)或 Subtract 混合模式時則不需要。
偏移量: 燈光紋理的偏移量。與移動燈光節點不同,改變偏移量 不會 導致陰影移動。
紋理縮放: 燈光大小的乘法器。數值越大,燈光越亮。較大的燈光會影響螢幕上更多的像素,因此在增大燈光尺寸前要考慮到這一點。
高度: 燈光在法線貼圖中的虛擬高度。預設情況下,燈光與接收燈光的表面非常接近。如果使用法線貼圖,這將使燈光幾乎不可見,因此可以考慮增加此值。只有在使用法線貼圖的表面上,調整燈光的高度才會產生明顯的不同。
如果沒有預製紋理可用於燈光,可以使用這種 “中性 ”點光源紋理(按右鍵 > 圖像另存為... ):
中性點光源紋理
如果您需要不同的漸變,可以通過在燈光的**紋理**屬性上分配 新建 GradientTexture2D 來程式化地建立紋理。建立資源後,展開其 Fill 部分並將填充模式設定為 Radial 。然後,您需要調整漸變本身,使其從不透明的白色開始到透明的白色,並將其起始位置移動到中心。
平行光
Directional lighting is used to represent sunlight or moonlight. Light rays are casted parallel to each other, as if the sun or moon was infinitely far away from the surface that is receiving the light.
DirectionalLight2D 提供以下的屬性:
高度: 燈光在法線貼圖中的虛擬高度(
0.0= 平行於曲面,1.0= 垂直於曲面)。預設情況下,燈光與接收燈光的表面完全平行。如果使用法線貼圖,這將使燈光幾乎不可見,因此可以考慮增大此值。調整燈光的高度只會對使用法線貼圖的表面產生視覺差異。 高度 不會影響陰影的外觀。最大距離: 物體距離相機中心的最大距離(單位:像素)。減小該值可以防止對位於相機外的物體投射陰影(同時還能提高性能)。 最大距離 不考慮 Camera2D 的縮放,這意味著在較高的縮放值下,當縮放至給定點時,陰影會更快消失。
備註
無論 Height 屬性的值是多少,定向陰影看起來總是無限長。這是 Godot 中用於 2D 燈光的陰影算繪方法的限制。
不想獲得無限長的定向陰影,應禁用 DirectionalLight2D 中的陰影,並使用自訂著色器來讀取 2D 帶符號距離場。該距離場從場景中的 LightOccluder2D 節點自動生成。
常用光源屬性
PointLight2D 和 DirectionalLight2D 都提供共同的屬性,這些屬性是 Light2D 基底類別的一部分:
啟用: 允許切換燈光的可見性。與隱藏燈光節點不同,禁用此屬性不會隱藏燈光的子節點。
僅編輯器: 如果啟用,燈光僅在編輯器中可見。在運作的專案中將自動禁用。
顏色: 燈光的顏色。
能量: 燈光強度乘數。數值越大,光線越亮。
混合模式: 用於光線計算的混合公式。預設的 新增(Add) 適合大多數使用情況。 減(Subtract) 可用於負光,負光在物理上並不精確,但可用於特殊效果。 混合(Mix) 模式通過線性插值將燈光紋理對應的像素值與燈光下方的像素值混合。
範圍 > Z 下限: 受光線影響的最小 Z 值。
範圍 > Z 上限: 受光線影響的最大 Z 值。
範圍 > 層下限: 受光線影響的最小層數值。
範圍 > 層上限: 受光線影響的最大層數值。
範圍 > 對象遮罩: 根據其他節點的可視層選項**Occluder Light Mask**(遮擋掩膜),控制那些節點接收到來自這個節點的光線。通過這種方式可以讓某些物體不被光線照射。
設定陰影
啟用一個 PointLight2D 或者 DirectionalLight2D 節點的 Shadow > Enabled 屬性之後,你將看不到任何變化。這是因為在你的場景中還沒有任何節點擁有投射陰影需要使用的 遮擋器 。
要在場景中顯示陰影,必須在場景中新增 LightOccluder2D 節點。這些節點還必須具有與精靈輪廓相配對的遮光多邊形。
除了多邊形資源(必須設定多邊形資源才能產生視覺效果)之外,LightOccluder2D 節點還有兩個屬性:
SDF碰撞: 如果啟用,則遮擋器將成為可在自訂著色器中使用的即時生成的 簽章距離欄位 (signed distance field)的一部分。當不使用從此 SDF 中讀取的自訂著色器時,啟用這個功能不會帶來視覺上的差異,並且沒有性能成本,因此預設情況下為方便起見它是啟用的。
遮擋器光照遮罩: 這是與 PointLight2D 和 DirectionalLight2D 的 Shadow > Item Cull Mask 屬性一起使用的功能,以控制哪些物件為每個光照投射陰影。這可用於防止特定物件投射陰影。
有兩種建立光遮蔽物的方法:
自動產生光遮蔽器
遮擋器可以自動地 Sprite2D 節點上建立,需要選中節點,按一下2D編輯器頂部的 Sprite2D**功能表,然後選擇 **建立 LightOccluder2D 兄弟節點\\從而自動進行。
在出現的視窗中,一個外框將會包裹在你的精靈的邊緣。如果外框貼合在了你的精靈的邊緣上,你可以點擊**確定**。如果外框離你的精靈邊緣太遠(或者它穿過了你的精靈的邊緣),調整**擴充(像素)**和**收縮(像素)**,然後點擊**更新預覽**。重複這一個操作直到你對結果滿意為止。
手動繪製光遮蔽器
建立一個 LightOccluder2D 節點,然後選中節點,點擊 2D 編輯器頂部的 “+” 按鈕。在詢問是否要新增一個多邊形資源的時候選擇**建立**。然後你就可以通過點擊新增頂點的方式繪製遮光多邊形了。你可以通過右鍵已經建立的頂點來刪除它們,並且你可以點擊並拖動一個已經存在的線段上來新增新的頂點。
啟用陰影的 2D 燈光能夠調整以下屬性:
Color: 陰影區域的顏色。預設情況下,陰影區域是全黑的,但這可以出於藝術目的而改變。顏色的 alpha 通道控制的是陰影被指定顏色著色的程度。
Filter:**陰影所使用的篩選模式。預設值為 **None,算繪速度最快,並且非常適合像素藝術風格的遊戲(因為它具有“方塊”視覺效果)。如果你想要柔和的陰影,請使用 PCF5。PCF13 則更柔和,但算繪需求更高。由於算繪成本較高,PCF13 只應用於少量光源同時存在的情況下。
Filter Smooth:**篩選平滑。控制的是當 **Filter 為 PCF5 或* PCF13* 時,應用於陰影的柔化程度。較高的值會導致陰影更加柔和,但可能會出現帶狀偽影(特別是使用 PCF5 時)。
Item Cull Mask: 專案剔除遮罩。控制的是哪些 LightOccluder2D 節點能夠投射陰影,取決於對應的 Occluder Light Mask (遮擋器燈光遮罩)屬性。
備註
Lighting and shadow resolution in pixel-art games
The engine computes 2D lighting and shadows at the Viewport's pixel resolution, not at the source texture's texel resolution. The appearance of lights and shadows depends on your window or Viewport resolution, not on the resolution of individual sprite textures.
If you create a pixel-art game and want pixelated or blocky lighting and shadows that match your art style, Nearest texture filtering will not achieve this effect. Nearest filtering affects only how the engine samples textures — it does not change how the engine renders lighting and shadows.
To achieve pixelated lighting and shadows, use a custom shader to modify
LIGHT_VERTEX and SHADOW_VERTEX to snap light sampling to a pixel grid.
The following shader snaps lighting to a grid using the floor() function:
shader_type canvas_item;
uniform float pixel_size = 4.0;
void fragment() {
// Snap lighting and shadows to pixel grid.
LIGHT_VERTEX.xy = floor(LIGHT_VERTEX.xy / pixel_size) * pixel_size;
SHADOW_VERTEX = floor(SHADOW_VERTEX / pixel_size) * pixel_size;
// Normal rendering.
COLOR = texture(TEXTURE, UV);
}
This works by dividing the position by pixel_size to convert to grid space,
using floor() to round down to the nearest grid point, then multiplying back
to convert to screen space. The result forces the engine to sample lighting from
discrete grid positions, which creates the pixelated effect.
For more information on canvas item shaders, see CanvasItem shaders.
硬陰影
柔和陰影(PCF13,Filter Smooth 1.5)
因 Filter Smooth 值太高而產生條紋偽影的柔和陰影(PCF5,Filter Smooth 4)
法線貼圖與鏡面貼圖
法線貼圖和鏡面貼圖可以大大提升你的2D光照的立體感。與3D算繪類似,法線貼圖可以根據接收光線的表面方向來改變光線的強度,從而使照明效果不再平面化(按像素進行調整)。鏡面貼圖通過讓一部分光線反射回觀察者來進一步改善視覺效果。
Both PointLight2D and DirectionalLight2D support normal mapping and specular mapping. Normal and specular maps can be assigned to any 2D element, including nodes that inherit from Node2D or Control.
法線貼圖表示每個像素 “指向” 的方向。引擎會利用這些資訊,以物理上合理的方式將光照正確應用到 2D 表面。法線貼圖通常由手繪的高度貼圖建立,但也可以由其他紋理自動生成。
鏡面貼圖定義了每個像素對光線的反射程度(如果鏡面貼圖包含顏色,則定義反射的顏色)。亮度值越高,紋理上指定位置的反射就越亮。鏡面貼圖通常以漫反射紋理為基礎,通過手動編輯建立。
小訣竅
如果在你的精靈中沒有使用法線貼圖或者鏡面貼圖,可以使用免費的開源工具`Laigter <https://azagaya.itch.io/laigter>`來生成。
要在 2D 節點上設定法線貼圖和/或鏡面貼圖,請為繪製節點紋理的屬性建立一個新的 CanvasTexture 資源。例如,在一個 Sprite2D 節點上建立一個新的 CanvasTexture 資源:
為 Sprite2D 節點建立 CanvasTexture 資源
展開新建立的資源。您可以找到需要調整的幾個屬性:
Diffuse > Texture(漫反射 > 紋理): 基礎的顏色貼圖。在這個屬性中,載入你將使用在精靈本身的紋理。
Normal Map > Texture: 法線貼圖。在此屬性中載入你從高度圖產生的法線貼圖(見上方提示)。
Specular > Texture: 鏡面貼圖紋理,用於控制漫反射紋理上每個像素的鏡面反射強度。鏡面貼圖通常為灰階,但也可包含顏色來調整反射色彩。在此屬性中載入你建立的鏡面貼圖(見上方提示)。
Specular > Color: 鏡面反射的顏色乘數。
Specular > Shininess: 鏡面反射高光指數。值低時反射會較亮且擴散,值高時反射會更集中。較高的值適用於濕潤表面。
Texture > Filter:**可覆蓋紋理的篩選模式,無論節點屬性或專案設定(**算繪 > 紋理 > 畫布紋理 > 預設紋理篩選)如何。
Texture > Repeat:**可覆蓋紋理的重複模式,無論節點屬性或專案設定(**算繪 > 紋理 > 畫布紋理 > 預設紋理重複)如何。
啟用法線貼圖後,你可能會注意到燈光會顯得較弱。為了解決這個問題,可以增加 PointLight2D 和 DirectionalLight2D 節點上的 Height 屬性。也可以略微增加燈光的 Energy 屬性,以接近啟用法線貼圖之前的照明強度。
用加法混合精靈作為 2D 光源的快速替代方案
如果在使用 2D 燈光時遇到性能問題,不妨將其中一些節點替換為使用疊加混合的 Sprite2D 節點。這尤其適用於短暫的動態效果,如子彈或爆炸。
新增式精靈的算繪速度要快得多,因為它們不需要通過單獨的算繪管道。此外,這種方法還可以與 AnimatedSprite2D(或 Sprite2D + AnimationPlayer)一起使用,這樣就可以建立動畫二維 “燈光”。
不過,與 2D 燈光相比,新增式精靈有一些缺點:
與 “實際 ”二維光照相比,混合公式並不準確。這在光線充足的區域通常不是問題,但這會妨礙新增精靈去正確照亮那些完全黑暗的區域。
新增式精靈不能投射陰影,因為它們不是燈光。
新增式精靈會忽略其他精靈上使用的法線貼圖和鏡面貼圖。
要顯示一個混合疊加效果的精靈,需要建立一個 Sprite2D 節點並分配一個紋理給它。在檢視視窗中,往下滾動到 CanvasItem > Material 部分,展開它並點擊 Material 屬性旁邊的下拉式功能表。選擇 New CanvasItemMaterial,點擊新建的材質來編輯它,然後將 Blend Mode 設定為 Add。