質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

Q&A

解決済

2回答

1792閲覧

【DirectX12】ピクセルシェーダーに位置を直接渡すと正常に値を読み込めない?

shukrin

総合スコア14

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

0グッド

0クリップ

投稿2022/06/18 06:42

前提

「DirectX12の魔導書」という参考書を用いてDirectX12の勉強をしているのですが、理解できない挙動があったため質問させていただきました。ご教授いただければ幸いです。

発生している問題・エラーメッセージ

第4章「ポリゴンの表示」を進めている最中に問題が発生しております。この章の最後で、スクリーン上の位置によって頂点色が変わる四角形ポリゴンを表示するシェーダーの実装を行います。私が実装したものは以下の通りです。

頂点シェーダー

HLSL

1float4 BasicVS(float4 pos: POSITION) : SV_POSITION{ 2 return pos; 3}

ピクセルシェーダー

HLSL

1float4 BasicPS(float4 pos : SV_POSITION) : SV_TARGET{ 2 return float4((float2(0,1) + pos.xy) * 0.5f,1,1); 3}

シェーダー以外のファイルの内容はここにあるものと同じです。これを実行すると以下のように表示されます。
イメージ説明

一方でシェーダーファイルの中身を上記リンクと同じように書き直すと異なる結果が得られます。こちらの結果が想定していた挙動です。
頂点シェーダー

HLSL

1struct Output { 2 float4 pos:POSITION; 3 float4 svpos:SV_POSITION; 4}; 5 6Output BasicVS(float4 pos : POSITION) { 7 Output output; 8 output.pos = pos; 9 output.svpos = pos; 10 return output; 11}

ピクセルシェーダー

HLSL

1struct Input { 2 float4 pos:POSITION; 3 float4 svpos:SV_POSITION; 4}; 5 6float4 BasicPS(Input input ) : SV_TARGET{ 7 return float4((float2(0,1)+ input.pos.xy)*0.5f,1,1); 8}

描画結果
イメージ説明

違いとしては、座標情報を直接渡すのではなく構造体に入れて渡すようにしただけだと思うのですが、なぜこのような違いが出るのでしょうか?  
グラフィックスに詳しい方がいらっしゃったら何かお教えいただけますと幸いです。

補足情報(FW/ツールのバージョンなど)

シェーダーモデル:Shader Model 5.0
Visual Studio 2019

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

X_III

2022/06/18 08:46

頂点シェーダーの戻り値が違いますね。 質問者さんのコードだと、SV_POSITIONの情報を得られないのでは?
shukrin

2022/06/18 10:01 編集

ご回答ありがとうございます。 私が書いた頂点シェーダーにも戻り値のセマンティクスとしてSV_POSITIONを指定しているつもりですがこれでは足りないのでしょうか?
guest

回答2

0

その本の著者です。
SV_POSITIONとPOSITIONは違いがあって、SV_POSITIONのSVはSystemValueの略で、システムに渡す値です。
この値は何に利用されるのかと言うとラスタライザが利用するための値です。
それに対してPOSITIONは、座標を表しますが、単なる値に過ぎないため単純に「線形補間」されます。
必ずしもSV_が補間されないわけではないのですが、前述の理由からこちらの思った通りの線形補間にならないため、わざわざPOSITIONに同じ値を入れています。
分かりづらいですがそういう仕組みなので、よろしくお願いします。

投稿2022/06/18 13:27

CTsuchinoko

総合スコア28

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

追記しておきます。
前述のとおり、SV_はシステムが使う値なので、想定通りの値になりませんが、具体的には最終的にレンダーターゲットの解像度に左右されるようです。つまり-1~1ではなく、内部的に0~widthの値になってたりします(なってないかもしれない)。
仮に0~widthの値になってるとすると、隣のピクセルがいきなり+1と言ったことになるため真っ白になるわけです(この辺の事をはっきりと書いてる公式ドキュメントを見つけられなかったので推測ですが…)

投稿2022/06/18 13:52

CTsuchinoko

総合スコア28

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shukrin

2022/06/19 07:11 編集

ご回答ありがとうございます。著者の方から直接ご回答いただけるとは感激です。 PSを以下のように書き直すと想定した結果が得られたので、C_Tsuchinokoさんのおっしゃる通りSV_POSITIONの値は最終的に0~widthの値になっていそうです。しかしならないこともあるということなので、PSで座標情報を使いたい場合はやはり別途POSITIONのセマンティクスをつけた値を用意した方がよさそうですね。 ```hlsl float2 ConvertSVpos(float2 pos) { return float2(pos.x / 1280.f * 2.f - 1.f, 1.f - pos.y / 720.f * 2.f); } float4 BasicPS(Input input ) : SV_TARGET{ return float4((float2(0,1)+ ConvertSVpos(input.pos.xy))*0.5f,1,1); } ``` まとめると、 ・SV_POSITIONのセマンティクスをつけると、ラスタライザーステージで値を単に補間するだけではなくラスタライザーが使用しやすいような形に加工されてしまう ・VSでSV_POSITIONの値を出力する必要があるが、PSでその値を使うことはない というような理解でよろしいのでしょうか?
CTsuchinoko

2022/06/19 17:50

ひとまずそんな感じの理解で大丈夫だと思います。 この辺がきちんと書かれてるドキュメントがないため、実際説明に困っている感じです。
shukrin

2022/06/20 15:12

ありがとうございます! おかげ様で疑問が氷解いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問