3

私は640x480のレンダーターゲット(メインのバックバッファー)を持っています。

フルスクリーンクワッドを頂点シェーダーに渡す場合、フルスクリーンクワッドはXとYの両方で[-1,1]の座標を持ちます。つまり、計算なしで座標をピクセルシェーダーに渡すだけです。

struct VSInput
{
    float4 Position : SV_POSITION0;
};

struct VSOutput
{
    float4 Position : SV_POSITION0;
};

VSOutput VS(VSInput input)
{
    VSOutput output = (VSOutput)0;
    output.Position = input.Position;
    return output;
}

ただし、ピクセルシェーダーでは、各フラグメントのx座標とy座標は画面空間にあります(0<x<640および0<y<480)。何故ですか?座標はピクセルシェーダーに向かう途中で補間され、-1,1の間に設定されるといつも思っていました。この場合は、頂点シェーダーにハードコードされた-1と1の間の座標を渡すため、さらにそうなります。

しかし真実は、このピクセルシェーダーは機能します:

float x = input.Position.x;

if(x < 200)
    output.Diffuse = float4(1.0, 0.0, 0.0, 1.0);
else if( x > 400)
    output.Diffuse = float4(0.0, 0.0, 1.0, 1.0);
else
    output.Diffuse = float4(0.0, 1.0, 0.0, 1.0);

return output;

レンダリングウィンドウに3つのカラーストライプが出力されますが、値を画面スペース(上記のコードの200と400)から-1,1スペースに変更し、if(x <0.5)のようなものを使用すると機能しません。

私はすでに試しました

float x = input.Position.x / input.Position.w;

そのようにどこかで読んだので、-1,1の間の値を取得できましたが、どちらも機能しません。

前もって感謝します。

4

1 に答える 1

4

セマンティクスのMSDNから-SV_POSITIONに関するページ:

ピクセルシェーダーで使用する場合、SV_Positionはピクセルの位置を記述します。

したがって、期待される動作が見られます。

最善の解決策は、追加のパラメータとして画面空間の座標を渡すことです。この「フルスクリーントライアングル」頂点シェーダーを使用するのが好きです。

struct VSQuadOut {
    float4 position : SV_Position;
    float2 uv: TexCoord;
};

// outputs a full screen triangle with screen-space coordinates
// input: three empty vertices
VSQuadOut VSQuad( uint vertexID : SV_VertexID ){
    VSQuadOut result;
    result.uv = float2((vertexID << 1) & 2, vertexID & 2);
    result.position = float4(result.uv * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
    return result;
}

(元のソース:頂点バッファなしのフルスクリーンクワッド?

于 2012-11-27T23:51:56.870 に答える