GLSL と HLSL の対応を示すリファレンス
グラフィックス アーキテクチャを OpenGL ES 2.0 から Direct3D 11 に移植してユニバーサル Windows プラットフォーム (UWP) 向けのゲームを作成する際は、OpenGL シェーダー言語 (GLSL) コードを Microsoft 上位レベル シェーダー言語 (HLSL) コードに移植します。 ここで参照される GLSL は OpenGL ES 2.0 とは互換性がありません。HLSL は Direct3D 11 と互換性があります。 Direct3D 11 と以前のバージョンの Direct3D の違いについては、「機能のマッピング」をご覧ください。
- OpenGL ES 2.0 と Direct3D 11 の比較
- HLSL への GLSL 変数の移植
- HLSL への GLSL の型の移植
- HLSL への GLSL の定義済みグローバル変数の移植
- HLSL への GLSL 変数の移植の例
- Direct3D への OpenGL のレンダリング コードの移植例
- 関連トピック
OpenGL ES 2.0 と Direct3D 11 の比較
OpenGL ES 2.0 と Direct3D 11 には多くの類似点があります。 どちらも、類似したレンダリング パイプラインとグラフィックス機能があります。 ただし、Direct3D 11 はレンダリングの実装と API であり、仕様ではありません。OpenGL ES 2.0 はレンダリングの仕様と API であり、実装ではありません。 Direct3D 11 と OpenGL ES 2.0 は通常、次の点で異なります。
OpenGL ES 2.0 | Direct3D 11 |
---|---|
ハードウェアやオペレーティング システムにとらわれない仕様とベンダーが提供する実装 | Windows プラットフォームのハードウェア アブストラクションと認定の Microsoft 実装 |
多様なハードウェア向けに抽象化、ランタイムがほとんどのリソースを管理 | ハードウェアのレイアウトに直接アクセス。アプリがリソースと処理を管理できる |
サード パーティのライブラリ (たとえば、Simple DirectMedia Layer (SDL)) によって高レベルのモジュールを提供 | Direct2D などの高レベルのモジュールは下位モジュールに基づいて構築されるため、Windows アプリの開発が簡略化 |
ハードウェア ベンダーは拡張子によって区別 | Microsoft は、汎用的な方法で API にオプション機能を追加するため、特定のハードウェア ベンダーに限定されない |
GLSL と HLSL は一般に次の点で異なります。
GLSL | HLSL |
---|---|
手続き型、ステップ中心 (C など) | オブジェクト指向、データ中心 (C++ など) |
グラフィックス API に統合されたシェーダー コンパイル | HLSL コンパイラが中間バイナリ表現にシェーダーをコンパイルし、その後で Direct3D がそれをドライバーに渡します。
注 このバイナリ表現はハードウェアに依存していません。 通常はアプリの実行時ではなくアプリのビルド時にコンパイルされます。
|
変数ストレージ修飾子 | 入力レイアウトの宣言による定数バッファーとデータ転送 |
一般的なベクター型: vec2/3/4 lowp、mediump、highp |
一般的なベクター型: float2/3/4 min10float、min16float |
texture2D [Function] | texture.Sample [datatype.Function] |
sampler2D [datatype] | Texture2D [datatype] |
行優先マトリックス (既定) | 列主行列 (既定)
注 1 つの変数のレイアウトを変更するには、row_major 型修飾子を使います。 詳しくは、「変数の構文」をご覧ください。 コンパイラ フラグまたはプラグマを指定してグローバルな既定値を変更することもできます。
|
フラグメント シェーダー | ピクセル シェーダー |
注: HLSL には、2 つの個別のオブジェクトとしてテクスチャとサンプラーがあります。 GLSL では、Direct3D 9 と同様に、テクスチャのバインドはサンプラーの状態の一部です。
GLSL では、事前定義されたグローバル変数として OpenGL の状態の多くを示します。 たとえば、GLSL では、gl_Position 変数を使って頂点の位置を指定し、gl_FragColor 変数を使ってフラグメントの色を指定します。 HLSL では、アプリ コードからシェーダーに Direct3D の状態を明示的に渡します。 たとえば、Direct3D と HLSL を使う場合は、頂点シェーダーへの入力が頂点バッファーのデータ形式に一致し、アプリ コードの定数バッファーの構造がシェーダー コードの定数バッファー (cbuffer) の構造と一致する必要があります。
HLSL への GLSL 変数の移植
GLSL では、グローバル シェーダーの変数の宣言に修飾子を適用し、その変数にシェーダーの特定の動作を割り当てます。 HLSL では、シェーダーとやり取りする引数を使ってシェーダーのフローを定義するため、これらの修飾子は必要ではありません。
GLSL の変数の動作 | 相当する HLSL の要素 |
---|---|
uniform アプリ コードから uniform 変数を頂点シェーダーとフラグメント シェーダーのどちらか一方または両方に渡します。 これらのシェーダーを使って三角形を描画する前にすべての uniform の値を設定する必要があります。三角形のメッシュの描画中に値が変わらないようにするためです。 これらの値は変化しません。 フレーム全体に対して設定される uniform もあれば、特定の頂点ピクセル シェーダーのペアに対してのみ設定される uniform もあります。 uniform 変数はポリゴン単位の変数です。 |
定数バッファーを使います。 「定数バッファーを作成する方法」と「シェーダー定数」をご覧ください。 |
varying 頂点シェーダー内で varying 変数を初期化し、フラグメント シェーダーの同じ名前の varying 変数に渡します。 頂点シェーダーは各頂点でのみさまざまな変数の値を設定するため、ラスタライザーはその値を (透視補正の方法で) 補間し、フラグメント単位の値を生成してフラグメント シェーダーに渡します。 これらの変数は各三角形で異なります。 |
頂点シェーダーから取得した構造をピクセル シェーダーへの入力として使います。 セマンティック値が一致することを確かめてください。 |
attribute 属性は、アプリ コードから頂点シェーダーだけに渡す頂点の記述の一部です。 uniform とは異なり、頂点ごとに各属性の値を設定します。それにより、各頂点が異なる値を持つことができるようになります。 属性変数は頂点単位の変数です。 |
Direct3D アプリ コードで頂点バッファーを定義し、頂点シェーダーで定義されている頂点の入力と一致させます。 必要に応じてインデックス バッファーを定義します。 「頂点バッファーを作成する方法」と「インデックス バッファーを作成する方法」をご覧ください。 Direct3D アプリ コードで入力レイアウトを作成し、セマンティック値を頂点の入力の値と一致させます。 「入力レイアウトの作成」をご覧ください。 |
const シェーダーにコンパイルされ、変更されない定数。 |
static const を使用します。 static は、値が定数バッファーに公開されないことを表し、const は、シェーダーが値を変更できないことを表します。 そのため、値は初期化子に基づいてコンパイル時に把握されます。 |
GLSL では、修飾子のない変数は、各シェーダーに対してプライベートな通常のグローバル変数に過ぎません。
テクスチャ (HLSL での Texture2D) と関連のサンプラー (HLSL での SamplerState) にデータを渡すときに、通常は、ピクセル シェーダーのグローバル変数としてこれらを宣言します。
HLSL への GLSL の型の移植
HLSL に GLSL の型を移植する場合は、次の表を参考にしてください。
GLSL の型 | HLSL の型 |
---|---|
スカラー型: float、int、bool | スカラー型: float、int、bool また、uint、double 詳しくは、「スカラー型」をご覧ください。 |
ベクター型
|
ベクター型
vector は、float4 として定義される型でもあります (typedef vector <float, 4> vector;)。 詳しくは、「ユーザー定義型」をご覧ください。 |
マトリックス型
|
マトリックス型
また、マトリックスの定義にマトリックス型を使うこともできます。 例: matrix <float, 2, 2> fMatrix = {0.0f, 0.1, 2.1f, 2.2f}; matrix は、float4x4 として定義される型でもあります (typedef matrix <float, 4, 4> matrix;)。 詳しくは、「ユーザー定義型」をご覧ください。 |
float、int、sampler の有効桁数修飾子
|
有効桁数の型
詳しくは、「スカラー型」と「HLSL の最小精度の使用」をご覧ください。 |
sampler2D | Texture2D |
samplerCube | TextureCube |
HLSL への GLSL の定義済みグローバル変数の移植
GLSL の定義済みグローバル変数を HLSL に移植する場合は、次の表を参考にしてください。
GLSL の定義済みグローバル変数 | HLSL セマンティクス |
---|---|
gl_Position この変数は vec4 型です。 頂点の位置 例: gl_Position = position; |
SV_Position Direct3D 9 の POSITION このセマンティックは float4 型です。 頂点シェーダーの出力 頂点の位置 例: float4 vPosition : SV_Position; |
gl_PointSize この変数は float 型です。 ポイントのサイズ |
PSIZE Direct3D 9 を対象としない場合、意味はありません このセマンティックは float 型です。 頂点シェーダーの出力 ポイントのサイズ |
gl_FragColor この変数は vec4 型です。 フラグメント色 例: gl_FragColor = vec4(colorVarying, 1.0); |
SV_Target Direct3D 9 の COLOR このセマンティックは float4 型です。 ピクセル シェーダーの出力 ピクセルの色 例: float4 Color[4] : SV_Target; |
gl_FragData[n] この変数は vec4 型です。 カラー アタッチメント n のフラグメント色 |
SV_Target[n] このセマンティックは float4 型です。 n レンダー ターゲットに格納されるピクセル シェーダーの出力値 (0 <= n <= 7)。 |
gl_FragCoord この変数は vec4 型です。 フレーム バッファー内のフラグメントの位置 |
SV_Position Direct3D 9 では使用できません このセマンティックは float4 型です。 ピクセル シェーダーの入力 画面領域の座標 例: float4 screenSpace : SV_Position |
gl_FrontFacing この変数は bool 型です。 フラグメントが前向きのプリミティブに属しているかどうかを決定します。 |
SV_IsFrontFace Direct3D 9 の VFACE SV_IsFrontFace は bool 型です。 VFACE は float 型です。 ピクセル シェーダーの入力 プリミティブの向き |
gl_PointCoord この変数は vec2 型です。 ポイント内のフラグメントの位置 (ポイントのラスター化のみ) |
SV_Position Direct3D 9 の VPOS SV_Position は float4 型です。 VPOS は float2 型です。 ピクセル シェーダーの入力 画面領域のピクセルまたはサンプルの位置 例: float4 pos : SV_Position |
gl_FragDepth この変数は float 型です。 深度バッファーのデータ |
SV_Depth Direct3D 9 の DEPTH SV_Depth は float 型です。 ピクセル シェーダーの出力 深度バッファーのデータ |
頂点シェーダーの入力とピクセル シェーダーの入力に位置や色などを指定するには、セマンティクスを使います。 入力レイアウトのセマンティクス値と頂点シェーダーの入力を一致させる必要があります。 例については、「HLSL への GLSL 変数の移植の例」をご覧ください。 HLSL セマンティクスについて詳しくは、「セマンティクス」をご覧ください。
HLSL への GLSL 変数の移植の例
ここでは、OpenGL/GLSL コードの GLSL 変数の使用例と、Direct3D/HLSL コードでの相当する例を紹介します。
GLSL での uniform、attribute、および varying
OpenGL のアプリ コード
// Uniform values can be set in app code and then processed in the shader code.
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
// Incoming position of vertex
attribute vec4 position;
// Incoming color for the vertex
attribute vec3 color;
// The varying variable tells the shader pipeline to pass it
// on to the fragment shader.
varying vec3 colorVarying;
GLSL の頂点シェーダー コード
//The shader entry point is the main method.
void main()
{
colorVarying = color; //Use the varying variable to pass the color to the fragment shader
gl_Position = position; //Copy the position to the gl_Position pre-defined global variable
}
GLSL のフラグメント シェーダー コード
void main()
{
//Pad the colorVarying vec3 with a 1.0 for alpha to create a vec4 color
//and assign that color to the gl_FragColor pre-defined global variable
//This color then becomes the fragment's color.
gl_FragColor = vec4(colorVarying, 1.0);
}
HLSL での定数バッファーとデータ転送
データを HLSL の頂点シェーダーに渡し、それがピクセル シェーダーに渡されるしくみの例を示します。 アプリ コードでは、頂点と定数バッファーを定義します。 次に、頂点シェーダー コードで、定数バッファーを cbuffer として定義し、頂点単位のデータとピクセル シェーダーの入力データを格納します。 ここでは、VertexShaderInput および PixelShaderInput と呼ばれる構造を使います。
Direct3D のアプリ コード
struct ConstantBuffer
{
XMFLOAT4X4 model;
XMFLOAT4X4 view;
XMFLOAT4X4 projection;
};
struct SimpleCubeVertex
{
XMFLOAT3 pos; // position
XMFLOAT3 color; // color
};
// Create an input layout that matches the layout defined in the vertex shader code.
const D3D11_INPUT_ELEMENT_DESC basicVertexLayoutDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
// Create vertex and index buffers that define a geometry.
HLSL の頂点シェーダー コード
cbuffer ModelViewProjectionCB : register( b0 )
{
matrix model;
matrix view;
matrix projection;
};
// The POSITION and COLOR semantics must match the semantics in the input layout Direct3D app code.
struct VertexShaderInput
{
float3 pos : POSITION; // Incoming position of vertex
float3 color : COLOR; // Incoming color for the vertex
};
struct PixelShaderInput
{
float4 pos : SV_Position; // Copy the vertex position.
float4 color : COLOR; // Pass the color to the pixel shader.
};
PixelShaderInput main(VertexShaderInput input)
{
PixelShaderInput vertexShaderOutput;
// shader source code
return vertexShaderOutput;
}
HLSL のピクセル シェーダー コード
// Collect input from the vertex shader.
// The COLOR semantic must match the semantic in the vertex shader code.
struct PixelShaderInput
{
float4 pos : SV_Position;
float4 color : COLOR; // Color for the pixel
};
// Set the pixel color value for the renter target.
float4 main(PixelShaderInput input) : SV_Target
{
return input.color;
}
Direct3D への OpenGL のレンダリング コードの移植例
ここでは、OpenGL ES 2.0 コードのレンダリングの例と、Direct3D 11 コードでの相当する例を紹介します。
OpenGL のレンダリング コード
// Bind shaders to the pipeline.
// Both vertex shader and fragment shader are in a program.
glUseProgram(m_shader->getProgram());
// Input assembly
// Get the position and color attributes of the vertex.
m_positionLocation = glGetAttribLocation(m_shader->getProgram(), "position");
glEnableVertexAttribArray(m_positionLocation);
m_colorLocation = glGetAttribColor(m_shader->getProgram(), "color");
glEnableVertexAttribArray(m_colorLocation);
// Bind the vertex buffer object to the input assembler.
glBindBuffer(GL_ARRAY_BUFFER, m_geometryBuffer);
glVertexAttribPointer(m_positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, m_colorBuffer);
glVertexAttribPointer(m_colorLocation, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// Draw a triangle with 3 vertices.
glDrawArray(GL_TRIANGLES, 0, 3);
Direct3D のレンダリング コード
// Bind the vertex shader and pixel shader to the pipeline.
m_d3dDeviceContext->VSSetShader(vertexShader.Get(),nullptr,0);
m_d3dDeviceContext->PSSetShader(pixelShader.Get(),nullptr,0);
// Declare the inputs that the shaders expect.
m_d3dDeviceContext->IASetInputLayout(inputLayout.Get());
m_d3dDeviceContext->IASetVertexBuffers(0, 1, vertexBuffer.GetAddressOf(), &stride, &offset);
// Set the primitive's topology.
m_d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Draw a triangle with 3 vertices. triangleVertices is an array of 3 vertices.
m_d3dDeviceContext->Draw(ARRAYSIZE(triangleVertices),0);
関連トピック