GLSL の移植Port the GLSL

重要な APIImportant APIs

バッファーとシェーダー オブジェクトを作成して構成するコードが完成したら、それらのシェーダー内のコードを OpenGL ES 2.0 の GL シェーダー言語 (GLSL) から Direct3D 11 の上位レベル シェーダー言語 (HLSL) に移植します。Once you've moved over the code that creates and configures your buffers and shader objects, it's time to port the code inside those shaders from OpenGL ES 2.0's GL Shader Language (GLSL) to Direct3D 11's High-level Shader Language (HLSL).

OpenGL ES 2.0 でシェーダーがなどの組み込み関数を使用して実行後にデータを返すgl_位置gl_FragColor、またはgl_FragData[n] (n は、特定のレンダー ターゲットのインデックスです)。In OpenGL ES 2.0, shaders return data after execution using intrinsics such as gl_Position, gl_FragColor, or gl_FragData[n] (where n is the index for a specific render target). Direct3D では、特定の組み込みメソッドはなく、シェーダーはそれぞれの main() 関数の戻り値の型としてデータを返します。In Direct3D, there are no specific intrinsics, and the shaders return data as the return type of their respective main() functions.

頂点の位置や法線など、シェーダー ステージ間で補間されるデータは、varying 宣言を使って処理します。Data that you want interpolated between shader stages, such as the vertex position or normal, is handled through the use of the varying declaration. ただし、Direct3D にはこの宣言がありません。そのため、シェーダー ステージ間で受け渡されるデータは HLSL セマンティクスでマークする必要があります。However, Direct3D doesn't have this declaration; rather, any data that you want passed between shader stages must be marked with an HLSL semantic. 選んだ特定のセマンティクスはデータの目的を示します。The specific semantic chosen indicates the purpose of the data, and is. たとえば、フラグメント シェーダー間で補完される頂点データは次のように宣言します。For example, you'd declare vertex data that you want interpolated between the fragment shader as:

float4 vertPos : POSITION;

またはor

float4 vertColor : COLOR;

POSITION は、頂点の位置データを示すために使うセマンティクスです。Where POSITION is the semantic used to indicate vertex position data. また、POSITION は特殊なケースで、補間後にピクセル シェーダーからアクセスできません。POSITION is also a special case, since after interpolation, it cannot be accessed by the pixel shader. したがって、SV でピクセル シェーダーへの入力を指定する必要があります_位置と、補間された頂点データは、その変数に配置されます。Therefore, you must specify input to the pixel shader with SV_POSITION and the interpolated vertex data will be placed in that variable.

float4 position : SV_POSITION;

セマンティクスは、シェーダーの body (main) メソッドで宣言できます。Semantics can be declared on the body (main) methods of shaders. ピクセル シェーダー、SV の_ターゲット[n]、本文メソッドで必要なレンダー ターゲットを示します。For pixel shaders, SV_TARGET[n], which indicates a render target, is required on the body method. (SV_ターゲット インデックス 0 を表示するために既定値は数値のサフィックスなしの対象です)。(SV_TARGET without a numeric suffix defaults to render target index 0.)

また 頂点シェーダーが SV を出力するために必要なことに注意してください_位置システム値セマンティック。Also note that vertex shaders are required to output the SV_POSITION system value semantic. このセマンティクスは頂点の位置データを座標値に解決します。x は -1 ~ 1 の値に、y は -1 ~ 1 の値になり、z は元の同次座標 w の値で割られ (z/w)、w は 1 を元の w の値で割った値 (1/w) になります。This semantic resolves the vertex position data to coordinate values where x is between -1 and 1, y is between -1 and 1, z is divided by the original homogeneous coordinate w value (z/w), and w is 1 divided by the original w value (1/w). ピクセル シェーダーを使用して、SV_セマンティック x が 0 と、レンダー ターゲットの幅と y の間は、画面のピクセル位置を取得する位置のシステム値が 0 ~ レンダー ターゲットの高さ (0.5 で各オフセット)。Pixel shaders use the SV_POSITION system value semantic to retrieve the pixel location on the screen, where x is between 0 and the render target width and y is between 0 and the render target height (each offset by 0.5). 機能レベル 9_ピクセル シェーダーは、SV から読み取ることができません x_位置の値。Feature level 9_x pixel shaders cannot read from the SV_POSITION value.

定数バッファーは cbuffer を使って宣言し、検索のために特定の開始レジスタに関連付ける必要があります。Constant buffers must be declared with cbuffer and be associated with a specific starting register for lookup.

Direct3D 11。HLSL 定数バッファーの宣言は、Direct3D 11: An HLSL constant buffer declaration

cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
  matrix mvp;
};

