2

私はGLSLで「距離フィールドのレイマーチング」(適切な用語:球体追跡)をしています。その上にコーン マーチングを実装するには (また、コーン マーチングが追加されているかどうかに関係なく、レイ マーチングのステップ数を最小限に抑えるため)、任意の距離でのレイ コーンの半径を推定する必要があります。

レイマーチング距離フィールドを思い出してください。オブジェクトまでの距離がしきい値よりも小さい場合、「ヒット」が記録されます。多くの場合、nearLimit または epsilon という名前のコードで記録されます。このしきい値は、移動距離に応じて指数関数的に増加する場合、光線円錐半径と同等であると見なすことができます。この方法では、直線の細い光線を空間に発射するのではなく、透視投影に従って円錐を拡大します。これにより、「正しい」遠くのオブジェクトをキャッチすることがより正確にカバーされます (この時点では、距離 t にある表示コーン内のすべての交差オブジェクトのマテリアルのブレンドと法線のフィルタリングの問題は無視しましょう...)。

ステップ 0 で、この半径は次のようなもので近似できます。

float fInitialRadius = 1 / min(screenwidth, screenheight);

これは、開始半径を距離に適用することにより、各ステップで指数関数的に増加できます。

fNearLimit = fTotalDist * fInitialRadius;  // after each raymarching step

これは正常に機能しますが、まだアーティファクトがあります。fInitialRadius*fInitialRadius を使用すると (640px フレームバッファーと単位幅のビュープレーンの初期半径が 1/640 であるため、結果として小さい数値になります)、アーティファクトが少なくなり、より正確な結果が得られます。しかし、どちらのアプローチも不正確です。前者は積極的すぎます (半径を大きくするのが早すぎます)。後者は怠惰すぎます (半径を大きくするのが遅すぎます)。

fNearLimit / 特定の距離での円錐半径を増加させる最も正確な係数は、現在の視野を考慮に入れる必要があり、視野が 45° か 60° か 90° か...

TL;DR :ステップ 0 での初期ピクセル半径と視野角が与えられた場合に、与えられた距離での円錐半径の適切な計算または最も許容できる近似値を知りたいですか?

4

1 に答える 1

3

円錐の半径は、その先端からの距離に直線的に対応します。(そうでなければ、それは円錐ではありません!)

したがって、円錐がinitialRadius画面平面と交差するときにある場合は、後で:

radius(distance) = distance * initialRadius / focalDistance

ステップごとに距離が異なるため、ステップごとにその値を再計算する必要があります。

distanceこれがカメラからの光線の距離であり、はカメラからfocalDistanceのスクリーン平面の距離です。

(画面の中央にないピクセルの場合、代わりにfocalDistance、カメラから画面平面上のピクセルの距離を使用する方が正確な場合があります。)

(または、距離をまったく使用しないでください。代わりに深度を使用してください。つまり、画面平面に垂直なベクトルのコンポーネントのみを使用します。これは、シーンを回転させた場合はz軸またはy軸になります。カメラフレーム。)

于 2012-07-05T17:36:39.423 に答える