3

これは少し複雑な問題なので、できるだけ細かく分割してみます。

私は、学習/楽しみのために3D Pythonライブラリを作成しています(他の人が使用することを意図したライブラリとは対照的に)。私が開発したシステムでは、3 次元の点は通常、次のように画像に平坦化されます。

  • Z インデックスを大きくするwidthと、ポイントが中央の消失点の途中まで移動します。
  • ではZ = 0、X と Y の値は X、Y のピクセルに直接対応します。

(このメソッドには名前があるかもしれませんが、あるとしても私はよく知りません。)

Python の場合:

# vx and vy are the vanishing point's coordinates
def flatten_point(width, vx, vy, x, y, z):
    distance = (x - vx, y - vy)
    flat_distance = [d / (1 + float(z) / width) for d in distance]
    return (vx + flat_distance[0], vx + flat_distance[1])

この時点で、三角形の頂点を平坦化し、重心座標を使用してこれらの 3 点の間にあるピクセルを見つけて塗りつぶすことで、ある程度効率的に三角形を作成できます。これらのピクセルが対応する三角形上の実際の点について何も知る必要がない場合、これは十分に機能しますが、三角形を陰影付けして、より深い点がより暗く描画されるようにする場合は、平坦化されていない点を知る必要があります。ピクセルが対応する三角形。

math.stackexchange の jorikiは、重心座標を重みとして使用して元の点を見つけることを推奨しました。これはしばらくの間機能しているように見えました-そして、線形深度システムを使用していればおそらく機能するでしょう-しかし、三角形のポイントの深さが十分に異なると崩壊します. 三角形は、実際よりも速く最大深度に近づいているように見えます。まるで後方に湾曲しているかのようです。

要するに、ポイントの平坦化関数を逆にして、平坦化された三角形上の任意の 2D ピクセルの実際の 3D ポイントを取得するにはどうすればよいでしょうか? または、各ピクセルの深さを失うことなく三角形を平坦化するためのより良い/より効率的な方法があれば、それも機能します。

4

1 に答える 1

2

問題は深度値が線形ではないことにあるということは正しいです。幸いなことに、解決策は単純ですが、ピクセルごとに計算すると少しコストがかかります。

3 つの Z コンポーネントを直接補間するのではなく、重心座標を使用して、逆補間し、結果を逆補間する必要があります。これを遠近補正といいます。

Z のみの例:

def GetInterpolatedZ(triangle, u, v):
    z0 = 1.0 / triangle[0].z
    z1 = 1.0 / triangle[1].z
    z2 = 1.0 / triangle[2].z
    z = z0 + u * (z1-z0) + v * (z2-z0)
    return 1.0/z

triangle3 つのベクトルのリストと、uおよびそれぞれvの重心座標を使用triangle[1]triangle[2]ます。Z がオフセットされている場合は、分割の前後で Z を再マッピングする必要があります。

実際の X 座標と Y 座標を補間したい場合は、同様のことを行います。x/z と y/z を補間し、z を掛けて結果を再線形化する必要があります。

def GetInterpolatedZ(tri, u, v):
    t0 = Vec3(tri[0].x/tri[0].z, tri[0].y/tri[0].z, 1.0/tri[0].z)
    t1 = Vec3(tri[1].x/tri[1].z, tri[1].y/tri[1].z, 1.0/tri[1].z)
    t2 = Vec3(tri[2].x/tri[2].z, tri[2].y/tri[2].z, 1.0/tri[2].z)

    inter = t0 + u * (t1-t0) + v * (t2-t0)
    inter.z = 1.0 / inter.z
    inter.x *= inter.z
    inter.y *= inter.z
    return inter

triは 3 つのベクトルのリストで、はu, vの重心座標ですtri[1], tri[2]Vec3通常の 3 成分ユークリッド ベクトル タイプです。

于 2012-07-24T17:20:55.150 に答える