シェーダー

シェーダー（英: shader）とは、3次元コンピュータグラフィックスにおいて、シェーディング（陰影処理）を行うコンピュータプログラムのこと。「shade」とは「次第に変化させる」「陰影・グラデーションを付ける」という意味で、「shader」は頂点色やピクセル色などを次々に変化させるもの（より具体的に、狭義の意味で言えば関数）を意味する。

解説

技術的な視点から見るとシェーダーは（物体の位置を計算・決定するモデリングシステムやレイアウト・アニメーションシステムとは違い）物体の色の計算を担当するレンダラの一部である。すなわち、CGレンダリングソフトはリアルタイム／非リアルタイムを問わず、ソフトウェアあるいはハードウェアによるシェーダーを必ず備えていることになる。
RenderMan Shading Languageに代表されるように、プロダクション向けの3次元コンピュータグラフィックスのレンダリングでは古くからシェーディング処理をプログラムで記述してカスタマイズし、高品質な映像を作り出すといったことは当たり前のように行なわれてきたが、ゲームやCADのようなリアルタイム用途では処理時間の制約があるため、ソフトウェア（CPU）による定形の簡易シェーディングもしくはハードウェア（GPU）に固定実装された頂点変換・シェーディング機能（ハードウェアT&L）を使った簡素なシェーディングにとどまっていた。しかし、GPUがシェーダー機能や演算能力および柔軟性を強化し、プログラマビリティを獲得したことを受けて、OpenGLやDirect3D (DirectX) といった主なリアルタイムグラフィックスライブラリはAPIに専用のプログラマブル（プログラム可能）なシェーディング機能（プログラマブルシェーダー）を備えるようになった。OpenGLはバージョン1.5で、またDirect3Dはバージョン8でプログラマブルシェーダーが導入された。

プロダクション用途のシェーダー

プロダクションレンダリングは、静止画あるいは動画の生成が最終目的であるが、動画の場合は複数枚の静止画をつなぎ合わせて最終的にコンポジットを行ない、動画を作り出す。
リアルタイム用途と比較すると、プロダクションレンダリングでは時間や資源の制約が少ない。例えば、映画作品の1シーンをレンダリングするために数時間から数日をかけ、高品質な映像を作り出してもかまわない。レンダリングのための膨大な一時情報（中間計算結果などのキャッシュデータ）がコンピュータの物理メモリに収まりきらない場合でも、ハードディスクなどの二次記憶領域に退避してレンダリングを続行することもできる。
プロダクション用途のシェーダーでは、時間はかかるが高品質でリアリティの高い結果を生成できる、レイトレーシングなどのより厳密な大域照明（グローバルイルミネーション）ベース・物理ベースの陰影計算モデルが用いられる。例えば、PIXARのRenderManはグローバルイルミネーションをサポートしている。
また、物体同士の相互反射光の計算や、ある物体から別の物体へ投影されるシャドウ（影）の計算は、シーン内のライト（光源）の数に比例して時間がかかるようになるが、プロダクションレンダリングではデザイナーの望む数だけ自由に光源を配置することができる。

リアルタイム用途のシェーダー

ゲームなどのリアルタイムレンダリングでは、例えば60FPSの場合1フレームの描画にかけられる時間は最大でもわずか16ミリ秒程度であり、また頂点情報やテクスチャデータの格納・参照に使用できるビデオメモリ（グラフィックスカードに直結実装されたVRAM）の容量といった制約条件が多い。そのため、リアルタイム用途のシェーダーでは、相互反射などを考慮しない、低品質だが簡潔で高速な局所照明（ローカルイルミネーション）ベースの陰影計算モデルやZバッファ技法が用いられることが大多数である。GPUの進化とリアルタイム用プログラマブルシェーダーの発展を受けて、アルゴリズムやデータ構造を工夫してグローバルイルミネーションをリアルタイム実装している例（PRT、ライトフィールド、ISPM、SVO-GI法やNVIDIA GI WorksのCLIPMAP法など）も出てきているが、高性能なハードウェアを要求するなど、2018年時点でも未だ発展途上の技術である。シャドウや多光源環境のライティングに関しても、CSM/PSSMといった種々のシャドウマップ派生技術、および遅延シェーディング・遅延ライティングなどが考案されているが、時間および資源の制約が足かせとなり、品質や柔軟性はプロダクションレンダリングに及ばない。

