Cocos Creator Shader Effect 系列 - 4 - 老照片特效

在閱讀過前面的基礎章節,相信現在的你已經迫不及待想實現點特效。

那么我們先來點簡單的,比如:老化特效(完整代碼在我的 Github 倉庫Gitee 倉庫 中可以找到)。

2d-sprite-old-photo.gif

老化特效在游戲中有很多使用場合。比如:

  • 將照片老化
  • 在玩家游戲通關過程中,如果玩家通關失敗,給游戲界面進行老化
  • ...

使用恰當會給游戲帶來更好的體驗,現在我們看看怎么實現吧。

一、創建新材質

如果你很清楚怎么創建材質,那么可以跳到下個章節。

既然我們要寫自己的特效,那么這次,先來個基礎的創建教程:

  1. 我們先創建一個材質和一個Effect文件
  2. 打開材質的屬性編輯器,指定 Effect 為我們剛剛創建的 Effect
  3. 將我們材質綁定到一個場景中的紋理上,方便預覽調試
New Effect

Ok. Let's go!

一、老化原理

其實,老化的原理很簡單,針對紋理的每個uv顏色,執行下面的公式就可以了

r = 0.393 * r + 0.769 * g + 0.189 * b; 
g = 0.349 * r + 0.686 * g + 0.168 * b; 
b = 0.272 * r + 0.534 * g + 0.131 * b;

現在,打開我們的特效 Effect 文件,找到 片段著色器 代碼部分,加入如下函數即可:

add Code

ps: 可能你會注意,框框部分,我加了一個宏 USE_OLD_PHOTO ,這是我自己為了調試方便而加入的宏,在 Cocos Creator Shader Effect 系列 - 3 - Effect 文件調試 文章中,我有說到宏調試的方案,這里是一個應用例子。

二、線性老化

通過上面的公式,我們得到的是一個直接老化后的效果。

而在實際使用的時候,我們有可能需要一個漸變過程,從不老化漸變為老化效果, 。

那么,我們試著來做一個 線性漸變的老化效果。

線性漸變,其實也是很好理解一個公式:

finalColor = srcColor + (oldColor - srcColor) * oldLevel;
  • srcColor:原始顏色
  • oldColor:最終老化后的顏色
  • oldLevel:老化程度,值在區間 [0.0, 1.0]

依舊還是在 片段著色器 中加入這部分代碼即可:

image.png

這里有些注意事項要說一下:

  1. 著色程序執行時是從上往下執行,因此,如果我們要在 main() 函數中調用 getOldPhotoColor() 函數,那么 getOldPhotoColor() 函數要在 main() 函數之前定義
  2. getOldPhotoColor() 函數在 main() 函數使用時,要注意包裹在 USE_OLD_PHOTO 宏中使用,因為這個函數是定義在該宏中。
  3. Cocos Creator 在 關于 UBO 內存布局 中有如下規定:

首先結論是,我們規定在 shader 中所有非 sampler 的 uniform 都應以 block 形式聲明

  • 因此,按照這個規定,我們將 oldLevel 屬性放在了 UBO 結構對象中
  1. 我們定義了的 oldLevel uniform 屬性,還應該在 CCEffect 結構中聲明,這樣子我們可以在編輯器中進行變量修改調試
    Inspector

    ps: 注意,編輯器屬性的key是 inspector 名稱,而官方文檔截圖中的 editor ,小問題,提醒一下。
    image.png

來自評論2樓的提醒
Creator 3D 中,這里的確為 editor ,Cocos Creator 從 2.3 開始同步了這個修改,2.3 之前還是 inspector

OK,現在我們就可以打開我們的編輯器,在 Inspector 中修改 oldLevel 去查看不同老化程度的效果。

1.gif

三、修改材質 uniform 屬性

當然我們也可以做個測試場景去實時看這個漸變效果。代碼中更新材質的 uniform 屬性,在 Cocos Creator 上需要3步:

// 獲取渲染組件的材質
let material: cc.Material = sprite.getMaterial(0);

// 給材質的 uniform 變量跟新值
// let oldLevel: number = 1.0;  // [0.0, 1.0]
material.setProperty("oldLevel", oldLevel);

// 重新將材質設置回去
sprite.setMaterial(0, material);

配合一些其他組件,比如:cc.Slider 等,我們就可以做出這種測試效果了。

2d-sprite-old-photo.gif

四、總結

寫完下來,是不是感覺我很啰嗦,因為是這個系列的第一個的特效,所以難免寫了很多基礎的內容,后續的特效可能不會那么啰嗦了。

Ok,回歸主題。

其實,除了 老化原理的那條公式 之外,其他都是屬于很基礎,很通用的東西,后續都可以用上。

而類似的,單單公式就可以實現的一些特效,還有我們經常用的 變灰特效 。而這個特效已經內置在 Cocos 中,公式是什么呢?大家自行查閱,課后作業~~

image.png

OK,本章完,完整代碼在我的 Github 倉庫Gitee 倉庫 中可以找到。

下一篇:

上一篇:

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。