
コンピュータグラフィックスにおいて、シェーダーはレンダリングパイプラインを通過するデータに適用されるプログラム可能な操作です。[ 1 ] [ 2 ]シェーダーは頂点やプリミティブなどのデータに作用し、ジオメトリやフラグメントを生成または変形し、レンダリングされた画像の色を計算します。[ 2 ]
シェーダーは、さまざまな操作を実行できます。現代のリアルタイムコンピュータグラフィックスでは、シェーダーはグラフィックス処理ユニット(GPU)上で実行されます。GPUは、プログラムの並列実行を提供する専用ハードウェアです。画像レンダリングは、並列処理が容易な問題(アムダール指数が1)であるため、シェーダーはSIMDハードウェアなどの並列コンピューティングから大きな恩恵を受けます。レンダリングの高速化への取り組みにより、GPUのような高度に並列化されたプロセッサが開発され、現在では汎用コンピューティングに使用されています。[ 3 ] [ 4 ]汎用目的で使用されるシェーダーは、一般的にコンピュートシェーダーと呼ばれます。
「シェーダー」という用語は、ピクサーが1988年5月に最初に公開したRenderManインターフェース仕様のバージョン3.0で初めて一般に紹介されました。[ 5 ]
グラフィックス処理ユニットが進化するにつれて、OpenGLやDirect3Dなどの主要なグラフィックス ソフトウェア ライブラリがシェーダーをサポートするようになりました。最初のシェーダー対応 GPU はピクセル シェーディングのみをサポートしていましたが、開発者がシェーダーのパワーに気づくとすぐに頂点シェーダーが導入されました。プログラマブル ピクセル シェーダーを搭載した最初のビデオ カードは、2001 年にリリースされた Nvidia GeForce 3 (NV20)でした。 [ 6 ]ジオメトリ シェーダーはDirect3D 10 と OpenGL 3.2 で導入されました。グラフィックス ハードウェアは統一されたシェーダー モデルに向かって進化し、すべてのシェーダーが平等になりました。
シェーダーの従来的な用途は、グラフィックスパイプライン内のデータに対して操作を行い、画像のレンダリングを制御することです。グラフィックスシェーダーは、パイプライン内での位置、操作されるデータ、および使用されるグラフィックスAPIに基づいて分類されます。
頂点シェーダーは、グラフィックスプロセッサに渡される各 3D頂点に対して 1 回実行されます。その目的は、仮想空間における各頂点の 3D 位置を、画面上に表示される 2D 座標 (および Z バッファの深度値) に変換することです。 [ 7 ]頂点シェーダーは、位置、色、テクスチャ座標などのプロパティを操作できますが、新しい頂点を作成することはできません。頂点シェーダーの出力は、パイプラインの次のステージ (存在する場合はジオメトリシェーダー、存在しない場合はラスタライザー)に送られます。頂点シェーダーを使用すると、 3D モデルを含むあらゆるシーンで、位置、動き、照明、色の詳細を強力に制御できます。
ジオメトリシェーダーはDirect3D 10とOpenGL 3.2で導入されました。以前は拡張機能を使用することでOpenGL 2.0+でも利用可能でした。[ 8 ]このタイプのシェーダーは、グラフィックスパイプラインの先頭に送られたプリミティブから、点、線、三角形などの新しいグラフィックスプリミティブを生成できます。 [ 9 ]
ジオメトリシェーダープログラムは、頂点シェーダーの後に実行されます。ジオメトリシェーダーは、隣接情報を含むプリミティブ全体を入力として受け取ります。たとえば、三角形を操作する場合、3つの頂点がジオメトリシェーダーへの入力となります。シェーダーは、0個以上のプリミティブを出力し、それらはラスタライズされ、その断片が最終的にピクセルシェーダーに渡されます。
ジオメトリシェーダーの一般的な用途としては、ポイントスプライトの生成、ジオメトリのテッセレーション、シャドウボリュームの押し出し、キューブマップへのシングルパスレンダリングなどが挙げられます。ジオメトリシェーダーの利点を実際に示す例としては、メッシュの複雑さの自動変更があります。曲線の制御点を表す一連の線分がジオメトリシェーダーに渡され、必要な複雑さに応じて、シェーダーは曲線のより良い近似値を提供する追加の線を自動的に生成します。
フラグメントシェーダー(ピクセルシェーダーとも呼ばれる)は、各「フラグメント」の色やその他の属性を計算します。フラグメントとは、最大で単一の出力ピクセルに影響を与えるレンダリング作業の単位です。最も単純な種類のピクセルシェーダーは、1 つのスクリーンピクセルを色値として出力します。複数の入力/出力を持つより複雑なシェーダーも可能です。[ 10 ]ピクセルシェーダーは、常に同じ色を出力するだけのものから、照明値を適用するもの、バンプマッピング、影、鏡面反射、半透明などの現象を実行するものまで多岐にわたります。フラグメントの深度を変更したり(Z バッファリングのため)、複数のレンダーターゲットがアクティブな場合は複数の色を出力したりできます。3D グラフィックスでは、ピクセルシェーダーはシーンのジオメトリ(頂点データ)を知らずに単一のフラグメントのみを操作するため、一部の複雑な効果を単独で生成することはできません。ただし、ピクセルシェーダーは描画されているスクリーン座標を知っており、スクリーン全体の内容がテクスチャとしてシェーダーに渡された場合は、スクリーンと近くのピクセルをサンプリングできます。この技術により、ぼかしや、カートゥーン/セルシェーダーのエッジ検出/強調など、さまざまな2次元後処理効果を実現できます。ピクセルシェーダーは、パイプライン内の任意の2次元画像(スプライトやテクスチャ)の中間段階で適用することもできますが、頂点シェーダーは常に3Dシーンを必要とします。たとえば、ピクセルシェーダーは、ラスタライズされた後のビデオストリームの後処理やフィルタとして機能できる唯一の種類のシェーダーです。
OpenGL 4.0とDirect3D 11では、テッセレーションシェーダーと呼ばれる新しいシェーダークラスが導入されました。これは、従来のモデルに2つの新しいシェーダーステージ、すなわちテッセレーション制御シェーダー(ハルシェーダーとも呼ばれる)とテッセレーション評価シェーダー(ドメインシェーダーとも呼ばれる)を追加したもので、これらを組み合わせることで、実行時に数学関数に基づいてより単純なメッシュをより細かいメッシュに分割できます。この関数は、さまざまな変数、特にビューイングカメラからの距離に関連付けられ、アクティブなレベルオブディテールスケーリングを可能にします。これにより、カメラに近いオブジェクトは細かいディテールを持ち、遠いオブジェクトはより粗いメッシュを持ちながらも、品質は同程度に見えるようになります。また、非常に複雑なメッシュをメモリからダウンサンプリングするのではなく、シェーダーユニット内でメッシュを細分化できるため、必要なメッシュ帯域幅を大幅に削減できます。一部のアルゴリズムは任意のメッシュをアップサンプリングできますが、他のアルゴリズムでは、メッシュに「ヒント」を付けて、最も特徴的な頂点とエッジを指定できます。
2017年頃、AMD Vegaマイクロアーキテクチャは、ジオメトリの処理に必要なデータにアクセスできるコンピュートシェーダーにやや似た、プリミティブシェーダーという新しいシェーダーステージのサポートを追加しました。[ 11 ] [ 12 ]
Nvidiaは2018年にTuringマイクロアーキテクチャでメッシュシェーダーとタスクシェーダーを導入しましたが、これらもコンピュートシェーダーをモデルにしています。 [ 13 ] [ 14 ] Nvidia Turingは、Ampere RTX 30シリーズがリリースされる数か月前に、DirectX 12 Ultimate APIを介してメッシュシェーディングをサポートする世界初のGPUマイクロアーキテクチャです。[ 15 ]
2020年、AMDとNvidiaは、DirectX 12 Ultimateを介してメッシュシェーディングをサポートするRDNA 2とAmpereマイクロアーキテクチャをリリースしました。[ 16 ]これらのメッシュシェーダーにより、GPUはより複雑なアルゴリズムを処理できるようになり、CPUからGPUへの作業負荷が軽減され、アルゴリズムが集中するレンダリングでは、シーンのフレームレートまたは三角形の数が桁違いに増加します。[ 17 ] Intelは、2022年第1四半期に出荷されるIntel Arc Alchemist GPUがメッシュシェーダーをサポートすると発表しました。[ 18 ]
レイ トレーシングシェーダーは、MicrosoftではDirectX Raytracing を介して、Khronos GroupではVulkan、GLSL、SPIR-Vを介して、[ 19 ] AppleではMetalを介してサポートされています。NvidiaとAMDは、これらのシェーダーを実行するハードウェアの部分を「レイ トレーシング コア」と呼んでいます。[ 20 ]
コンピュートカーネルは、高スループットアクセラレータ(グラフィックス処理ユニット(GPU)、デジタル信号プロセッサ(DSP)、フィールドプログラマブルゲートアレイ(FPGA)など)用にコンパイルされたルーチンであり、メインプログラム(通常は中央処理装置上で実行)とは別個のものですが、メインプログラムによって使用されます。これらは、「 OpenCL C 」などの別のプログラミング言語で指定することも、シェーディング言語で記述された「コンピュートシェーダー」として指定することも、高水準言語で記述されたアプリケーションコードに直接埋め込むこともできます。[ 21 ] [ 22 ]コンピュートカーネルは、従来の言語でアルゴリズムを実装する際の内部ループ(ただし、暗黙の逐次操作はありません)または内部イテレータに渡されるコードにほぼ対応します。Microsoft は、 DirectComputeとしてこれをサポートしています。
この単一プログラム・複数データ方式のプログラミングパラダイムは、ベクトルプロセッサによく適合します。バッチ内のカーネルの各呼び出しは独立しており、データ並列実行が可能であるという前提に基づいています。ただし、場合によっては、要素間の同期(相互依存的な処理)のためにアトミック操作が使用されることがあります。個々の呼び出しには、(1次元以上の)インデックスが割り当てられ、重複しないという前提が守られている限り、バッファデータの任意のアドレス指定(スキャッターギャザー操作を含む)を実行できます。
Vulkan APIは、言語やマシンに依存しない方法でグラフィカルシェーダーと計算カーネルの両方を記述するための中間表現であるSPIR-Vを提供します。これは、言語の進化を促進し、統合メモリアーキテクチャやヘテロジニアスシステムアーキテクチャなどのハードウェア開発に合わせて、GPUの計算能力をより自然に活用できるようにすることを目的としています。これにより、CPUとGPU間の連携が強化されます。
コード最適化の手段として、LLM によるカーネル生成の分野では多くの研究が行われてきました。スタンフォード大学のスケーリング インテリジェンス ラボが作成したKernelBench [ 23 ]は、LLM が効率的な GPU カーネルを生成する能力を評価するためのフレームワークを提供します。Cognitionは、効率的な CUDA カーネルを作成する Kevin 32-B を作成しました。これは、2025 年 5 月の時点で KernelBench で最もパフォーマンスの高いモデルでした。[ 24 ]
コンピュートシェーダーとは、シェーディング言語で記述された計算カーネルのことです。これらのシェーダーは、GPU上で頂点シェーダーやピクセルシェーダーと実行ユニットを共有します( GPGPU動作の一例)。グラフィックスパイプラインにおいて、アニメーションやライティングアルゴリズムの追加ステージ(タイルフォワードレンダリングなど)といった用途で使用される場合もあれば、グラフィックス以外の用途で使用される場合もあります。一部のレンダリングAPIでは、コンピュートシェーダーがグラフィックスパイプラインとデータリソースを容易に共有できるため、グラフィックスとコンピュートの統合が容易になります。
テンソルシェーダーは、ニューラルネットワークベースのAIで一般的に使用されるタイプの演算である、大規模配列に対する行列演算を扱うアクセラレータプログラムです。これらはNPUまたはGPUで実行できます。テンソルシェーダーは、 MicrosoftがDirectML経由で、Khronos GroupがOpenVX経由で、AppleがCore ML経由で、GoogleがTensorFlow経由で、Linux FoundationがONNX経由でサポートしています。[ 25 ] NvidiaとAMDは、これらのシェーダーを実行するハードウェアの部分を「テンソルコア」と呼んでいます。[ 26 ]
シェーダーを記述するためのプログラミング言語は複数存在し、どの言語を使用するかは対象環境によって異なります。OpenGLのシェーディング言語はGLSL、Direct3DはHLSLを使用します。Appleデバイスで使用されているMetalフレームワークには、 Metal Shading Languageと呼ばれる独自のシェーディング言語があります。
現代のグラフィックス API では、シェーダーはエンド ユーザーに配布される前に中間言語であるSPIR-Vにコンパイルされることが増えています。この標準により、ターゲット プラットフォームに関係なく、シェーディング言語をより柔軟に選択できます。 [ 27 ] Vulkan と OpenGL で最初にサポートされた SPIR-V は、Direct3D でも採用されています。[ 28 ]
Unity、Unreal Engine、Godotといった最新のビデオゲーム開発プラットフォームでは、コードを記述することなくシェーダーを作成できるノードベースのエディタがますます多く採用されています。ユーザーには、接続されたノードの有向グラフが表示され、ユーザーは様々なテクスチャ、マップ、数学関数を、拡散色、鏡面反射色と強度、粗さ/金属感、高さ、法線などの出力値に制御できます。そして、このグラフがコンパイルされてシェーダーが生成されます。
ウェブ開発の分野では、ビジュアルシェーダーやコンポーネントベースのシェーダーツールも登場しています。shaders.comのようなプラットフォームは、Vue、React、Svelteなどのフロントエンドフレームワークに統合するためのコンポーネント駆動型のシェーダー構成を提供する一方、 ShadertoyやFragCoord.xyzのようなツールは、より低レベルのシェーダー作成とデバッグに重点を置いています。