リアルタイム処理系におけるプログラマブルシェーダーの出現と一般化

従来、CADソフトやゲームなどのリアルタイム 2D/3Dグラフィックス アプリケーション開発者は、グラフィックスハードウェア（グラフィックスカードにおけるGPU）に固定機能として実装されていた「定形のパイプライン」（固定機能パイプライン）を使用してグラフィック表示を行なっていた。
しかし、多数のグラフィック表現技術が次々と開発されていく中で、それらの技術をGPUメーカーが逐一ハードウェアに機能として実装していく形態は非効率であり、またユーザープログラマーが新しい技術を試すにはメーカーの対応を待たねばならなかった。この問題を解決するアイディアとして、GPUのパイプラインをソフトウェアプログラムにより組み立てる「プログラマブル パイプライン」と呼ばれるアーキテクチャが構築されることになる。以前は完全にブラックボックスだったグラフィックスパイプラインがユーザープログラマーに対して開放されることで、新たな陰影処理技法や各種エフェクト（画面効果）を試験的に実装してGPU上で走らせることが容易になり、先進的なGPUの機能を利用する優れた柔軟性と、表現力の爆発的な向上がもたらされた。
なお、従来のOpenGLあるいはDirectX (Direct3D) のAPIによってブラックボックスとして提供されていたシェーダーは、固定機能シェーダーと呼ばれ、プログラマブルシェーダーと区別される。OpenGLにおいてはバージョン1.5からプログラマブルシェーダーが拡張として導入され、バージョン2.0からは標準化された。Direct3Dにおいてはバージョン8からプログラマブルシェーダーが導入された。OpenGL 3.1、OpenGL ES 2.0、およびDirect3D 10以降はそれぞれ固定機能シェーダーを完全に廃止しており、グラフィックスパイプラインはプログラマブルシェーダーによって記述することが必須となっている。なおリアルタイム処理系において「シェーダー」といえば、通例プログラマブルシェーダーを指す 。また、Direct3D 9世代までは、頂点シェーダーとピクセルシェーダーの処理を担当するGPU内のハードウェア演算ユニット（演算器）は完全に分かれており、それぞれの演算ユニットのことを「シェーダー」と呼んでいた。そのため、かつてはグラフィックスカードのハードウェア性能指標として演算ユニット数を表すために「シェーダー数」という言葉が使われていたが、統合型シェーダーアーキテクチャを採用したDirect3D 10世代以降は「ストリームプロセッサ数（SP数）」あるいは「CUDAコア数」という言葉が用いられるようになっている    。
CGレンダリングソフトの多くは、最終的な出力結果を得るための高品質な計算モデルとして、レンダリング方程式に基づく、光学的・物理学的により厳密なグローバルイルミネーションモデルを実現する各種計算手法（レイトレーシングやラジオシティ、フォトンマッピングなど）を採用しているが、モデリングやパラメータ設定の作業中は、プレビューのために描画品質を落としてOpenGLあるいはDirect3Dによってリアルタイム表示する必要がある。GPUが固定機能シェーダーのみをサポートしていた頃は、プレビューは最終描画結果とはほど遠いものであったが、プログラマブルシェーダーをサポートするようになってからは、各CGソフトもプレビューにプログラマブルシェーダーを使用するようになり、プレビューの品質が飛躍的に向上した。2009年時点で、Autodesk 3ds Max、Autodesk Maya、Autodesk Softimage、およびNewTek LightWave 3Dといった有名なソフトウェアの最新版はいずれもプログラマブルシェーダーによるプレビューを実装している。
また、リアルタイム用のプログラマブルシェーダーはAdobe PhotoshopやAdobe Flashのように2DCGを主に扱うソフトウェアにもアクセラレータとして導入されることが多くなっている。GUIベースオペレーティングシステム (OS) のデスクトップ合成エンジンや標準2DグラフィックスAPIでも、Windows Aero/Direct2D (Windows) やQuartz Extreme/Core Image (macOS) などのように、GPUおよびプログラマブルシェーダーを活用したものが現れている。ハードウェア（グラフィックスカード）が一定のシェーダー機能を満たす場合、CPUの負荷が低減され、表示や応答が高速化されるなどのメリットがある。

