幻影坦克架構指南(二)
看這篇文章之前,必須繼續強調,我是搞學術的,不是在教人發車的。
上篇文章評論中,有人問到能不能發彩色底圖。這個其實有點難度,但是又感覺不是實現不了,比如說我可以對白底圖的需求放寬,對黑底圖要求彩色。那麼好的,我就開始了一番數學推導:
回放下我們的需求:
已知白底的圖1顏色 ,以及黑底的圖2顏色 ,求帶alpha通道的顏色 。並且我們最終得到的解如下:
這裡最蛋疼的就是三個alpha的表達式,如果圖片允許我們帶3個alpha,那麼問題簡直迎刃而解,不過現實很殘酷。於是我想到,如果不關心白底的圖片顯示,只要看不出黑底長啥樣就行,於是只要把 的rgb當成未知數, 當成已知數,求解3元一次方程組即可。對方程組進行 矩陣形式的變形如下
化成矩陣形式如下
然後求解行列式
行列式為0代表,這個三元一次方程組秩數不夠,易得,這個矩陣的秩數為2(前兩行直接加到第三行),所以結果被 與 兩個方程確定。
不過為了簡化理解,讀者只要知道 目前可以在 這個值域中取任意值。
好的繼續研究下,(1)的下半部
這裡還是強調下顏色的值域是 ,所以為了顏色不越界, 的值域為 ,彩色圖片一般來說rgb的最大值很容易接近1,所以可以把黑底圖的顏色變暗,擴大值域範圍來增加白底圖與黑底圖的無關性,因為我們的目的就是讓白底圖看不見黑底圖,如果兩張圖片相關性太強就遠離了我們的初衷。並且當我們把黑底圖變的很暗的同時我發現一個很有趣的現象。
好的,(2)又變成了這樣
很容易得到通解 。灰度圖!!
很好,我現在歸納下兩個條件,只要白底圖是個灰度圖的前提下,把黑底圖的亮度調的足夠低。那麼我們就很容易把這兩張不帶alpha通道的圖片合成一張帶alpha通道的顏色
繼續我們上一課崩壞3的例子,這回我們要顯示彩色的黑底圖
關鍵的shader代碼
fixed4 frag (v2f IN) : COLOR { fixed4 color1 = tex2D(_MainTex, IN.uv); // 轉灰度圖 color1.rgb = dot(color1.rgb, fixed3(.222, .707, .071)); fixed4 color2 = tex2D(_BackTex, IN.uv); fixed scale = 0.2; // 為了減小alpha計算3個值差異太大,使用變暗灰度圖的值來計算alpha fixed a = dot(color2.rgb, fixed3(.222, .707, .071)) * scale; color2 = color2 * scale; // 計算黑底圖 rgb的最大值 fixed maxc = max(max(color2.r, color2.g), color2.b); a = max(1 - color1.r + a, maxc); fixed r = color2.r / a; fixed g = color2.g / a; fixed b = color2.b / a; fixed4 color = fixed4(r, g, b, a); return color;}
最後貼上效果
白底圖:
黑底圖
這裡要強調的是,彩色圖的顏色信息並沒有喪失。我們可以將於黑色疊加的rgb算好,乘回去即可還原。
好的,現在流行的手機貼圖中,有一種alpha分離技術。將原圖的alpha導出一種灰度圖,這樣就是一張彩色圖與一張灰度圖!很滿足我們這個 幻影坦克技術的需求啊,莫非etc2的技術與我的推論有不謀而合之處?
還原彩色圖的關鍵代碼如下
//5是因為縮小到0.2, 乘以a是因為黑色背景的疊加公式fixed4 color = fixed4(r*a*5, g*a*5, b*a*5, 1);
上還原之後的黑底彩色圖
推薦閱讀:
※GPU Gems 基於物理模型的水面模擬 學習筆記 (一)
※Unity特效(1) 夢幻旋屏
※手游逆向分析<二>: Unity內還原《鎮魔曲》角色渲染效果
※Unity命令行模式,也能「日誌實時輸出」
※利用GPU實現無盡草地的實時渲染