小屋創作

日誌2020-12-12 12:57

【教學】專案中的轉場Shader

作者:樂小呈

專案中的轉場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:

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

30

9

LINE 分享

相關創作

《Pintaris》 自製遊戲介紹

Canvas Scaler

20240518 遊戲進度 施工圍籬(可破壞)

留言

開啟 APP

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

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