小ネタ : スクリーンスペースの矩形描画
小ネタです。 以下,DirectX系を考えています。
1つの三角形で矩形のUVを描画する
普通四角形のテクスチャを画面全体に表示しようとすると,こんな感じでスクリーンスペースで2つの三角形を描くかと思います。
これと同じことを,大きな三角形一つで実現できます。
はみ出たところはクリッピングされるので問題ありません。 画面全体にレンダリングしない場合でも,適当にスケーリングして.ID3D11DeviceContext::RSSetScissorRects()などシザー矩形でクリップすれば大丈夫です。
頂点バッファを利用しないで三角形を描画する
結論から言うと,DirectX11ならば,頂点シェーダーの入力にSV_VertexIDを使うと良いです。 SV_VertexIDは何個目の頂点を処理しているかが入ってくるシステム値です。
実際に先程の大きな三角形で画面全体にUVを張る頂点シェーダーは以下のようになります。
struct OUTPUT { float4 Position : SV_POSITION; float2 UV : TEXCOORD0; }; OUTPUT VS_TEX2D(uint index : SV_VertexID) { // 0----2 // | / // | / // 1 const float2 vId = float2(index / 2u, index % 2u); // 三角形を定義する 0 ~ 1 空間 OUTPUT Out = (OUTPUT )0; // Positionの計算 // {(-1,1), (-1,-3), (3, 1)} screenPosition = float2(4.0f, -4.0f) * vId.xy+ float2(-1.0f, 1.0f); Out.Position = float4(screenPosition.xy, 0.1f, 1.0f); // UV座標の計算 // {(0,0), (0,2), (2,0)} Out.aUV[index] = float2(2.0f, 2.0f) * vId.xy; return Out; }
この頂点シェーダーを利用すると,頂点バッファもインデックスバッファも利用せずに,シェーダーだけセットして,
m_pDeviceContext->Draw(3, 0);
みたいなドローコールを直接呼び出すだけで画面全体にUVを張れます。