Substance Designer 中實現形態圖形處理演算法(I) --- 腐蝕與膨脹及其拓展


Erosion & Dilation!

腐蝕與膨脹是在圖形學中經常被使用到的操作, 意思很好理解, 腐蝕原有的圖像, 或者延擴原有的圖像. 據我所知, 最早在Substance Designer 中實現這兩個操作並分享出節點的人是suzukiMY.

效果圖

但是可能處於一些原因, 他並沒有將.sbs分享出來, 而只是封包的.sbsar. 我根據理論描述的演算法, 又重新實現了一次, 儘管實現之後的效果和他的效果一模一樣, 但是據我所知, 真正能放到SD上面的完全版腐蝕/膨脹演算法並不存在...

腐蝕演算法的原理:

嚴謹定義非常坑爹, 講多了也沒意思, 我在這裡只拿SD裡面實現的簡化版本 來做例子:

如圖, 腐蝕後中間像素取9宮格中所有像素的最暗值

上圖中3x3鄰域腐蝕操作的結果顯而易見, 圖像中明亮的脈絡會被逐漸周圍的黑色像素"侵蝕"掉, 這也是flood fill做裂縫是很常見的操作:

根據前面講到的演算法, 這裡是我自己寫的代碼截圖:

不懂編程的讀者可能不太懂, 我在這裡簡略解釋下這張圖的一些元素:

$pos, $size是SD自帶的系統常量, 分別表示像素位置和圖像長寬; min表示取得輸入值中的最小值; sample節點負責在指定的輸入圖(比如input0, 就是輸入的第一張圖)在輸入的位置(比如$pos)處提取顏色.

而dilation(膨脹)操作, 自然就是和腐蝕操作剛好相反啦, 代碼都只要把min(最小值)節點改成max(最大值)就好了.這兩個節點雖然挺好實現的, 但是非常有用, 很多大神在gumroad, artstation上面的作品都用到了這兩個節點.

基本知識就在這裡講完了, 接下來是更硬核一點的部分, 也是比較新穎的知識:


Open & Close...?

Open/Close(開/閉)操作分別定義為

Open = Erosion(腐蝕)-->Dilation(膨脹)

Close = Dilation --> Erosion

二者次序剛好相反, 為什麼叫開, 閉操作呢? 原因很簡單, 它們處理圖像的效果剛好就是打開洞/閉合(填補)洞, 例如, 閉操作:

如圖, 一開始圓中有一個小黑孔, 膨脹使之閉合, 再腐蝕讓圓縮回原來大小

在複雜的圖像中, 也能看出其上述特徵:

可以看到, 原來的小黑孔全部都被一堆亮度稍高些的方框"封"住了

開操作則與之相反, 如圖:

如圖, 一開始大圓中有一個小亮點, 腐蝕後被消除, 隨後膨脹, 恢復原來形狀

開操作可以移除掉兩個形狀間細小的連接部分:


圖形形態學其實還有許多其它的操作, 而腐蝕與膨脹也不一定就必須用3x3的鄰接域來做, 也可以用5x5, 7x7, ... 甚至任意你想要的形狀來做, 但是一次5x5, (2n + 1)x(2n + 1)腐蝕/膨脹其實可以分解為數次3x3操作, 這是在數學上被證明了的, 叫做structure element decomposing(在matlab等軟體中, 就有專門把你輸入的腐蝕/膨脹模板分解成簡單的3x3, 或者1xn, nx1模板的函數), 所以就沒有必要費勁在SD裡面實現了.

而實現1xn的GPU演算法的確存在, 但是我仔細研究過後, 認為在SD內實現的難度過高, 而且目前3x3的版本已經夠用了, 所以就偷偷懶吧...

這裡是我的sbs源文件, 獻醜了~歡迎大家使用, 順便給出一些改進的建議吧

https://pan.baidu.com/s/1s_sGz6_ckcBwAGh1cwFFRg?

pan.baidu.com


推薦閱讀:

細數那些美術表現拿到好成績的遊戲
[譯] 用3D掃描創造出《星球大戰:前線》的世界
評價UI設計作品好壞的八個標準

TAG:計算機圖形學 | 二維圖形學 | 遊戲美術設計 |