日別アーカイブ: 2008年11月17日

Direct3D11/DirectX11 (10) テセレータの補間

isoline を使うと線分の分割だけでなく 2次元方向にも数を増やすことが出来ます。
おそらく髪の毛の表現などに使われる機能だと考えられます。
uv の u 方向のみライン描画されるので、u が毛の滑らかさ(丸み)、v が密度(本数)
を表します。

出力トポロジの line は domain(“isoline”) の場合のみ使用できるようです。
前回の記事で tri/quad の出力にも line を含ませていたのは間違いでした。
訂正致します。

テセレータを使うと、かなり簡単に頂点を増やすことができます。
特に isoline は uv 方向に任意に頂点を生成できるため使い勝手が良さそうです。
outputtopology を point にして GeometryShader でオブジェクトを配置すれば、
草むらなどの表現に使えるかもしれません。LOD も容易です。

テセレータは partitioning の指定によってテセレータの各段階を補間できるように
なります。一番シンプルな isoline の 1 line だけで調べてみました。

共通事項として、TessFactor のどれかに 0 が含まれているとプリミティブは表示
されないようです。無関係の固定図形を GeometryShader で描画している場合も
出力されないので、描画が完全に捨てられていると判断できます。

integier の場合、TessFactor が 1.0 の時分割数が 1 です。
isoline で頂点のみ出力すると両端の 2点が表示されます。(点を ‘*’ で表します)

1.0=   *              *

TessFactor= 2.0 の時、線分は 2分割されて 3頂点が表示されます。

2.0=   *      *       *

同じように各 partitioning タイプ毎に TessFactor を変えて調べてみました。

fractional_odd
1.0= *              * 1分割
1.5= * *          * *
2.0= *  *        *  *
2.5= *   *      *   *
3.0= *    *    *    * 3分割

fractional_even
1.0= *       *       *
2.0= *       *       * 2分割
2.5= *      ***      *
3.0= *     * * *     *
3.5= *    *  *  *    *
4.0= *   *   *   *   * 4分割

integer == pow2
1.0= *               * 1分割
1.5= *       *       * 切り上げ
2.0= *       *       * 2分割
2.5= *    *     *    * 切り上げ
3.0= *    *     *    * 3分割
4.5= *   *   *   *   * 切り上げ
4.0= *   *   *   *   * 4分割

fractional_odd は奇数の時が基準です。
1.0 で 1分割、3.0 で空間が 3分割されており、その間は補間するように頂点が
移動しています。

fractional_even も同じように偶数時が基準となっています。
2分割と 4分割の中間の図形が生成されています。

integer では中間状態はなく、常に整数値で分割された値になります。
ここで興味深いのは、integer の TessFactor は切り捨てではなく切り上げになる
ことです。1.0 を少しでも超えると 2分割相当となります。

この挙動は他の fractional_even , fractional_odd と見比べると納得できます。
間を補間する場合は、1.0 を少しでも超えると補間のための頂点が生成されて移動を
始めるからです。

今回のテストでは pow2 の動作は integer と同じ結果で違いを発見できませんでした。

tess quad odd

上の図は、domain(“quad”) で partitioning(“fractional_odd”) の場合の様子を
表示したものです。
それぞれ左上から TessFactor = 1.0、1.5、2.0、3.0 を表しています。

isoline の場合と同じように、quad でも 1.0(1分割) と 3.0(3分割) の間が補間
されていることがわかります。
またその動きも 2次元になっているだけで、基本的には isoline と変わりません。
両端から生成された線分が次の分割状態に近づくよう中心に徐々に移動しています。

テセレータの挙動は想像よりもずっとわかりやすいものでした。テセレータ部だけ
固定機能と言われていたため、もっと決まった動作しかできないかと思ってましたが
HullShader DomainShader のおかげで十分な自由度もあります。
正直かなり使いやすいと思います。

CPU の core 数も増えて、CPU と GPU の違いも少なくなりつつあります。
複雑で特別な仕様の GPU や API をいちいち覚えるくらいなら、必要な機能だけ
CPU で直接書いた方が速いんじゃないかと思ってましたが見直しました。

関連エントリ
Direct3D11/DirectX11 (9) テセレータによるアウトラインフォントの描画など
Direct3D11/DirectX11 (8) テセレータの動作
Direct3D11/DirectX11 (7) テセレータの流れの基本部分
Direct3D11/DirectX11 (6) D3D11 の ComputeShader を使ってみる
Direct3D11/DirectX11 (5) WARP の試し方、Dynamic Shader Linkage
Direct3D11/DirectX11 (4) FeatureLevel と旧 GPU の互換性、テクスチャ形式など
Direct3D11 (DirectX11) シェーダーの書き込み RWBuffer 他
Direct3D11 の遅延描画、スレッド対応機能、シェーダー命令
Direct3D11 Technical Preview D3D11の互換性、WARP Driver