「画面の四隅をふわっと暗くしたい」「レトロなCRT風の走査線をのせたい」「被弾した瞬間、画面全体を赤く点滅させたい」——こうした ゲーム画面まるごと にかかる演出は、個別オブジェクトのシェーダー では作れません。使うのは ポストプロセスシェーダー です。
ポストプロセスは、 一度描き終えた画面全体を読み込んで、その上から加工 をかける手法です。この記事では、その構成(CanvasLayer+全画面ColorRect)から、画面を読む鍵 hint_screen_texture 、ビネットや色収差などの定番レシピ、被弾フラッシュの実践までを解説します。
この記事でわかること
- ポストプロセスの構成(CanvasLayer+全画面ColorRect)
hint_screen_textureとSCREEN_UVで 描画済み画面を読む- 定番レシピ (ビネット・色収差・CRT走査線など)
- 被弾フラッシュ の実践と、SubViewport方式との使い分け
ポストプロセスの仕組み
ポストプロセスの考え方は、 「ゲーム画面を1枚の絵として描いてから、その絵に加工をかける」 です。写真を撮ってからフィルタをかけるのに似ています。

Godotでこれを実現する構成はシンプルです。
CanvasLayer:常にゲーム画面より手前に描かれるレイヤー。ここに載せたものが最前面になります- 全画面
ColorRect:画面いっぱいに広げた四角形。これが「加工をかけるキャンバス」になります ShaderMaterial:そのColorRectに割り当てる、加工の中身(シェーダー)
つまり、 画面全体を覆うColorRectにシェーダーをかけて、その下のゲーム画面を加工する わけです。ColorRectのアンカーを「Full Rect」にして画面全体に広げれば、準備完了です。
画面全体を読む:hint_screen_texture
ポストプロセスの心臓部が hint_screen_texture です。これは、シェーダーに 「今まさに描き終えた画面」 を渡してくれる仕組みです。

シェーダー側では、こう宣言して読みます。
shader_type canvas_item;
// hint_screen_texture で「描画済みの画面」を受け取る
uniform sampler2D screen_tex : hint_screen_texture, filter_linear_mipmap;
void fragment() {
// SCREEN_UV は画面上の座標。そこの色を読む
vec3 screen_color = texture(screen_tex, SCREEN_UV).rgb;
// ここで screen_color を加工する(例:そのまま出す)
COLOR = vec4(screen_color, 1.0);
}
ポイントは2つです。 hint_screen_texture が「加工前の画面」を screen_tex に流し込み、 SCREEN_UV がその画面上の位置(0.0〜1.0)を表します。この2つで画面の各ピクセルの色を読み、COLOR に加工結果を書けば、画面全体が変化します。あとは「読んだ色をどういじるか」がレシピごとの腕の見せどころです。
定番レシピ
読んだ画面をどう加工するかで、色々な画面効果が作れます。代表的なものを見てみましょう。

| レシピ | 何をするか | よく使う場面 |
|---|---|---|
| ビネット | 画面の四隅を暗く落とす | 集中感・シネマティックな演出 |
| 色収差 | 画面の端で色をわずかにずらす | 衝撃・酔い・グリッチ表現 |
| CRT走査線 | 横線とにじみでブラウン管風にする | レトロゲームの雰囲気 |
| グレースケール | 色を抜いてモノクロにする | 瀕死・回想・ポーズ中の演出 |
どれも「SCREEN_UV で画面を読み、色や座標をいじって COLOR に書き戻す」という同じ骨組みです。例えばビネットなら「画面中心からの距離に応じて暗くする」、グレースケールなら「RGBの平均を取って色を抜く」——加工の式が違うだけで、構成は共通です。
実践:被弾で画面を赤く光らせる
アクションの被ダメージ、ホラーの恐怖演出、シューティングのピンチ表現——「ダメージを受けた瞬間、画面全体が赤くフラッシュする」のは、状態をプレイヤーに直感的に伝える定番の画面効果です。ポストプロセスで組んでみましょう。

読んだ画面の色を、flash_amount(uniform)に応じて 赤に寄せる だけです。
shader_type canvas_item;
uniform sampler2D screen_tex : hint_screen_texture, filter_linear_mipmap;
uniform float flash_amount : hint_range(0.0, 1.0) = 0.0; // 外から制御する赤み
void fragment() {
vec3 screen_color = texture(screen_tex, SCREEN_UV).rgb;
vec3 red = vec3(0.8, 0.0, 0.0);
// flash_amount の割合だけ赤に寄せる
COLOR = vec4(mix(screen_color, red, flash_amount), 1.0);
}
スクリプト側は、被弾時に flash_amount を1に上げ、すぐ0へ戻すだけです。
@onready var mat: ShaderMaterial = $CanvasLayer/ColorRect.material
func on_damaged() -> void:
mat.set_shader_parameter("flash_amount", 0.6) # パッと赤く
# Tweenで0へ戻すと、赤みがスッと引く
create_tween().tween_property(mat, "shader_parameter/flash_amount", 0.0, 0.3)
ポイントは2つです。
- 画面全体に一律にかかる :個別キャラを光らせる modulate と違い、これは 画面全部 が赤くなります。「自分がダメージを受けた」感を強く出せます。
uniform+ Tween で制御 :flash_amountを1つ用意し、set_shader_parameter()で動かします。Tweenで0へ戻せば、赤みがなめらかに引いていきます。
SubViewport方式との使い分け
画面を加工する手段には、SubViewport を使う方法もあります。目的で使い分けます。

- ポストプロセス :完成した 画面全体に、後から一律 にかける。ビネット・CRT・全画面フラッシュなど
- SubViewport :特定の 映像を別途レンダリング して加工する。ミニマップ、監視カメラ、画面の一部だけの効果など
「ゲーム画面まるごと」ならポストプロセス、「一部の映像を作り込む」ならSubViewport、と覚えておけば迷いません。
おまけ:先に知っておくと良いこと
- 3Dにもかけられる :CanvasLayerの全画面ColorRectは2D・3Dどちらのゲームの上にも重なるので、3Dゲームの画面にもそのままポストプロセスをかけられます。
- 重ねがけは順序に注意 :複数のエフェクト(ビネット+CRTなど)をかけるなら、1つのシェーダーにまとめるか、ColorRectを重ねます。重ねる場合は下から上への処理順を意識します。
- 画面遷移のワイプにも :
SCREEN_UVと時間で「画面を左から徐々に塗りつぶす」ようにすれば、場面転換のワイプ演出もポストプロセスで作れます。
まとめ
- ポストプロセスは 描き終えた画面全体を読んで加工 する手法。構成は CanvasLayer+全画面ColorRect+ShaderMaterial
- 画面は
hint_screen_textureで受け取り、SCREEN_UVで各ピクセルを読む - ビネット・色収差・CRT走査線・グレースケールなど、加工の式を変えるだけ で多彩な画面効果が作れる
- 被弾フラッシュは、読んだ色を
flash_amount(uniform)で赤に寄せる だけ。Tweenで戻す - 全画面はポストプロセス、部分はSubViewport と使い分ける
まずは画面をそのまま出すだけの最小シェーダーを作り、そこにビネットを1つ足してみてください。画面全体がスッと締まって見える瞬間、ポストプロセスの効果を実感できます。
さらに学ぶために
- Fragment Shaderの基礎 ——シェーダーの基本文法(ポストプロセスの土台)
- SubViewportの活用法 ——部分的な映像加工との使い分け
- modulateによるホワイトフラッシュ ——個別オブジェクトの被弾演出
- Godot公式ドキュメント:Screen-reading shaders ——画面読み取りシェーダーの一次情報