ここでは、定数バッファーはレジスタ b0 を使って、パックされたバッファーを保持します。Here, the constant buffer uses register b0 to hold the packed buffer. すべてのレジスタ フォーム b で参照される#します。All registers are referred to in the form b#. HLSL での定数バッファー、レジスタ、データ パッキングの実装について詳しくは、「シェーダー定数 (HLSL)」をご覧ください。For more information on the HLSL implementation of constant buffers, registers, and data packing, read Shader Constants (HLSL).

手順Instructions

手順 1:ポート、頂点シェーダーStep 1: Port the vertex shader

この簡単な OpenGL ES 2.0 の例では、頂点シェーダーに 3 つの入力があります。1 つの定数のモデル ビュー プロジェクション 4x4 マトリックスと 2 つの 4 座標ベクトルです。In our simple OpenGL ES 2.0 example, the vertex shader has three inputs: a constant model-view-projection 4x4 matrix, and two 4-coordinate vectors. これら 2 つのベクトルには、頂点の位置と色が含まれます。These two vectors contain the vertex position and its color. シェーダーがパースペクティブ座標に position ベクトルを変換し、gl に代入_ラスタライズの組み込みの位置。The shader transforms the position vector to perspective coordinates and assigns it to the gl_Position intrinsic for rasterization. また、頂点の色は、ラスタライズ時に補間のために varying 変数にコピーされます。The vertex color is copied to a varying variable for interpolation during rasterization, as well.

OpenGL ES 2.0:キューブ オブジェクト (GLSL) の頂点シェーダーOpenGL ES 2.0: Vertex shader for the cube object (GLSL)

uniform mat4 u_mvpMatrix; 
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 destColor;

void main()
{           
  gl_Position = u_mvpMatrix * a_position;
  destColor = a_color;
}

次に、direct3d で定数のモデル-ビュー-射影行列がレジスタ b0 に搭載された定数バッファーに含まれているし、頂点の位置と色が、適切なそれぞれの HLSL セマンティクスでマークされた具体的には。位置や色。Now, in Direct3D, the constant model-view-projection matrix is contained in a constant buffer packed at register b0, and the vertex position and color are specifically marked with the appropriate respective HLSL semantics: POSITION and COLOR. 入力レイアウトはこれら 2 つの頂点の値の特定の配置を示しているため、それらの値を保持する構造体を作成し、シェーダーの body 関数 (main) でその構造体を入力パラメーターの型として宣言します Since our input layout indicates a specific arrangement of these two vertex values, you create a struct to hold them and declare it as the type for the input parameter on the shader body function (main). (2 つの個別のパラメーターとして指定することも、面倒を取得する可能性があります)。このステージでは、挿入位置と色を含む出力の種類を指定し、頂点シェーダーの本文の関数の戻り値として変数を宣言します。(You could also specify them as two individual parameters, but that could get cumbersome.) You also specify an output type for this stage, which contains the interpolated position and color, and declare it as the return value for the body function of the vertex shader.

Direct3D 11。キューブ オブジェクト (HLSL) の頂点シェーダーDirect3D 11: Vertex shader for the cube object (HLSL)

cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
  matrix mvp;
};

// Per-vertex data used as input to the vertex shader.
struct VertexShaderInput
{
  float3 pos : POSITION;
  float3 color : COLOR;
};

// Per-vertex color data passed through the pixel shader.
struct PixelShaderInput
{
  float3 pos : SV_POSITION;
  float3 color : COLOR;
};

PixelShaderInput main(VertexShaderInput input)
{
  PixelShaderInput output;
  float4 pos = float4(input.pos, 1.0f); // add the w-coordinate

  pos = mul(mvp, projection);
  output.pos = pos;

  output.color = input.color;

  return output;
}

出力のデータ型 PixelShaderInput は、ラスタライズ時に設定され、フラグメント (ピクセル) シェーダーに渡されます。The output data type, PixelShaderInput, is populated during rasterization and provided to the fragment (pixel) shader.

手順 2:ポート フラグメント シェーダーStep 2: Port the fragment shader

GLSL で、例のフラグメント シェーダーは非常に単純: 提供、gl_FragColor 色の補間値を持つ組み込み。Our example fragment shader in GLSL is extremely simple: provide the gl_FragColor intrinsic with the interpolated color value. OpenGL ES 2.0 では、それを既定のレンダー ターゲットに書き込みます。OpenGL ES 2.0 will write it to the default render target.

OpenGL ES 2.0:キューブ オブジェクト (GLSL) のフラグメント シェーダーOpenGL ES 2.0: Fragment shader for the cube object (GLSL)

varying vec4 destColor;

void main()
{
  gl_FragColor = destColor;
} 

