創作內容

30 GP

【教學】專案中的轉場Shader

作者:樂小呈│2020-12-12 12:57:40│巴幣:1,058│人氣:822
專案中的轉場Shader
還算簡單的效果(但我花了好幾天才成功 :P)
想要自己嘗試的可以先試試看 => 提示

教學
建立著色器和材質球
Create > Shader > Image Effect Shader
注意建立vertex shader的話frag uv會經過畫面轉換,但我們不需要所以建立image shader
建立一個UI Image,指定材質球

Shader 腳本
> 首先畫出UV空間
fixed4 frag (v2f i) : SV_Target
{
    return fixed4(i.uv, 0, 1);
}

> 使用 frac(取小數) 分割空間
Propertie
{
    _MainTex ("Texture", 2D) = "white" {}
    _Tiling ("Tiling", Range(5, 30)) = 10
}

float _Tiling;
fixed4 frag (v2f i) : SV_Target
{
    return fixed4(frac(i.uv * _Tiling), 0, 1);
}


> 把分割空間打包成函式,保持乾淨,並保留一個return 值用於之後運算
使用 floor(無條件捨去) 取得tile 座標
float tileValue(float2 uv, out float2 tilest, out float2 tilePos)
{
    tilest = frac(uv * _Tiling);
    tilePos = floor(uv * _Tiling);
    return 1;
}
fixed4 frag (v2f i) : SV_Target
{
    float2 tilest;
    float2 tilepos;
    tileValue(i.uv, tilest, tilepos);
    
    return fixed4(tilest, 0, 1);
}


> 寫一個隨機函式,將2D輸入轉為1D輸出
tileValue 回傳tile的隨機值
float Random2DTo1D(float2 input)
{
    return frac(sin(input.x * 61.87 + 0.1) * cos(input.y * 78.84 + 5.6) * 137.35 );
}
float tileValue(float2 uv, out float2 tilest, out float2 tilePos)
{
    tilest = frac(uv * _Tiling);
    tilePos = floor(uv * _Tiling);
    return Random2DTo1D(tilePos);
}
fixed4 frag (v2f i) : SV_Target
{
    float2 tilest;
    float2 tilepos;
    
    float value = tileValue(i.uv, tilest, tilepos);
    
    return value;
}


> 過濾器,做出敞開的效果
Properties
{
    _MainTex ("Texture", 2D) = "white" {}
    _Tiling ("Tiling", Range(5, 30)) = 10
    _Filter ("Filter", Range(0, 1)) = 0.5
}
float _Filter;
float tileFilter(float2 uv)
{
    float filter = lerp(-1, 1, _Filter);
    return abs(uv.x - 0.5) * 2 + filter;                
}
fixed4 frag (v2f i) : SV_Target
{
    float2 tilest;
    float2 tilepos;
    
    float value =  tileValue(i.uv, tilest, tilepos);
    float filter = tileFilter(i.uv);
    
    return filter;
}


> 但我們需要的是以tile為單位的過濾器,這樣才能做出格狀的消失
將tileFilter輸入改為以tile為單位
float tileFilter(float2 tilepos)
{
    float filter = lerp(-1, 1, _Filter);
    return abs(tilepos - _Tiling / 2) * _Filter + filter;                
}
fixed4 frag (v2f i) : SV_Target
{
    float2 tilest;
    float2 tilepos;
    
    float value =  tileValue(i.uv, tilest, tilepos);
    float filter = tileFilter(tilepos);
    
    return filter;
}


> 將隨機加入過濾器
float tileFilter(float2 tilepos, float noise)
{
    float filter = lerp(-1, 1 + noise, _Filter);
    return abs(tilepos - _Tiling/2) * _Filter + filter;                
}
fixed4 frag (v2f i) : SV_Target
{
    float2 tilest;
    float2 tilepos;
    
    float value =  tileValue(i.uv, tilest, tilepos);
    float filter = tileFilter(tilepos, value);
    
    return filter;
}


> 透明度混合
使用 saturate (限制數值在0~1的範圍),防止filter數值超出需要的範圍
並把 noise移進 saturate,讓隨機過濾的計算更正確
SubShader
{
    Cull Off ZWrite Off ZTest Always
    Blend SrcAlpha OneMinusSrcAlpha
}
float tileFilter(float2 tilepos, float noise)
{
    float filter = lerp(-1, 1, _Filter);
    filter = abs(tilepos - _Tiling/2) * _Filter + filter;
    filter = saturate(filter + noise);
    return filter;                
}


> 上色,將剛剛的過濾器設為透明度
Properties
{
    _Color ("Color", Color) = (0,0,0,0)
}
fixed4 _Color;
fixed4 frag (v2f i) : SV_Target
{
    float2 tilest;
    float2 tilepos;
    
    float value =  tileValue(i.uv, tilest, tilepos);
    float filter = tileFilter(tilepos, value);
    fixed4 color = fixed4(_Color.rgb, filter);
    
    return color;
}


> 使用step(根據閥值輸出0或1) 移除漸變,不需要的可以跳過這一步
float tileFilter(float2 tilepos, float noise)
{
    float filter = lerp(-1, 1, _Filter);
    filter = abs(tilepos - _Tiling / 2) * _Filter + filter;
    filter = saturate(filter + noise);
    filter = step(0.5, filter);
    return filter;                
}

搭拉~
至於在遊戲中使用的話,用C# 的material.setfloat修改 _Filter就行了
轉場就是把Image放大到擋住整個畫面而已

基本上就這樣,還想要甚麼延伸效果就自己研究吧 :P

這次是教學,和筆記不一樣,會再詳細一點
第一次寫教學,感覺配色沒選得很好 D:

有錯或有什麼建議歡迎提出~

引用網址:https://home.gamer.com.tw/TrackBack.php?sn=5009733
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:Shader|Unity

留言共 9 篇留言

I2OI3
學起來

12-12 13:14

樂小呈
學都學~12-12 17:59

今天怎麼那麼早就發日誌?

12-12 13:26

樂小呈
因為這不是日誌?12-12 17:59
在意你就輸了
感謝教學

12-12 13:30

樂小呈
ㄅ客氣12-12 17:59
蒼天落葉
酷斃了,已收藏

12-12 14:39

樂小呈
還好啦><12-12 17:59
joLoo 走鹿
不是配色不好,是你沒放蘿莉

12-12 14:51

樂小呈
低調一點不然FBI要破門了12-12 18:01
御安鴨·摸頭害鴨哭
這樣寫竟然都沒有錯誤出現,太強了

12-12 14:55

樂小呈
這重寫好幾次後整理出的精華code12-12 18:01
矮鵝
程式好複雜喔~~

12-12 15:13

樂小呈
ㄅ複雜ㄅ複雜12-12 18:01
kiwi(薇薇安)
天啊都是英文...

12-12 17:56

樂小呈
度的,字是英文,但和真的英文不太依樣12-12 18:02
居家型暗黑凶宅
好 我學!

12-13 03:06

樂小呈
學都可以學12-13 09:40
我要留言提醒:您尚未登入,請先登入再留言

30喜歡★angus945 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:【專案】ACG Baha... 後一篇:【紀錄】Shader -...


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】