次に必要になるのが線、矩形、円の描画。矩形と円については線バージョンと塗りつぶしバージョンを用意する。
塗りつぶし用シェーダ
どう描画するのがいいか?
思いつく方法は2つで、オーソドックスに頂点バッファとインデックスバッファを用意して、別途構造化バッファで形状や色を指定する方法。
もう1つは、構造化バッファのみで描画する方法。
文字描画は後者の方法で描画していて、前から2D描画の仕組みもこれで行こうと考えていた。
いざこの方法で描画しようとした場合、形別にシェーダ関数を用意してシェーダ内で振り分けるか、呼び出し側で振り分けてシェーダ自体を切り替える必要があると至った。
どちらもシェーダにとって重くなりそうな処理なので前者の方式で描画することにした。
形状を頂点バッファ、インデックスバッファで表現することにより、シェーダを同一にできる。通常の3Dモデル描画と同じだけど、こうすることによりこの後作る円や、もっと複雑な形状もモデルの準備で済む。
複数インスタンスを同時に描画する部分は構造化バッファに位置、スケール、色情報を含めて対応することにした。
通常3Dモデルの場合はWorldMatrixを複数用意して描画するけど、サイズが大きいのとそこまで複雑な指定をしないので、制限を掛けることでサイズを減らしてパフォーマンスを向上させる。
シェーダ側でWorldMatrixを作って、m[0][0]に幅の倍率、m[1][1]に高さの倍率、m[0][3]にX座標(移動量)、m[1][3]にY座標(移動量)を指定してからmul関数で変換する。
あと、深度バッファを有効にして、z座標を調整することで自動的にZオーダが処理されるようにした。手前ほど先に描画するようにして奥をスキップできるようにソートして構造化バッファに書き込むようにする。
矩形(塗りつぶしバージョン)
矩形のモデルを下記の4点で用意
-0.5,0.5(左上)
0.5,0.5(右上)
-0.5,-0.5(左下)
0.5,-0.5(右下)
円(塗りつぶしバージョン)
3Dモデルの場合はグローシェーディングでモデルがローポリでも球に見えるけど、2Dの場合輪郭だけなのでごまかせない。
分割数16、32、64の輪郭+中心の頂点バッファのデータを用意して、描画サイズにより違和感のないクオリティを選択して描画できるようにした。
線用シェーダ
線の描画自体あまりやったことがなかったけど、唯一やってたのが視錐台の描画でD3D12_PRIMITIVE_TOPOLOGY_TYPE_LINEを使っていた。
線の描画ではD3D_PRIMITIVE_TOPOLOGY_LINELISTとD3D_PRIMITIVE_TOPOLOGY_LINESTRIPの両方を対応できるシェーダを用意したいと考えた。
通常の線描画であれば頂点バッファを用意する必要もないので、構造化バッファのみで描画を行う方式を採用した。
D3D_PRIMITIVE_TOPOLOGY_LINELISTで描画する場合は、構造化バッファに始点、終点のセットで書き込みを行う。
D3D_PRIMITIVE_TOPOLOGY_LINESTRIPで描画する場合は、単純に構造化バッファに点情報を書き込む。ただし、他のデータをまた描きたい場合その前に描いた線と繋がってしまう。そこで、線と線の間に、アルファ0、Zオーダ0の2点(最後の線の終点と次の線の先頭と同じ座標)を追加することにした。こうすることで、D3D_PRIMITIVE_TOPOLOGY_LINESTRIPのデータもまとめて1コマンドで描画できるようになる。
線
線の場合、D3D_PRIMITIVE_TOPOLOGY_LINELISTで2点追加することで描画できる。
矩形
矩形の場合は、線のD3D_PRIMITIVE_TOPOLOGY_LINESTRIPに対して5点(左上、右上、右下、左下、左上)を指定する。
円
円の場合は、線のD3D_PRIMITIVE_TOPOLOGY_LINESTRIPに対してN点を指定する。
Nは3点以上で、cos、sinで座標を計算する。8点以上で円ぽくなる。
スプライト用シェーダ
矩形のテクスチャ貼り付けバージョンのシェーダを用意する。
データソースにリソースに登録されたテクスチャの他に、文字列描画で出力したテクスチャ、さらに今作ってる2D描画で出力したテクスチャも指定できるようにした。
スプライト描画
張り付ける位置の矩形、テクスチャを参照する矩形を指定する。
半透明の描画
不透明の描画の場合、Zオーダが手前を先に描画することで高速化を図る。
逆に透明の描画の場合は、Zオーダが奥のものから描画することで結果を正しく表現する。
またシェーダも切り替えて深度バッファ参照のみに変更して書き込みを止める。
同じシェーダ同士の描画順は制御しているが、塗りつぶし、線、スプライトの描画順は固定。
スプライト(不透明)、塗りつぶし(不透明)、線(不透明)、スプライト(透明)、塗りつぶし(透明)、線(透明)の順で描画する。
0 件のコメント:
コメントを投稿