シェーダーステージ

リアルタイム用途のプログラマブルシェーダーでは、グラフィックスパイプラインの中でもユーザープログラマーが制御できるステージがあらかじめ決められている。
OpenGL 3.2以降とDirect3D 10以降では3種類のシェーダーを使用できる。

頂点シェーダー（バーテックスシェーダー）

頂点シェーダー（英: Vertex Shader, VS）は主に入力頂点を座標変換（トランスフォーム）するための機能である。頂点シェーダーはオブジェクトを構成する頂点の集合（頂点配列、頂点バッファ）に対してのみ作用し、例えば3次元空間におけるXYZ位置座標や法線ベクトル、色、テクスチャマッピング座標（UV座標など）といった頂点の属性だけを参照・変換できる。3次元グラフィックスにおける主な座標変換にはワールド変換、ビュー変換、プロジェクション変換、およびビューポート変換が存在するが、頂点シェーダーが担当するのはワールド・ビュー・プロジェクション変換である。ワールド・ビュー変換はモデル・ビュー変換とも呼ばれる。なお頂点単位のライティングであれば、頂点シェーダーで座標変換のほかにライティング計算を行なうこともできる。頂点シェーダーで計算された頂点情報はジオメトリシェーダーに渡されるか、そのままピクセルシェーダーに渡される。
Direct3D 9では頂点シェーダーをソフトウェアエミュレーションすなわちCPUで実行することもできるが（D3DCREATE_SOFTWARE_VERTEXPROCESSING）、プログラマブルシェーダー機能に対応しているハードウェア（GPU）であれば多数のプロセッサコアを使用して並列に処理を行なうことができるので、CPUで頂点シェーダーを実行するよりもGPUを利用した方が高速になる。
なお、シェーダーモデル3.0（DirectX 9.0c、OpenGL 2.x世代）で導入されたVertex Texture Fetch (VTF) を使用すると、頂点シェーダーステージでテクスチャデータを参照することも可能となる。
シェーダーモデル4.0（DirectX 10世代）以降では、VTFはバッファデータの参照とともに標準化されている（OpenGLは3.1でVTFを標準化し、バーテックスシェーダーで少なくとも16個のTIUを使えるようになっている）。
さらに、OpenGL 4.2ではすべてのシェーダーステージにおいてイメージオブジェクトに対するロード／ストアを可能にする機能が標準化された。DirectXにおいても、バージョン11.1にて、ピクセルシェーダーやコンピュートシェーダーだけでなく、すべてのシェーダーステージにおいて各種リソースに対する書き込みが可能になっている。

ジオメトリシェーダー

ジオメトリシェーダー（英: Geometry Shader, GS）はピクセルシェーダーに渡されるオブジェクト内の頂点の集合を加工するために使用される。ジオメトリシェーダーにより、実行時に頂点数を増減させたり、プリミティブの種類を変更したりすることが可能となる。OpenGLではプリミティブシェーダーとも呼ばれる。
ジオメトリシェーダーはポイント、ライン、トライアングルといった既存のプリミティブから新しいプリミティブを生成できる。
ジオメトリシェーダーは頂点シェーダーの後に実行され、プリミティブ全体または隣接したプリミティブの情報を持つプリミティブを入力する。例えばトライアングルを処理するとき、3つの頂点がジオメトリシェーダーの入力となる。ジオメトリシェーダーはラスタライズされるプリミティブを出力でき、そのフラグメントは最終的にピクセルシェーダーに渡される。またプリミティブを出力せずにキャンセルすることもできる。
ジオメトリシェーダーのよくある使い方としては、ポイントスプライトの生成、ジオメトリテセレーション、シャドウボリュームの切り出し、キューブマップあるいはテクスチャ配列へのシングルパスレンダリングなどがある。

ピクセルシェーダー

