天天看點

《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果

本節書摘來自華章出版社《unity着色器和螢幕特效開發秘笈》一 書中的第2章,第2.7節,作者:(美)kenny lammers,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

如果你曾經做過任何圖像編輯的工作,如潤色一張家庭照片,制作遊戲的紋理,或者數字繪畫等,我們相信你應該會明白色階的調整對畫面所産生的影響。是以,photoshop使用時的偏好完全有可能影響着色器的效果。

我們發現photoshop中的所有不同的圖像編輯工具和混合模式都可以描述成一組數學運算。最後,我們通過乘法、加法、減法,或者将像素值與其他一些值進行比較,最後得到一個傳回值。這個傳回值就成為你目前編輯圖像的新的像素顔色。

photoshop效果涉及的不同數學算法可以寫成一本書,但在這裡我們的重點是色階(level)。我們将在第10章讨論更加進階的混合模式。

為了完成本節,你需要建立一個新的着色器和材質,并在建立的unity場景中将它附加在某個物體上。你還需要一個源紋理用來測試我們使用色階的代碼。當然,你也可以使用本書附随的一些材質檔案。

1.将如下代碼所示的屬性添加至建立的着色器:

《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果
《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果

2.確定你在cgprogram語句中也将下面這些屬性聲明為變量:

《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果

3.建立一個變量用于存儲_maintex紋理的紅色通道:

《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果

4.因為tex2d()函數所提供的顔色值範圍是從0到1,是以我們需要将其重新映射至0.0到255.0的範圍内。

《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果

5.然後減去我們的輸入值_inblack,這樣當我們将輸入色階的黑色滑塊朝着255.0滑動時可以使所有像素變得更暗。

《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果

6.然後,當我們将輸入色階的白色滑塊朝着0.0滑動時,可以将所有像素變得更亮,并對得到的結果求_ingamma次方:

《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果

7.最後,我們将新的像素值與_outwhite減去_outblack的差相乘,然後将新的像素值重新映射到0.0~1.0的範圍内:

《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果

下圖展示的是我們通過着色器将制作的色階程式應用到紋理中的最終效果:

《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果

在着色器的surf函數中我們首先使用tex2d()函數對一個顔色紋理進行取樣,并使用變量c存儲取樣後的值。這時,我們就要開始對特定的某個通道進行工作并修改每個通道的像素值。為了做到這一點,我們建立了一個名為outrpixel的新變量,并為它賦了一個大小為c.r * 255.0的值。做完這一步值的範圍将從0.0~1.0擴大至0.0~255.0。

接下來,程式把目前像素值減去_inblack屬性值,使像素值變得更暗。我們還要確定該值在進行相減之後不得低于0.0,通過使用max()函數我們可以得到兩個參數中的最大值。

現在我們想将修改的像素值除以新的白點值。可以用_inwhite值減去_inblack值得到新的白點值。這樣可以簡單地提高像素值,或者使它更亮。然後我們再對該值求_ingamma次方也可以提高像素值,這樣基本上做到了可以讓你移動目前像素的中間值。

最後,我們使用_outwhite和_outblack再次修改像素值,這樣你就可以對最小像素值以及最大像素值有一個最終的全局控制了。然後再将這一結果除以255.0,使其重新恢複到0.0~1.0的範圍内。

我們将最後的結果傳給o.albedo作為我們最終的漫反射顔色。當你在材質inspector面闆中滑動滑塊時,就會發現你可以對紋理的對比度和亮度進行控制了。

我們相信你已經注意到了,在我們的着色器代碼中有很多重複的代碼。我們可以在着色器中建立一個自定義的函數來使我們的着色器變得更加簡潔。從開發的角度講這對我們保持代碼的清晰和着色器的高效更有幫助。自定義函數如下代碼所示:

《Unity着色器和螢幕特效開發秘笈》—— 2.7 Photoshop色階效果

通過在我們的着色器中使用這個新函數來處理最後的像素色階,我們将surf()函數中處理所有通道像素的代碼從15行降到了3行。這極大地簡化了我們的代碼,現在隻需要修改一處代碼,而不是三處。