HLSLシェーダーは実際にレンダー出力にどのように影響するのですか?


11

私はHLSLの構文を理解しています。たとえば、これを自分のHLSLであるとしましょう。

struct VOut
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
    VOut output;

    output.position = position;
    output.position.xy *= 0.7f;    // "shrink" the vertex on the x and y axes
    output.color = color;

    return output;
}


float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
    return color;
}

そして私はそれを次のようにコンパイルします:

D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);

どのように...変更することがわかっています... HLSLと画面上の実際のピクセル/頂点との間のパイプラインが正確に何であるかについて混乱しています。

これは実際にそれらを「適用」するものですか?

dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);

// set the shader objects
devcon->VSSetShader(pVS, 0, 0);
devcon->PSSetShader(pPS, 0, 0);

私はこのようなものの文字通りの初心者のように覚えておいてください。誰かがそれが何をしているのかを説明できますか?頂点HLSL関数がすべての頂点を通過し、関数内にあるものに変更すると想定しています。出力は変更されたものです...同様に、ピクセルシェーダーの場合も同様です。

別の混乱、私はピクセルが何であるかを知っています、そして私は頂点が何であるかを理解しています...しかし、ピクセルシェーダーは正確に何をしますか?


大丈夫です、誰もしません
ボボボボ2011年

回答:


10

どのように変更するのか......変更を知っている.... HLSLと画面上の実際のピクセル/頂点間のパイプラインで正確に混乱しています。

これはおおよそ次のように機能します。描画呼び出し(D3DでのDrawPrimitives、DrawIndexedPrimitives、10以上での描画など)を発行すると、パイプラインにバインドしたジオメトリデータ(頂点バッファー)が処理されます。すべての頂点について、頂点シェーダーが実行され、クリップ空間に出力頂点が生成されます。

次に、GPUはそのクリッピングスペースの頂点に対して、クリッピング/カリング、頂点のスクリーンスペースへの移動などのいくつかの固定機能を実行し、そこで三角形のラスタライズを開始します。各三角形のラスタライゼーション中に、GPUはその三角形の表面全体の頂点属性を補間し、補間された各属性をピクセルシェーダーに供給して、そのピクセルのセミファイナルカラーを生成します(ブレンドはピクセルシェーダーの実行後に適用されるため、「セミ最後の")。

これが実際にそれらを「適用」するものです。

最初に投稿したコードはシェーダーをコンパイルし、次にそれらをパイプラインにバインドし、変更されるまで後続の描画呼び出しのためにアクティブのままにします。実際には実行されません。

誰かがそれが何をしているのかを説明できますか?Vertex HLSL関数がすべての頂点を通過し(入力Position:POSITIONおよびcolor:COLORとして)、それらを関数内にあるものに変更し、出力が変更されたものと仮定します。 ...(ピクセルシェーダーも同様です)。

別の混乱、私はピクセルが何であるかを知っています、そして私は頂点が何であるかを理解しています...しかし、正確にピクセルシェーダーは何をしますか......

頂点シェーダーは、頂点をモデル空間からクリップ空間に変換します。

ピクセルシェーダーは、補間された頂点属性に基づいて、ピクセルの最後から2番目の色/深度を計算します。


9

専門用語をあまり使わずに物事がどのように機能するかを説明しようと思います。

インタラクティブな速度ではなく単純さが問題である場合、コンピュータの3Dサーフェスは、空間内のポイントの巨大なクラウドであり、十分な密度があるため、各ポイントを隙間なく個別にレンダリングできます。

モデルをメモリに1回だけ保存したいが、さまざまなサイズと角度でモデルを表示する必要があるため、3Dモデルをレンダリングするときは、メモリから読み取るときにすべてのポイントを「変換」する必要があります。たとえば、モデルを50%の大きさでレンダリングするには、ポイントの位置を半分にスケ​​ーリングする必要があります。

out.position = in.position * 0.5;
out.color = in.color;

これは、考えられる限りで最も単純な「頂点シェーダー」です。inはメモリから頂点の位置に移動し、outは新しい頂点の位置を半分の大きさにします。half-as-big頂点はメモリに保存されません。レンダリングにすぐに使用され、その後破棄されます。

けれども重要な概念が欠如している総単純化、これは精神で映画がグラフィックスを行う方法の特徴を説明しています。

インタラクティブなグラフィックス(ゲーム)は、グラフィックスを映画よりも数桁速くレンダリングする必要があるため、これほど単純にすることはできません。

ゲームでは、画面上のピクセルごとに1つのポイントをレンダリングする余裕はありません。さらに、ギャップをカバーするための追加要素も用意できません。したがって、妥協案として、隣接する3つのポイント間のギャップは三角形としてレンダリングされます。これは、さまざまな技術的な理由により、画面上で少なくとも10ピクセルの大きさになることを好みます。

3Dの三角形は2Dスクリーンに投影でき、1Dのラインのスタックに分割できます。1Dのラインはそれぞれ0Dピクセルのスタックに分割できます。したがって、3Dの三角形をレンダリングする問題を、多数の0Dピクセルを分離してレンダリングするという単純な問題に分割統治することができます。コンピューターはより短い時間でより単純な問題を解決できます。

ピクセルシェーダーは、三角形を分解することで生成される、各ピクセルで実行する小さなプログラムです。

out.color = in.color;

これは、想像できる最も単純な「ピクセルシェーダー」です。inは3つの三角形の頂点の色のブレンドを行い、outは同じ色を使用します。入力は「頂点シェーダー」の出力からのもので、出力はメモリ内の画面に書き込まれます。

つまり、「頂点シェーダー」はGPUチップ内で実行されるプログラムです。その入力はGPUメモリの「頂点バッファー」であり、その出力は「ピクセルシェーダー」に直接供給されます。「ピクセルシェーダー」もGPUチップ内で実行されるプログラムです。その入力は頂点シェーダーからの3つの頂点のブレンドであり、その出力は画面上のピクセルです。



-2

今のところ、ピクセルシェーダーについて心配する必要はありません。完全な初心者であれば、頂点シェーダーとフラグメントシェーダーのみを備えたGLSL / HLSLのHello Worldである必要があります。慣れてきたら、さまざまな動きなどを理解し始めたら、視野を広げます。

APIがどのように機能するかについての要点を理解するために、教科書を強くお勧めします。OpenGLの本は、固定パイプラインから動的プログラム可能パイプラインに何年にもわたって状況がどのように変化したかを示す優れた働きもします。

チャンピオンになろう!


1
フラグメントシェーダーは、ピクセルシェーダーと同じ機能を果たします。

1
OPがすべてのゲームプログラミングの初心者であるかどうかの質問からは判断できないと思います。シェーダーコードを書く初心者であると彼が述べただけです。シェーダーを書くことを学ぶことは、ゲーム開発者の納屋にある非常に重要なツールです。ゲーム開発の学習の非常に初期の段階でない限り、私はそれらを単に見つめるだけではありません。
Olhovsky、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.