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 の中の** _ 色**、gl の添** _ データ [ 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 target n ] が body メソッドに必要です。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 POSITION システム値のセマンティックを出力するために必要です _ 。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 _ POSITION システム値のセマンティックを使用して画面上のピクセル位置を取得します。 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 _ x ピクセルシェーダーは、SV POSITION 値から読み取ることができません _ 。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).

InstructionsInstructions

手順 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. シェーダーは、位置ベクターをパースペクティブ座標に変換し、 _ ラスタライズのために組み込みの 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 セマンティクス (POSITION と COLOR) 使って明確にマークします。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 つのパラメーターとして指定することもできますが、そうすると扱いにくくなる場合があります)。また、補完された位置と色を格納するこのステージの出力の型を指定し、それを頂点シェーダーの body 関数の戻り値として宣言します。(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 の色を指定し _ ます。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. 色は4座標 (RGBA) の浮動小数点値であるため、float4 を戻り値の型として指定し、既定のレンダーターゲットを SV ターゲットシステム値のセマンティックとして指定し _ ます。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)」、「Direct3D 11 のバッファーについて」、「定数バッファーを作成する方法」をご覧ください。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 が元の同種座標 (x/w) で除算され、w が元の w 値 (1/w) で割った値を調整します。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).

簡単な OpenGL ES 2.0 レンダラーを Direct3D 11 に移植する方法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