2026年5月17日日曜日

線の描画

線の描画はD3D_PRIMITIVE_TOPOLOGY::D3D_PRIMITIVE_TOPOLOGY_LINESTRIPを使って出来るようにしていた。1ドット幅はきれいに引けるけど、太線は指定できない。

幅を指定して線を引けるように機能拡張した。


法線算出


線分の差分ベクトルを長さで割って、接線を算出。
法線=float2( -接線.y, 接線.x )
これを各点にwを加味して足してやると幅のある線が描ける。



連結線


次に連結した線を試してみたらこうなった。


なんだか線が細くなる。
これは2点だけで90度を出しておらず、前後の点を見て角の2等分線になるようにしているから。


2点だけの場合は線に対して90度の法線だけど(上の図)、連結の点は中間の角度になり同じ幅計算で出した点でポリゴンを形成した場合細く見えてしまう(真ん中の図)。
そこで幅に補正を掛けて引き延ばしてやる必要がある(下の図)。


マイター補正


合成した接線(間の縦線)と最初の2点で内積で角度を求めて、その逆数を求めると補正する数値が出るので、それをwに掛けるといい感じの幅になる。


グラフみたいな線をランダムに描画してみたところ、上記のような感じになっていた。
線がかすれてしまっている。
マイター補正で算出する掛目の上限を5にしてた所を50とかに変更したらまともに描画されるようにはなった。
ただ、この角度が鋭角になればなるほどマイタースパイクと呼ばれる状況になり、補正値がとんでもない値になってしまう。それをガードしていたんだけど、上限を大きくするとプロットしている座標を超えて線が描かれてしまうし、足りないと上図のようにラスタライズ時1ドット未満で切り捨てられてかすれてしまう。


線を切り離す


複数の線の塊は1回の描画で行っているが、線データの隙間に切れ目のデータを挟むことで実現している。
線の結合部分の角度が鋭角すぎると判断したら、1つの塊の連結線を切り離してしまうことで問題を解決する。デメリットは線の結合部分がそれぞれの法線の角度同士でうまくつながってない状態になることだけど、線の太さがよほど大きくないとそこまで目立たない。


ベクトルの内積をとって、-0.8以下(約143度以上)の場合、線を自動的に切り離すようにしたところ、線がかすれる状態は改善。-0.8以下がデータとしてシェーダにも流れない為(計算上約3.7倍)、上限もマイターの倍数も上限5倍で問題なくなった。


1ドットの線しか描けなかったため、Emissiveを掛けてもブラーで縮小している最中にデータがなくなってしまっていたけど、幅を指定できるようになったので光って見えるようになった。



0 件のコメント:

コメントを投稿