title: "ポストプロセス" description: "シェーダーを使ったポストプロセスエフェクトを学びます。ビネット、カラーグレーディング、CRTエフェクトなどの画面全体に適用する効果を実装します。" chapter: "09-advanced" order: 1 challenge: description: "CRTモニター風のスキャンラインエフェクトを作りましょう。横方向の走査線と、画面端の歪み(バレルディストーション)を組み合わせて、レトロなモニター風の見た目を再現してください。" hints:
- "スキャンラインは sin(uv.y * 解像度 * PI) で作れます。暗い横線が等間隔に走るパターンです。"
- "バレルディストーション: vec2 centered = uv - 0.5; centered *= 1.0 + dot(centered, centered) * 0.3; vec2 distorted = centered + 0.5;"
- "完成形: バレルディストーション後のUVでパターンを取得し、スキャンライン float scanline = sin(distorted.y * u_resolution.y * 3.14159) * 0.04; を減算、さらにビネットを掛け合わせると完成です。"
ポストプロセス
ポストプロセスとは
ポストプロセスは、シーンがレンダリングされた後に画面全体に適用するエフェクトです。映画やゲームで見かける「フィルター」のようなもので、最終的な見た目を大きく変えることができます。
フラグメントシェーダー上では、画面全体をカバーする1枚のクワッド(四角形)にシェーダーを適用する形で実装します。
ビネット効果
ビネットは画面の端を暗くするエフェクトです。カメラのレンズの光量落ちを模した、映画的な雰囲気を出す定番テクニックです:
float vignette(vec2 uv) {
vec2 centered = uv - 0.5;
float dist = length(centered);
return 1.0 - smoothstep(0.3, 0.7, dist);
}
中心からの距離に応じて暗くするだけですが、効果は絶大です。
カラーグレーディング
映画のようなカラートーンを作るカラーグレーディング。基本的には色のリフト(暗部)、ガンマ(中間調)、ゲイン(明部)を調整します:
// ティール&オレンジ(映画風の色調)
vec3 colorGrade(vec3 color) {
// 暗部にティール(青緑)を加える
vec3 shadows = vec3(0.0, 0.05, 0.1);
// 明部にオレンジを加える
vec3 highlights = vec3(0.1, 0.05, 0.0);
float luma = dot(color, vec3(0.299, 0.587, 0.114));
color += shadows * (1.0 - luma);
color += highlights * luma;
return color;
}
グロウ(Bloom風)
明るい部分をぼかして重ねると、光が溢れるグロウ効果が得られます。フラグメントシェーダーだけでの完全なBloomは難しいですが、簡易的な実装は可能です:
// 明るい部分の抽出
float brightness = max(max(color.r, color.g), color.b);
vec3 glow = color * smoothstep(0.6, 1.0, brightness);
// ぼかしを加えて合成(擬似的なグロウ)
finalColor = color + glow * 0.5;
フィルム粒子
ランダムなノイズを少量加えると、フィルムのような粒子感が出ます:
float grain = random(uv + fract(u_time)) * 0.05;
color += grain - 0.025;
u_time を加えることで、フレームごとに異なるノイズパターンが生成され、フィルムの粒子のように見えます。
色収差(Chromatic Aberration)
RGB各チャンネルのUV座標を少しずらすと、レンズの色収差を模した効果が得られます:
vec2 offset = (uv - 0.5) * 0.01;
float r = pattern(uv + offset);
float g = pattern(uv);
float b = pattern(uv - offset);
vec3 color = vec3(r, g, b);
右のエディタでは、ビネットとカラーグレーディングを組み合わせて映画風の雰囲気を作っています。
エフェクトの重ね方
ポストプロセスは順番に重ねていきます。順序によって結果が変わることもあるので注意が必要です:
vec3 color = basePattern(uv); // ベースのパターン
color = colorGrade(color); // カラーグレーディング
color += grain; // フィルム粒子
color *= vignette(uv); // ビネット(最後に)
一般的には、ビネットは最後に適用します。
まとめ
- ポストプロセスは画面全体に適用する最終エフェクト
- ビネットは画面端を暗くして映画的な雰囲気を出す
- カラーグレーディングで色調を映画風に
- グロウ、フィルム粒子、色収差などを組み合わせて表現力を高める