Skip to content

Skija 中的陰影

Skija 提供兩種不同的繪製陰影方式:2D 投影陰影(透過 ImageFilters)和 3D 高程陰影(透過 ShadowUtils)。

1. 2D 投影陰影 (ImageFilter)

這是為特定繪製操作添加陰影的標準方式。陰影會跟隨所繪製的幾何形狀或圖像的形狀。

java
ImageFilter shadow = ImageFilter.makeDropShadow(
    2.0f, 2.0f,   // 偏移量 (dx, dy)
    3.0f, 3.0f,   // 模糊量 (sigmaX, sigmaY)
    0x80000000    // 陰影顏色 (50% 透明黑色)
);

Paint paint = new Paint().setImageFilter(shadow);
canvas.drawRect(Rect.makeXYWH(50, 50, 100, 100), paint);

僅繪製陰影

如果只想繪製陰影而不繪製原始物件(例如,用於複雜的分層),請使用 makeDropShadowOnly


2. 3D 高程陰影 (ShadowUtils)

ShadowUtils 提供了一個更基於物理的陰影模型,類似於 Material Design 的高程概念。它計算特定 3D 位置的光源如何將「遮擋物」(一個 Path)的陰影投射到畫布平面上。

基本用法

java
Path path = new Path().addRect(Rect.makeXYWH(50, 50, 100, 100));

// Z 平面:物體的高程。
// 對於平坦的 UI 元素通常是常數:(0, 0, elevation)
Point3 elevation = new Point3(0, 0, 10.0f); 

// 光源位置:相對於畫布的 3D 座標
Point3 lightPos = new Point3(250, 0, 600); 

float lightRadius = 800.0f;
int ambientColor = 0x10000000;
int spotColor = 0x30000000;

ShadowUtils.drawShadow(
    canvas, 
    path, 
    elevation, 
    lightPos, 
    lightRadius, 
    ambientColor, 
    spotColor, 
    ShadowUtilsFlag.TRANSPARENT_OCCLUDER
);

// 注意:drawShadow 僅繪製陰影。
// 您仍然需要繪製物件本身:
canvas.drawPath(path, new Paint().setColor(0xFFFFFFFF));

環境陰影 vs. 聚光陰影

  • 環境陰影:由間接光線引起的柔和、非定向陰影。
  • 聚光陰影:由特定光源位置引起的定向陰影。 結合兩者可以創造出逼真的深度效果。

陰影標誌

  • TRANSPARENT_OCCLUDER:如果您的物件是半透明的,請使用此標誌,這樣陰影就不會被裁剪在物件下方。
  • GEOMETRIC_ONLY:如果您不需要高品質的模糊效果,可以使用此優化標誌。
  • DIRECTIONAL_LIGHT:將光源視為無限遠(如陽光)。

比較

特性投影陰影 (ImageFilter)高程陰影 (ShadowUtils)
模型2D 高斯模糊3D 透視投影
效能快速(由 Skia 快取)更複雜,但高度優化
用法Paint 上設定直接呼叫 ShadowUtils
最適合文字、簡單的 UI 光暈、圖示Material Design 按鈕、卡片、深度效果

視覺範例

要查看這些陰影的實際效果,請執行 Scenes 範例應用程式並選擇 ShadowUtils 場景。

原始碼: examples/scenes/src/ShadowUtilsScene.java

圖:各種 ShadowUtils 標誌和光源位置的比較。