Fragment Shader — その概要、役割、動作原理

著者: IT Sectr 公開日: 2026-06-11 読了時間: 10 分

Fragment Shaderは、グラフィックスパイプラインのプログラマブルステージであり、画像の各フラグメント(ピクセル)の最終的な色を決定します。Khronos Group、2025によると、フラグメントシェーダーはVertex Shaderから補間されたデータを受け取り、照明計算、テクスチャリング、色効果を実行します。Fragment Shaderは各ピクセルに対して呼び出されるため、グラフィックスパイプラインの中で最もリソースを消費するステージとなります。

要点

  • Fragment Shader — 画面上の各ピクセルの色を決定するGPUのプログラマブルステージ。
  • 呼び出し回数は画面解像度に等しく、レンダリングの主要な計算負荷となる。
  • テクスチャリングとPhong照明は、フラグメントシェーダーで実装される典型的なタスク。
  • GLSLとMetal Shading LanguageはFragment Shaderを記述するための標準ツールを提供する。
  • パフォーマンスはモバイルアプリケーションで60 FPSを達成するために重要。

Fragment Shaderとは?

Fragment Shader(フラグメントシェーダーまたはピクセルシェーダー)は、画像の各フラグメントの最終的な色を計算するグラフィックスパイプラインのプログラマブルステージです。フラグメントとは、深度テストとステンシルテストを通過した後、画面上の可視ピクセルになる可能性のあるピクセルです。

Fragment Shaderはラスタライゼーション後に実行され、3Dプリミティブ(三角形)がすでにフラグメントのセットに変換されています。シェーダーは、Vertex Shaderで三角形の頂点に対して計算され、三角形内部の各ピクセルに対して線形補間された補間属性(テクスチャ座標、法線、色)を受け取ります。

Fragment Shaderの進化の歴史

プログラマブルシェーダー登場以前(DirectX 8 / OpenGL 2.0以前)は、ピクセルの色計算は限られた操作セットを持つ固定パイプラインによって実行されていました。プログラマブルFragment Shaderは2001年に登場し、グラフィックス機能を根本的に拡張しました。開発者は各ピクセルの色を完全に制御できるようになり、フォトリアリスティックな照明、複雑なマテリアル、ポストエフェクトを実現できるようになりました。

Fragment Shaderの動作原理

Fragment Shaderは、ラスタライザーによって生成された各フラグメントに対してGPUによって起動されます。各シェーダー呼び出しは1つのフラグメントを処理し、その入力データを読み取り、ユーザーコードを実行し、出力値(RGBA形式のフラグメントの色)を書き込みます。

入力データと出力データ

Fragment Shaderの入力データには、Vertex Shaderからの補間属性(テクスチャ座標、法線、色)、ユニフォーム変数(光源、行列)、テクスチャサンプラーが含まれます。出力データは色ベクトル(OpenGL ES 2.0ではgl_FragColor、ES 3.0ではユーザー定義変数)であり、カラーバッファに書き込まれます。

glsl
#version 300 es
precision mediump float;

in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;

void main() {
    fragColor = texture(uTexture, vTexCoord);
}

Fragment Shaderの主な役割

Fragment Shaderは画像の視覚品質を担当します。ユーザーが画面上で見るすべてのエフェクト(色、影、反射、透明度)は、グラフィックスパイプラインのこのステージで計算されます。

テクスチャリング

最も頻繁な操作は、補間されたUV座標を使用してテクスチャから色をサンプリングすることです。Sampler2Dとtexture()関数を使用すると、テクスチャアトラスからピクセルの色を取得できます。フィルタリング(バイリニア、トライリニア、異方性)はサンプラーパラメーターを通じて制御され、さまざまな視野角での画像の鮮明さに影響します。

Phong照明

PhongシェーディングモデルはFragment Shaderでピクセルごとに計算され、頂点単位の照明(Gouraudシェーディング)よりも滑らかなハイライトを提供します。Phong照明には、環境光(ambient)、拡散反射(diffuse)、鏡面反射(specular)の3つの要素が含まれます。

glsl
// Fragment shader with Phong lighting
in vec3 vNormal;
in vec3 vPosition;
uniform vec3 uLightDir;
uniform vec3 uLightColor;

void main() {
    vec3 norm = normalize(vNormal);
    float diff = max(dot(norm, uLightDir), 0.0);
    fragColor = vec4(uLightColor * diff, 1.0);
}

ポストエフェクトとブレンディング

Fragment Shaderを使用すると、ルックアップテーブル(LUT)による色補正、ブラー、ブルーム効果、HDRレンダリングのトーンマッピングなどの後処理を適用できます。これらのエフェクトはすべてピクセルレベルで動作し、リアルタイムで実行されます。

Fragment Shaderのパフォーマンスと最適化

Fragment Shaderのパフォーマンスは、最新のモバイルゲームでFPSを制限する主な要因です。シェーダーは各ピクセルに対して呼び出されるため、コードの複雑さがわずかに増加するだけでも、フレームレートの顕著な低下につながる可能性があります。