Direct3D も同じくらい簡単です。Direct3D is almost as simple. 大きな違いは、ピクセル シェーダーの body 関数で値を返す必要があることだけです。The only significant difference is that the body function of the pixel shader must return a value. Float4 として戻り値の型を示すし、SV として既定のレンダー ターゲットを指定し、色は、4 座標 (RGBA) の浮動小数点値であるため_ターゲット システム値セマンティック。Since the color is a 4-coordinate (RGBA) float value, you indicate float4 as the return type, and then specify the default render target as the SV_TARGET system value semantic.

Direct3D 11。キューブ オブジェクト (HLSL) のピクセル シェーダーDirect3D 11: Pixel shader for the cube object (HLSL)

struct PixelShaderInput
{
  float4 pos : SV_POSITION;
  float3 color : COLOR;
};


float4 main(PixelShaderInput input) : SV_TARGET
{
  return float4(input.color, 1.0f);
}

位置のピクセルの色はレンダー ターゲットに書き込まれます。The color for the pixel at the position is written to the render target. 次に、「画面への描画」でそのレンダー ターゲットのコンテンツを表示する方法を見ていきます。Now, let's see how to display the contents of that render target in Draw to the screen!

前のステップPrevious step

頂点バッファーと頂点データの移植 次の手順Port the vertex buffers and data Next step

画面への描画 解説Draw to the screen Remarks

HLSL セマンティクスと定数バッファーのパッキングについて理解すると、デバッグの苦労がいくらか少なくなるだけでなく、最適化できるようにもなります。Understanding HLSL semantics and the packing of constant buffers can save you a bit of a debugging headache, as well as provide optimization opportunities. 機会を得る場合読んで変数構文 (HLSL)direct3d11 のバッファーの概要、および方法。定数バッファーを作成です。If you get a chance, read through Variable Syntax (HLSL), Introduction to Buffers in Direct3D 11, and How to: Create a Constant Buffer. 機会がない場合は、次のセマンティクスと定数バッファーについての基本的なヒントを心に留めておいてください。If not, though, here's a few starting tips to keep in mind about semantics and constant buffers:

  • 必ずレンダラーの Direct3D 構成コードを見直して、定数バッファーの構造体が HLSL の cbuffer 構造体の宣言と一致し、コンポーネントのスカラー型が両方の宣言で一致していることを確認する。Always double check your renderer's Direct3D configuration code to make sure that the structures for your constant buffers match the cbuffer struct declarations in your HLSL, and that the component scalar types match across both declarations.
  • レンダラーの C++ コードでは、データ パッキングが適切に行われるように、定数バッファーの宣言で DirectXMath 型を使う。In your renderer's C++ code, use DirectXMath types in your constant buffer declarations to ensure proper data packing.
  • 定数バッファーを効率的に使う最良の方法として、更新頻度に応じてシェーダーの変数を定数バッファーにまとめる。The best way to efficiently use constant buffers is to organize shader variables into constant buffers based on their frequency of update. たとえば、フレームごとに 1 回更新される uniform データと、カメラが移動したときにだけ更新される uniform データがある場合は、それらのデータを 2 つの定数バッファーに分けることを考えます。For example, if you have some uniform data that is updated once per frame, and other uniform data that is updated only when the camera moves, consider separating that data into two separate constant buffers.
  • セマンティクスの適用し忘れや誤った適用は、シェーダー コンパイル (FXC) エラーのよくある原因である。Semantics that you have forgotten to apply or which you have applied incorrectly will be your earliest source of shader compilation (FXC) errors. よく見直してください。Double-check them! 以前のページやサンプルの多くでは Direct3D 11 より前のさまざまなバージョンの HLSL セマンティクスを参照しているため、ドキュメントが混乱を招くことがあります。The docs can be a bit confusing, as many older pages and samples refer to different versions of HLSL semantics prior to Direct3D 11.
  • 各シェーダーのターゲットとする Direct3D 機能レベルを確認する。Make sure you know which Direct3D feature level you are targeting for each shader. 機能をセマンティクス レベル 9_ *が 11 の異なる_1。The semantics for feature level 9_* are different from those for 11_1.
  • SV_位置セマンティック解決の座標 x は 0 と、レンダー ターゲットの幅、y の間で値を後の補間の関連付けられている位置データが 0 ~、レンダー ターゲットの高さ、z が元の同種の座標 w で割った値値 (z/w)、および w は、元の w 値 (1 w) で割った値 1 です。The SV_POSITION semantic resolves the associated post-interpolation position data to coordinate values where x is between 0 and the render target width, y is between 0 and the render target height, z is divided by the original homogeneous coordinate w value (z/w), and w is 1 divided by the original w value (1/w).

方法: direct3d11 を単純な OpenGL ES 2.0 レンダラーのポートHow to: port a simple OpenGL ES 2.0 renderer to Direct3D 11

シェーダー オブジェクトの移植Port the shader objects

頂点バッファーと頂点データの移植Port the vertex buffers and data

画面への描画Draw to the screen