前往
大廳
主題

【Godot Shader】使用 Particle 粒子和 Shader 製作消失、溶解效果

Czu 晞梓 | 2023-11-07 23:05:29 | 巴幣 2112 | 人氣 228




教學



展示一下怎麼使用 GPUParticle + Shader 做到下面這兩個效果


從上到下消失

先在 Sprite2D 上套用一個 Shader
讓 Sprite 可以由上往下消失
當 UV.y 小於參數 dissolve_below  就是透明的 vec4(0.0)
反之就是 原本 texture 的顏色 tex_color

調整 dissolve_below 的變化


建立一個新的 Node2D 場景
然後新增一個 GPUParticles2D 子節點

GPUParticles2D 節點裡新增 ParticleProcessMaterial

ParticleProcessMaterial 裡面調整粒子效果
可以調整顏色、大小等等
然後把 Gravity 重力調成 0
重點是要將 Emission Shape 改成 Box
Box Extents的 xy 改成 Sprite 高寬的一半


調整完後點選 ProcessMaterial 最右側的勾勾
打開選單選擇 轉換為 ShaderMaterial

剛剛調整的粒子參數
會自動轉換成 particles shader code
(但是 texture 不會保留,比如 GradientTexure 或是 CurveTexture
只會生成對應的 shader 程式碼 和 uniform 參數
所以要再重新設定)

下圖有調整粒子數量、顏色、大小等等
只要畫面是在一個方形內生成粒子
粒子固定不動就可以了

接著我們要開始控制粒子生成的位置
先把 GPUParticles2D > Drawing > Local Coords 設成開啟
讓粒子的座標位置是相對於父節點的位置

打開剛轉換的 particles shader
在 uniform 參數的最後加上 3 個參數
sprite:限制粒子只能生成在 sprite 不是透明的位置
down_border、top_border:限制粒子只能生成在 down_border ~ top_border 的範圍內

找到 shader 裡的 start() function  [註解1]
在 function 最後加上這段 code
這裡做的事情是把粒子的位置
轉換成 sprite texure 的 uv
然後用 uv 計算出遮罩
把起始位置在遮罩外的粒子的 ACTIVE 屬性設為 false
這個粒子就不會產生了

粒子的位置資訊是儲存在 TRANSFORM [ 3 ] 裡
所以把位置除上 sprite 大小 + 0.5 就是 uv
然後再以 sprite 的透明度 和 兩個參數 top_border 和 down_border 所夾的區間當成遮罩
用 if 判斷把不在範圍內的粒子 ACTIVE 設成 false 就好

設定一下剛剛 3 個參數
看一下效果
調整 down_border 和 top_border 的變化

到這邊基本上就完成了
現在要加入一點變黑加深的效果
重複利用一下剛剛的 particle shader 來做
先將剛才的 particle shader 存檔

在同一個場景裡加入一個新的 GPUParticle2D
新增 ShaderMaterial 載入剛剛存檔的 particles shader

調整 texture 如下圖

然後在 CanvasItem 裡新增 CanvasItemMaterial
Blend Mode 改成 Subtract

就可以得到類似這個的結果

最後使用 AnimationPlayer 去調整這些 shader 的參數


使用 NoiseTexture 消失

在這裡主要講一下跟前面例子不同的部分
套用在 sprite 的 shader 如下
跟前面的差異是使用 noise texture 判斷哪個部份是要消失的

設定 shader 的 noise 參數

FastNoiseLite 的參數可以自由調整
設定好 noise 後看一下效果
調整 dissolve_below 的變化

直接跳到 particles shader 的部分
多一個 noise 參數

以 noise 值計算遮罩範圍

noise 參數記得要跟 sprite 套用一樣的 noise texture 才可以
看一下效果

加上一樣的變黑效果
一樣使用 AnimationPlayer 製作動畫



註解 1:particle shader 裡面有 start() 和 process() 兩個 function
一個是在粒子生成的時候執行,另一個是生成後會重複執行
類似 Node 裡的 _ready() 和 _process()


目前在學習 shader 製作不同的效果
順便分享一些做出的效果並製作教學
歡迎給予意見和指教 OAO 掰掰~

創作回應

相關創作

更多創作