ピクセルシェーダー（英: Pixel Shader, PS）はピクセル単位のライティングやポストプロセス（後処理）を行なうための機能である。ピクセルシェーダーはラスタライズされるプリミティブの各ピクセルに影響する。また、ピクセルシェーダーにてテクスチャを参照することでバンプマッピングやフォグ、シャドウ、ブルームといったエフェクトを最終レンダリング結果に適用することもできる。OpenGLではフラグメントシェーダー（英: Fragment Shader, FS）と呼ばれる（Fragment: 断片）。
ピクセルシェーダーはピクセルを操作する機能であり、頂点シェーダーもしくはジオメトリシェーダーから入力された情報を元にテクスチャを合成したり表面色を適用したりする。ピクセルを操作する処理にかかる時間は入力プリミティブのラスタライズ後のピクセル数や出力解像度に左右されるため、通例は頂点単位の処理と比較して高負荷である。これをピクセルシェーダープログラムとしてプログラミングし、高い並列処理性能を持つGPUで実行することにより、バンプマッピング等のより高度なエフェクトをCPUですべて実行するよりもはるかに高いパフォーマンスで実現できる。なお、通常のレンダーターゲットを使ったピクセルシェーダーでは、アルファブレンド（アルファ合成）処理の詳細をプログラムすることはできない。

テッセレーションシェーダー

OpenGL 4.0以降とDirect3D 11以降ではさらにテッセレーションシェーダーをオプションとして使用できる。

並列処理

シェーダーは膨大な要素の集合に対して変換処理を同時に適用するように記述される。例えばモデル内の全ての頂点を一様に平行移動・回転・拡大縮小したり、スクリーン（2次元画像バッファ）の特定の範囲内の各ピクセルに対して一様にフィルタリング・輝度変換などを実行したりする、などである。これらの処理は対象となる全要素に等しく適用される。これは並列処理に非常に適している。多くの先進的なGPUでは並列処理効率を高めるべく、（一般的なCPUのマルチコアとは比較にならないほどの）超マルチコア設計となっている。
リアルタイム描画性能と柔軟性を向上させるべく発展してきたGPUだが、ハードウェアレベルでの柔軟性と汎用性を強化したDirect3D 10世代GPUの登場以後、この並列処理におけるGPUの優位性を汎用計算に利用しようという試み（GPGPU）が活発化している。GPGPU向けの汎用APIとして、2006年にはNVIDIAからCUDAが、また2008年にはKhronosグループからOpenCLが発表され、それぞれ機能拡張を続けている。
BlenderのCyclesエンジンやV-Ray RTなどのように、CUDAやOpenCLを経由してプロダクションレンダリングにもGPUを活用し、計算時間を短縮するソフトウェアも出現してきている。

コンピュートシェーダー

GPGPU向けの汎用APIとして代表的なものはCUDAとOpenCLだが、OpenGL 4.3以降、OpenGL ES 3.1以降、およびDirect3D 11以降では、主にグラフィックス連携を重視したGPGPUのためのコンピュートシェーダー（Compute Shader、演算シェーダー）が搭載された。コンピュートシェーダーは前述のグラフィックスパイプラインとは独立して動作することのできるステージである。なお、コンピュートシェーダーは座標変換や陰影計算にとどまらない汎用計算が可能となっているため、「シェーダー」という命名はほかのシェーダーステージに合わせた便宜上のものである。Direct3Dのコンピュートシェーダーに関しては、Direct3D APIを含めた総称としてDirectComputeと呼ばれている。
コンピュートシェーダーがCUDAやOpenCLと比較して優れている点として、Direct3D（OpenGL）リアルタイムグラフィックスパイプラインとの連携がしやすい（シミュレーションの実行と可視化に向いている）、Direct3D/HLSL（OpenGL/GLSL）をすでに利用している場合は修得が容易である、などが挙げられる。

シェーディング言語

シェーダーを記述（プログラミング）するための種々の言語がプロダクションレンダリング（非リアルタイム）向けおよびリアルタイムレンダリング向けにそれぞれ開発されている。
多くの3DCGソフトウェアやオーサリングツール、ゲームエンジンにはノードエディタと呼ばれるGUIツールが搭載されており、ノードエディタを使うことでカスタムシェーダー開発を直感的に行なうことができるが、シェーディング言語を直接利用すると細やかな調整を行なうことができる。