WebGPU シェーディング言語( WGSL、インターネット メディア タイプ: text/wgsl) は、Web 上のWebGPU APIの標準シェーダー言語である高レベルのシェーディング言語です。 [ 1 ] [ 2 ] WGSL の構文はRustの影響を受けており、ブラウザでの安全な実行のために、強力な静的検証、明示的なリソース バインディング、移植性を念頭に置いて設計されています。[ 1 ] Web 環境では、WebGPU 実装は WGSL ソースを受け入れ、プラットフォーム固有の中間形式 (たとえば、ユーザー エージェントを介して SPIR-V、DXIL、または MSL へ) にコンパイルしますが、このようなバックエンドは Web コンテンツには公開されません。[ 2 ] [ 3 ]
ウェブ上のグラフィックスは、従来はシェーダーがGLSL ESで記述されたWebGLを使用していました。アプリケーションがより最新のGPU機能と、計算およびグラフィックスパイプラインのより細かい制御を要求するようになったため、W3CのGPU for the Webコミュニティグループとワーキンググループは、ウェブプラットフォームに適した安全で移植可能なモデルを提供するために、WebGPUとその付属のシェーディング言語であるWGSLを作成しました。[ 4 ] [ 2 ] WGSLは、人間が読みやすく、従来のシェーディング言語でよく見られる未定義の動作を回避し、WebGPUのリソースおよび検証モデルに密接に整合するように開発されました。[ 1 ]
WGSLのデザインは以下を重視しています。
コアとなるスカラー型にはbool、、、、およびが含まれます。浮動小数点要素型には、ベクトル(例:、、、)と行列(最大 4×4)が使用できます。オプションのi32(半精度)は、WebGPU 機能によって有効にできます。利用可能かどうかは実装に依存します。[ 1 ] [ 2 ]アトミック型(、 )は、限定されたアドレス空間でのアトミック操作をサポートします。[ 1 ]u32f32vec2vec3vec4f16atomic<i32>atomic<u32>
変数は、let(不変)、var(可変)、またはconst(コンパイル時定数)で宣言されます。ストレージクラス(アドレス空間)には、、、、、、およびfunctionがあり、必要に応じてまたはでアクセスできます。 [ 1 ] WGSLは明示的なレイアウトとアライメントのルールを定義します。 、、などの属性は、バッファの相互運用性のためのデータレイアウトを制御します。[ 1 ]privateworkgroupuniformstoragereadread_write@align@size@stride
関数は明示的なパラメータ型と戻り値の型を使用します。制御フローにはif、、、、、および、/をswitch含む構造が含まれます。再帰は許可されていません。エントリポイントの呼び出しグラフは非巡回である必要があります。[ 1 ]forwhileloopbreakcontinue
@vertexシェーダーは、、、@fragmentまたはを使用してステージエントリポイントを定義します@compute。属性は@group、、@binding(リソースバインディング)、@location(ユーザー定義のI/O)、 (または@builtinなどのステージ組み込み)、、、およびなどのバインディングとインターフェイスを注釈します。[ 1 ]positionglobal_invocation_id@interpolate@workgroup_size
WGSL は、バッファ ( uniform、storage)、テクスチャ (サンプリング、ストレージ、マルチサンプリングのバリアント)、およびサンプラー (フィルタリング/非フィルタリング/比較) を公開します。バインディング モデルは、WebGPU のパイプライン レイアウト モデルに一致するグループとバインディングと呼ばれる記述子セットを介して明示的に示されます。[ 2 ] [ 1 ]
ブラウザは WGSL をプラットフォームに適した表現とネイティブドライバ形式にコンパイルします。具体的なコンパイルパイプラインはウェブコンテンツからは見えません。[ 2 ] WGSL ソースは厳密な解析と静的検証を受け、WebGPU は境界外メモリハザードを回避するために堅牢なリソースアクセスルールを適用し、実装間で予測可能な動作に貢献しています。[ 2 ] [ 1 ]
WGSLは、頂点、フラグメント、計算の3つのパイプラインステージをサポートしています。[ 1 ]
頂点シェーダーは、頂点ごとの入力を変換し、クリップ空間の位置を組み込みposition関数に書き込むなど、ラスタライズ用の値を生成しています。[ 1 ]
/* MVPマトリックスによって位置を変換し、色を渡します。 */struct VertexInput { @location ( 0 ) position : vec3f , // vec3f は vec3<f32> のエイリアスです@location ( 1 ) color : vec3f , };struct VertexOutput { @builtin ( position ) clip_position : vec4f , @location ( 0 ) color : vec3f , };@group ( 0 ) @binding ( 0 ) var < uniform > mvp : mat4x4f ;@vertex fn main ( v_in : VertexInput ) -> VertexOutput { var v_out : VertexOutput ; v_out . clip_position = mvp * vec4f ( v_in . position , 1.0 ); v_out . color = v_in . color ; return v_out ; }フラグメントシェーダーはフラグメントごとに実行され、カラーアタッチメントに書き込まれるカラー(およびオプションで深度)出力を計算します。[ 1 ]
/* 不透明なアルファ値を持つ補間色を書き込みます。*/@fragment fn main ( @location ( 0 ) color : vec3f ) -> @location ( 0 ) vec4f { return vec4f ( color , 1.0 ); }半精度(vec4h、の省略形)が必要な場合は、コードの先頭にステートメントを追加する必要があります。vec4<f16>enablef16;
コンピュートシェーダーはワークグループで実行され、汎用GPU計算に使用されます。[ 1 ]
/* 入力バッファの要素を倍増させて出力バッファに格納します。 */struct Params { element_count : u32 , };@group ( 0 ) @binding ( 0 ) var < storage , read > in_data : array < f32 > ; @group ( 0 ) @binding ( 1 ) var < storage , read_write > out_data : array < f32 > ; @group ( 0 ) @binding ( 2 ) var < uniform > params : Params ;@compute @workgroup_size ( 64 ) fn main ( @builtin ( global_invocation_id ) gid : vec3 < u32 > ) { let idx : u32 = gid . x ; if ( idx >= params . element_count ) { return ; } out_data [ idx ] = in_data [ idx ] * 2.0 ; }従来のシェーディング言語と比較して、WGSLは次の利点があります。