主なパフォーマンス問題

  • Overdraw — オブジェクトの重なりによる同一ピクセルの再描画。半透明オブジェクトでは特に重要。
  • 条件分岐 — Fragment Shaderでの分岐はSIMD実行効率を低下させます。GPUは両方の分岐を実行する必要があるためです。
  • テクスチャサンプリング — 各テクスチャサンプリングには数十のGPUクロックサイクルのレイテンシがあります。サンプラーの数を最小限に抑えるとシェーダーが高速化します。

Fragment Shaderの最適化手法

モバイルGPU(Qualcomm Adreno、ARM Mali)では、float変数にmediump precisionを使用し、テクスチャサンプリングを統合し、シェーダー実行前に不可視フラグメントを破棄するearly-zテストを適用することを推奨します。

手法説明効果
Mediump precision32ビットの代わりに16ビット精度最大2倍の速度
Early-Zシェーダー前の深度テスト呼び出し削減
Texture atlasing複数の代わりに1つのテクスチャ切り替え削減

Fragment Shader vs Vertex Shader:比較

両方のタイプのシェーダーは開発者によってプログラミング可能ですが、パイプラインの異なるステージで動作し、異なるタスクを解決します。Fragment Shaderは呼び出し回数のため、はるかにリソースを消費します。

パラメータFragment ShaderVertex Shader
呼び出し回数数百万(画面解像度)数千(頂点数)
入力データ補間属性頂点属性
主な機能フラグメントの色計算ジオメトリ変換
テクスチャアクセス完全(複数サンプラー)制限付き
パフォーマンスへの影響高い(解像度に依存)中程度(ジオメトリに依存)

Fragment Shaderのコード例

Fragment Shaderは単純なもの(テクスチャサンプリング)から複雑なもの(多層照明)まであります。2つの実用的な例を見てみましょう:基本的なテクスチャリングと時間を使用したグラデーション効果です。

GLSLでの基本的なテクスチャリング

glsl
#version 300 es
precision mediump float;
in vec2 vTexCoord;
in vec3 vColor;
uniform sampler2D uDiffuseMap;
out vec4 fragColor;

void main() {
    vec4 texColor = texture(uDiffuseMap, vTexCoord);
    fragColor = texColor * vec4(vColor, 1.0);
}

Metal Shading Languageの例

cpp
#include <metal_stdlib>
using namespace metal;

struct FragmentIn {
    float2 texCoord;
    float3 normal;
};

fragment float4
fragmentMain(FragmentIn in [[stage_in]],
              texture2d<float> tex [[texture(0)]]) {
    constexpr sampler s(filter = linear);
    float4 color = tex.sample(s, in.texCoord);
    return color;
}

よくある質問

Fragment Shaderを簡単に言うと何ですか?

Fragment ShaderはGPU上のミニプログラムで、画面上の各ピクセルの色を決定します。Vertex Shaderがオブジェクトの形状を決定するのに対し、Fragment Shaderはそのオブジェクトの見た目(テクスチャ、照明、色)を決定します。

なぜFragment Shaderはそんなにリソースを消費するのですか?

Fragment Shaderは画面上のすべてのピクセルに対して呼び出されます。2532x1170(iPhone)の解像度のデバイスでは、1フレームあたり約300万回の呼び出しになります。60 FPSではシェーダーは毎秒1億8000万回実行され、膨大な計算能力が必要です。

Fragment Shaderではどのようなエフェクトが作れますか?

Fragment Shaderでは、テクスチャリング、照明(Phong、PBR)、影、反射、屈折、bloom、被写界深度、色補正、LUTフィルター、プロシージャルテクスチャ生成が実装されます。

モバイルデバイスでFragment Shaderを最適化するには?

floatにはmediump precisionを使用し、テクスチャサンプリングの数を減らし、early-zカリングを適用し、シェーダー操作を統合し、シェーダー内の条件分岐を避けてください。

Fragment ShaderとPixel Shaderの違いは?

同じものです。Fragment Shaderという用語はOpenGL / Vulkanで使用され、Pixel ShaderはDirect3D(Microsoft)の用語で使用されます。機能的には同一で、どちらも各フラグメント/ピクセルの色を計算します。

まとめ

  • Fragment Shader — 画像の各ピクセルの色を計算するGPUのプログラマブルステージ。
  • 呼び出し回数は画面解像度に等しく、最もリソースを消費するレンダリングステージ。
  • テクスチャリング、Phong照明、ポストエフェクトがフラグメントシェーダーの主な役割。
  • パフォーマンスはテクスチャサンプリング数とhighp precisionの使用に直接依存。
  • Mediump precisionとearly-zテストはモバイルGPUの主要な最適化手法。
  • OpenGL ESはFragment Shaderという用語を使用し、Direct3DはPixel Shaderを使用 — 意味は同じ。
  • GLSLとMetal Shading Languageはモバイル開発におけるFragment Shader記述の主要言語。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください