今回はモザイクシェーダーの作り方について解説します。
目次
モザイクシェーダーの作り方
画像素材の追加
まずは以下の画像をプロジェクトに追加します。
![](https://2dgames.jp/wp-content/uploads/2022/01/bg.png)
なお上記データには「white.png」というダミーデータも含まれています。このファイルも使用するのでプロジェクトに追加しておきます。
![](https://2dgames.jp/wp-content/uploads/2022/01/Main_tscn_-_TestMosaic_-_Godot_Engine-1024x731.png)
ルートシーンを作成し、”bg.png” を Spriteとして登録しておきます。
スプライトに直接モザイクシェーダーを記述する
まずはこのスプライトに直接シェーダーを適用してみます。
“Bg” ノードを選択して、インスペクタから「Canvas Item > Material > Material > [空]」をクリックして、「新規 Shader Material」を作成します。
![](https://2dgames.jp/wp-content/uploads/2022/01/Main_tscn_-_TestMosaic_-_Godot_Engine-1.png)
続けて作成した Material をクリックして、「Shader > [空]」を選び「新規 Shader」を作成します。
![](http://2dgames.jp/wp-content/uploads/2022/01/Main_tscn_-_TestMosaic_-_Godot_Engine-2.png)
作成したシェーダーをクリックすると、シェーダーエディタが開きます。
![](https://2dgames.jp/wp-content/uploads/2022/01/Main_tscn_-_TestMosaic_-_Godot_Engine-3.png)
シェーダーコード
シェーダーには以下のコードを記述します。
shader_type canvas_item;
// モザイクを正方形にするための調整比率.
const float RATIO = 1024.0 / 600.0;
void fragment() {
float size = 0.0001 + 0.05 * abs(sin(TIME));
float size2 = size * RATIO;
vec2 uv = UV;
uv -= mod(uv, vec2(size, size2));
// ブロックの位置を補正する
uv.x += mod(1.0, size) * 0.5;
uv.y += mod(1.0, size2) * 0.5;
COLOR.rgb = texture(TEXTURE, uv, 0.0).rgb;
}
実行するとスプライトにモザイクが適用されます。
![](https://2dgames.jp/wp-content/uploads/2022/01/mosaic.gif)
画面の一部分にモザイクを適用する
ただこの方法だとスプライトに直接適用されてしまっているので、画面の特定の部分のみに適用するようにしてみます。
bg スプライトのシェーダーはいったんクリアしておきます。
![](https://2dgames.jp/wp-content/uploads/2022/01/Main_tscn_-_TestMosaic_-_Godot_Engine-4.png)
次に “Main” ノードの直下に「TextureRect」を追加します。
![](https://2dgames.jp/wp-content/uploads/2022/01/Main_tscn_-_TestMosaic_-_Godot_Engine-5.png)
TextureRectのインスペクターの「Texture」に “white.png” を設定しておきます。そして 「Rect > Scale」でサイズを調整しておきます。今回は横2倍のサイズとしておきました。
![](https://2dgames.jp/wp-content/uploads/2022/01/Main_tscn_-_TestMosaic_-_Godot_Engine-6-499x1024.png)
そして TextureRect のシェーダーを作成し、以下のように記述します。
shader_type canvas_item;
// モザイクを正方形にするための比率
const float ASPECT = 2.0;
// モザイク1ブロックあたりの大きさ。
// 0.01 あたりが良さそう
uniform float size : hint_range(0.001, 0.1);
// 疑似乱数
vec2 random(vec2 uv){
uv = vec2( dot(uv, vec2(127.1,311.7) ),
dot(uv, vec2(269.5,183.3) ) );
return -1.0 + 2.0 * fract(sin(uv) * 43758.5453123);
}
void fragment() {
float size_y = size * ASPECT;
vec2 uv = SCREEN_UV;
uv -= mod(uv, vec2(size, size_y));
// 位置をランダムに少しだけずらす
float t = TIME * 2.0; // 動く速度
vec2 ofs = vec2(cos(t), sin(t));
uv += 0.005 * ofs;
// 右上に移動してしまうので補正する
uv.x += mod(1.0, size);
uv.y += mod(1.0, size_y);
COLOR.rgb = textureLod(SCREEN_TEXTURE, uv, 0.0).rgb;
}
すると TextureRect の領域のみモザイクが適用されます。
![](https://2dgames.jp/wp-content/uploads/2022/01/mosaic2.gif)
完成プロジェクトファイル
今回作成したプロジェクトを添付しておきます。