告別直角鋸齒:直角網格的審美疲勞
自 20 世紀 70 年代點陣螢幕誕生以來,像素化(Pixelation)一直是數位藝術最核心的視覺圖騰。然而在現代高解析度顯示器上,單純將照片降採樣成低解析度色塊的「樸素馬賽克」正面臨嚴峻的審美侷限:
- 生硬的 90° 直角階梯折線:無論是人像臉部邊緣還是自然風景的起伏地平線,斜向輪廓都會被強行鋸齒化,破壞主體的有機流動感;
- 平坦天空的割裂感:在平滑漸層的天空或霧氣區域,相近顏色的方形格子互相堆疊,既缺乏宏觀秩序,又顯得廉價凌亂;
- 死板的黑色網格線:為了突顯像素感,許多傳統濾鏡會機械地在每個方格邊緣畫一條黑線,導致整個畫面被切碎成死氣沉沉的方塊矩陣。
在設計藝術探索中,台灣生成藝術創作者 William Liang(@william77.fun)提出過一種極具啟發性的視覺語言:用程式將攝影作品轉譯為正交圓角世界——平坦的天空如同層層退暈的梯田等高線,邊緣的轉折全部帶有溫潤的圓弧導角,細密的水面波光則如同密佈微型焊盤與走線的矽基晶片。
為了在 質感工坊 (Texture Studio) 中忠實復刻這一極具先鋒感的生成藝術質感,我們構建了 Capsule Pixel(膠囊像素) 引擎。該引擎完全由純 Canvas 2D 驅動,無需外部依賴或複雜的向量幾何庫,實現了 100% 確定性的像素級生成效果。
圖 1: Yan 膠囊像素引擎的四階架構流程 — 從亮度色階合併到網格 SDF 雙向圓角倒角、雙重波形浮雕反差描邊與晶片同心微核生成。
視覺對照:樸素馬賽克 vs 膠囊像素引擎
在深入公式細節之前,我們先在包含大片綠色草坡與戴斗笠旅人的高反差測試圖上對比兩種處理方式:
![]()
圖 2: 高反差草坡人像裁切對比 — (01) 原始照片;(02) 傳統直角馬賽克,斗笠與草坡輪廓被生硬鋸齒粉碎,天空被切碎成死板格子;(03) Yan 膠囊像素引擎,大平坦區融合成平滑導弧的多邊形,人物剪影清晰銳利,細節呈現晶片走線般的機械美感。
仔細觀察上圖中間的 // 02: 樸素馬賽克:
- 旅人的斗笠與人像剪影完全被鋸齒淹沒:生硬的直角階梯割裂了人物輪廓,觀者很難在第一時間辨別斗笠邊緣的圓潤曲線;
- 草地與天空充斥著無意義的高頻方塊接縫:原本和諧連貫的背景被分割成數百個刺眼的微小色塊。
而在右側的 // 03: 膠囊像素 中:
- 天空平緩的受光面自動消融了內部接縫,聚合為宏大的等高線階梯;
- 每一個直角拐角無論是凸起還是凹陷,全部擁有精確的圓弧導角(
R ≈ 0.28 · cellSize); - 緊貼外層暗縫的內嵌亮白高光線,賦予全圖一種彷彿在壓克力板上雕刻電路板的立體浮雕質感。
階段 1:自適應色階聚合與正交連通域合併
膠囊像素的第一步,是消除平坦區域裡多餘的格子邊界。
我們將畫面劃分為邊長為 cellSize(預設 14px,根據影像尺度透過 scaleFor 動態縮放)的正交網格陣列。在每個單元格內,計算平均 RGB 與感知明度:
L = 0.299R + 0.587G + 0.114B
接著,根據對比度參數將明度量化為離散的等高色階 Q(通常劃分為 8 到 16 檔):
Q = round((L / 255) × Levels)
當相鄰網格單元的量化色階 Q 相等時,它們在拓撲上被視為屬於同一個連通多邊形(Polyomino)。這意味著:它們之間的交界線將被徹底抹除。
// 1. 網格單元顏色均值與色階量化
const gridR = new Float32Array(gw * gh)
const gridG = new Float32Array(gw * gh)
const gridB = new Float32Array(gw * gh)
const gridQ = new Int32Array(gw * gh)
for (let gy = 0; gy < gh; gy++) {
const y0 = gy * cellSize, y1 = Math.min(h, y0 + cellSize)
for (let gx = 0; gx < gw; gx++) {
const x0 = gx * cellSize, x1 = Math.min(w, x0 + cellSize)
let rSum = 0, gSum = 0, bSum = 0, count = 0
for (let y = y0; y < y1; y++) {
const row = y * w * 4
for (let x = x0; x < x1; x++) {
const idx = row + x * 4
rSum += data[idx] ?? 0
gSum += data[idx + 1] ?? 0
bSum += data[idx + 2] ?? 0
count++
}
}
const gIdx = gy * gw + gx
const r = rSum / count, g = gSum / count, b = bSum / count
gridR[gIdx] = r; gridG[gIdx] = g; gridB[gIdx] = b
const lum = 0.299 * r + 0.587 * g + 0.114 * b
gridQ[gIdx] = Math.round((lum / 255) * levels)
}
}
階段 2:網格有向距離場(Grid SDF)與雙向圓角倒角
如果僅僅合併單元格,得到的依然是一堆邊緣帶有硬折角的多邊形。膠囊像素的靈魂在於對每一個直角進行精密的圓角導弧(Filleting)。
膠囊像素透過網格拓撲有向距離場(Grid SDF)在單像素掃描中以 O(1) 常數時間完成倒角計算:
設當前像素所在單元格為 (g_x, g_y),格內局部相對座標為 (u, v) ∈ [0, cellSize-1]^2。我們檢查其 8 個正交與對角鄰居的色階是否與當前格不同:diffT, diffB, diffL, diffR, 以及 diffTL, diffTR, diffBL, diffBR。
1. 外凸角圓角(Convex Fillet)
當兩個正交相鄰邊均為邊界(例如上方與左側均不同 diffT && diffL),在左上角區域(u < R 且 v < R),直角需要被外凸圓弧切去:
d = R - sqrt((R - u)^2 + (R - v)^2)
2. 內凹角圓角(Concave Fillet)
當上方和左側與當前格相同(!diffT && !diffL),但對角線左上方不同(diffTL == true)時,這裡形成了一個內凹拐彎角!內凹圓角的圓心恰好在拐角頂點 (0, 0),距離為:
d = min(d, sqrt(u^2 + v^2))
const R = cellSize * 0.28
let d = cellSize * 2
// 直邊距離
if (diffT && u < d) d = u
if (diffB && (cellSize - 1 - u) < d) d = cellSize - 1 - u
if (diffL && v < d) d = v
if (diffR && (cellSize - 1 - v) < d) d = cellSize - 1 - v
// 外凸角倒角
if (diffT && diffL && u < R && v < R) d = R - Math.hypot(R - u, R - v)
if (diffT && diffR && u < R && (cellSize - 1 - v) < R) d = R - Math.hypot(R - u, R - (cellSize - 1 - v))
if (diffB && diffL && (cellSize - 1 - u) < R && v < R) d = R - Math.hypot(R - (cellSize - 1 - u), R - v)
if (diffB && diffR && (cellSize - 1 - u) < R && (cellSize - 1 - v) < R) d = R - Math.hypot(R - (cellSize - 1 - u), R - (cellSize - 1 - v))
// 內凹角倒角
if (!diffT && !diffL && diffTL) d = Math.min(d, Math.hypot(u, v))
if (!diffT && !diffR && diffTR) d = Math.min(d, Math.hypot(u, cellSize - 1 - v))
if (!diffB && !diffL && diffBL) d = Math.min(d, Math.hypot(cellSize - 1 - u, v))
if (!diffB && !diffR && diffBR) d = Math.min(d, Math.hypot(cellSize - 1 - u, cellSize - 1 - v))
階段 3:雙重反差波形浮雕描邊(Dual-Stroke Relief)
膠囊像素借鑑了 拉普拉斯高斯算子(LoG) 的墨西哥帽波形分佈,在距離邊界不同 d 處疊加兩重反差描邊:
- 外側暗色縫隙(Dark Seam):在緊貼邊界的微小帶狀區域(
d < 1.15 · kSize),將原本顏色壓暗 80% 以上; - 緊貼內側的高光白線(White Highlight Stroke):在距離邊緣約
1.3 \sim 1.8像素的位置,以高斯鈴形曲線注入一根高亮純白線條; - 對比度自適應衰減:描邊強度與交界兩側相鄰格子的實際色彩歐氏距離
\ΔC成正比。
階段 4:同心內嵌環與晶片微核點陣(Micro Core Nuclei)
在水面反光、樹林倒影等高頻碎紋區域,網格單元無法與鄰居合併,退化為單個獨立的 1× 1 方塊。我們為它們賦予了類似晶片焊盤與同心回紋的二級結構:
- 二級同心內環(Secondary Inset Ring):在
d ≈ 0.28 · cellSize處施加第二道柔和暗環; - 中心微核點陣(Micro Core Nucleus):在每個單元格的幾何中心點植入一顆高斯核點,孤立單元格呈現高亮的白色晶片核,而已合併的大塊區域內部則保留暗色微核。
橫向對比:四種離散柵格幾何渲染對比
| 維度 | 傳統像素畫 (Pixel Art) | 沃羅諾伊馬賽克 (Voronoi) | 半調網點 (Halftone) | 膠囊像素 (Capsule Pixel) |
|---|---|---|---|---|
| 空間拓撲 | 剛性笛卡兒矩形方陣 | 不規則泰森多邊形凸網格 | 旋轉角度 CMYK 點陣 | 自適應正交連通多邊形 (Polyomino) |
| 拐角幾何 | 銳利 90° 直角鋸齒 | 任意鈍角 / 銳角多邊形折線 | 連續圓形 / 橢圓點陣 | 內外雙向 SDF 平滑圓弧導角 (R=0.28s) |
| 色階處理 | 簡單均值或調色盤對齊 | 單胞內單色平塗 | 網點面積調製灰階 | 自適應色階聚合,平坦區消融接縫 |
| 輪廓浮雕 | 無,或單像素黑描邊 | 幾何單元交界單色縫隙 | 無輪廓(由網點密度感知) | 墨西哥帽式雙重反差浮雕(暗縫+高光) |
| 微觀層級 | 扁平實心填充 | 單胞純色 | 實心墨滴 | 二級同心內環 + 晶片焊盤微核 |
線上體驗與應用場景
膠囊像素現已作為第 31 款獨立濾鏡入駐 質感工坊 (Texture Studio)。無論是在電腦瀏覽器中免註冊直接匯出高解析度 PNG,還是在 Yan 手機端 App 中開啟 60fps 即時相機取景,都能即刻體驗這場流體正交晶格的視覺革命。