twitterにアップしたGameBoy風に見えるようなImageEffectのシェーダコードを貼っておきます。
さて、昨日と今日にかけて4つの記事(3つ+α)を投稿しました。Qiitaに貼り付ける用に、
— MIYAKE (@ScreenPocket) April 16, 2020
GameBoy風ImageEffect用シェーダ修正版の動画撮り直した。
twitterに貼るとボヤケてドット感薄れるので、
前回よりもドット幅広げたけどどうだろう。 pic.twitter.com/GG56FclUwX
- シンプルなImageEffectその1。モザイク。
- シンプルなImageEffectその2。モノクロ。
- モノクロImageEffectをベースに、スクリーン合成の話。 〜月曜日のたわわのようなトーンを目指して〜
- シンプルなImageEffectその3。Posterization
ここで全部の集大成としてGameBoy風の見た目になるようなImageEffect用シェーダを作ります。
正直に3つ(モザイク、モノクロ(スクリーン合成)、Posterization)のImageEffectをかけても良いのですが、
3回もGraphic.Blit()を行うのは処理がもったいないので、計算部分を一つにまとめたOldMobileGame.shaderを用意しました。
OldMobileGame.shader
Shader "ScreenPocket/ImageEffect/OldMobileGame"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_UvDivideNum ( "UV Divide Num", Float ) = 128
_ColorDivideNum ( "Color Divide Num", Float ) = 4
_Color ("Main Color", Color ) = (0.025,0.35,0,1)
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
float _UvDivideNum;
float _ColorDivideNum;
fixed4 _Color;
fixed4 frag (v2f i) : SV_Target
{
//モザイク状にサンプリングする
float2 uv = floor(i.uv * _UvDivideNum) / _UvDivideNum;
half4 col = tex2D( _MainTex, uv );
//モノクロ化
col.rgb = Luminance(col.rgb);
//ポスタリゼーションで色数を刻ませる
col.rgb = floor(col.rgb * _ColorDivideNum) / _ColorDivideNum;
//スクリーン合成で色を乗せる
col.rgb = 1 - (1 - col.rgb) * (1 - _Color.rgb);
return col;
}
ENDCG
}
}
}
それっぽい感じが出せたかな?
そのまま使うのも良いですが、元の色(tex2D( _MainTex, i.uv ))をキープしておいてシームレスに切り替えてみるとか、
ドット絵が急にリアルになるような世界観の切り替わり演出にも応用できそうですね。