[StrangeLoop 2017] How to Hack a Painting

前一段關注的一個博主,寫的畫都挺漂亮,演講風格也蠻有趣的。

博客:tylerlhobbs.com/writing

,如何靠程序生成水彩效果的畫。

#目標

可以觀察真實的水彩效果,主要有三個特徵:一是有類似分形一樣的邊緣效果,一是有變形,儘管畫的是一個圓○,但顏料在紙上流動後就會得到一個非正圓,最後是有軟邊緣柔化效果。

# 方法

## 形變

變形和分形效果是靠從多邊形不斷變形得到的,如下可以從左一變為右一的效果。基本方法很簡單,遍歷每一條邊,靠三個參數決定向外如何凸起,三個參數分別是在邊上的位置、突出距離和突出角度。

當然,每個參數會在各自區間內選取隨機值,這些值對效果有很重要的影響。為了有更好的效果,並不會使用白雜訊,而是使用高斯雜訊,這樣可以儘可能得讓各個參數在各自最優值周圍(邊上位置參數會在中點附近抖動,突出角度會在90°附近抖動)進行抖動。這樣遍歷一圈之後就可以得到右一的結果。

在取突出長度參數的時候考慮到該邊的長度,從而使得越短的邊突出長度也越短。這樣迭代6次演算法後就可以得到下面的效果,可以看出已經有分形和扭曲變形的效果了:

## 邊緣柔化

上面通過迭代6次得到的結果已經有非常多細節了,但缺少柔和的邊界。作者想到的辦法是,首先僅迭代3次來得到一個base polygon,然後不斷進行後3次迭代來產生不同的層,這樣每一層都有一些不同但又保有相同的核心形狀,然後按很低的透明度把所有層疊加起來即可。下面是靠這種方法疊加50層後的效果:

## 增加隨機

上面的效果已經比較接近水彩效果了,但其中一個問題是邊緣柔化比較平均,如果你觀察一開始真實的水彩效果的話會發現其實是有的地方柔和得很厲害,有些地方卻很銳利,這主要是因為不同濕度的紙對顏料的擴散有不同程度的影響。為了模擬這個效果,作者想到的方法是在初始化的時候給多邊形的每條邊指定不同的variance,這些variance會影響演算法里突出距離這個參數,如此一來variance大的邊會有很多的變化程度,得到的邊緣就越柔和,反之則會得到越隨機整齊的邊緣:

在迭代演算法的時候,由父邊分割得到的兩條子邊也會繼承這個variance值,同時在繼承時也會使用雜訊來略微抖動增加隨機性。使用這種方法後就可以得到下面更加自然的效果:

## 中濃外淡

作者另一個想要模擬的效果是顏色上的擴散效果,也就是中間顏色更濃越向外顏色越淡的效果。方法是對之前生成layers的過程進行改進。之前所有的layers都使用了同一個base polygon(通常是對初始多邊形進行3次演算法迭代後的結果),現在嘗試使用3層不同形變程度的base polygon,也就是說,對於前三分之一的layers,它們使用的base polygon是一次演算法迭代後的結果,對於中間三分之一的layers它們使用的也是兩次演算法迭代後的結果,最後三分之一是三次迭代後的結果。這樣,可以就保證中間的部分顏色更濃:

## 顏色混合

靠上面的方法生成的一個例子如下:

這個例子里還使用了兩個改進點:

一是在使用低透明度混合所有layers的時候,每一層使用了一張不同紋理遮罩(texture mask)來給透明度增加更多變化,上面的例子使用了一張類似紙張紋理的遮罩,使得混合效果更自然有趣。

二是在混合不同顏色的時候,是按照「你一層我一層」的順序計算的,即是按照逐層計算逐層混合來做的,而不是說先完全算完粉色、再算紫色、最後混合這樣的。這樣可以得到更加自然的混合效果。

# Q&A

問答環節也挺歡樂的,博主每賣一副畫會附上生成這幅畫的代碼,每幅畫的保存是需要保存源代碼以及使用的所有隨機數種子。有觀眾問何時這些畫可以通過圖靈測試,作者的回答太機智2333

對了,作者是資料庫程序員出身,表示用代碼畫畫可比寫資料庫有趣多了(? ̄??? ̄??)沒有code review,沒有bug tracker,沒有test case,沒有document,聽起來的確非常誘人啊
推薦閱讀:

走樣與反走樣(Aliasing/Anti-Aliasing):Graphics Cases
GAN在2017年實現四大突破,未來可能對計算機圖形學產生衝擊
Procedure Cloud
讓角色半透明:後期模糊(二)
為什麼需要模擬HDR

TAG:計算機圖形學 |