ミップマップを使用したテクスチャ座標の不連続性により継ぎ目が作成される


9

私はopenGLの学習を始めたばかりで、ミップマップで球体をテクスチャリングするときにこのアーティファクトを取得しています。基本的に、フラグメントがテクスチャのエッジをサンプリングするときに、不連続性(たとえば1から0まで)を検出し、最小のミップマップを選択して、この醜いシームを作成します。

醜い縫い目http://cdn.imghack.se/images/6bbe0ad0173cac003cd5dddc94bd43c7.png

だから私はtextureGradを使用してグラデーションを手動でオーバーライドしようとしました:

//fragVert is the original vertex from the vertex shader
vec2 ll = vec2((atan(fragVert.y, fragVert.x) / 3.1415926 + 1.0) * 0.5, (asin(fragVert.z) / 3.1415926 + 0.5));
vec2 ll2 = ll;
if (ll.x < 0.01 || ll.x > 0.99)
    ll2.x = .5;
vec4 surfaceColor = textureGrad(material.tex, ll, dFdx(ll2), dFdy(ll2));

今、私は1つではなく2つの縫い目を取得します。どうすればそれらを取り除くことができますか?そして、なぜ上記のコードは2つの継ぎ目を生成​​するのですか?

2 Eams http://cdn.imghack.se/images/44a38ef13cc2cdd801967c9223fdd2d3.png

2つの画像からは区別できませんが、2つのシームは元のシームの両側にあります。


2
あなたの球はメッシュですか、それともシェーダーなどで球を分析的にレイトレーシングしていますか?それはメッシュだ場合は片側のVertsには、U = 0、反対側はuは1 =持って持つことができるように、人々は通常、縫い目に沿って頂点を複製することによってこの問題を解決
ネイサン・リード

コードが2つの継ぎ目を生成​​する理由については、uが0.01から0.5にジャンプする場所と、uが0.99から0.5にジャンプする場所の2つの不連続を作成しているためと考えられます。これは、uが0から1にジャンプするときと同じ問題です-ジャンプの大きさではなく、大きなジャンプです。
ネイサンリード

球のメッシュがあります。正十二面体なので、頂点は継ぎ目に整列しません。2つのシームの面白い点は、元のシームがなくなっていることです。また、.01または.99にクランプしても、同じ2つのシームが得られます。
omikun 2013年

2つのシームのケースのスクリーンショットを投稿できますか?また、UVをどのように生成していますか(コードの関連部分を投稿できますか)?頂点から補間するだけでなく、シェーダーで手続き的にそれらを生成していると思います。そうしないと、12面体メッシュがまったく機能しません。
Nathan Reed

2つの縫い目の画像で質問を更新しました。それらは元の縫い目のどちら側にもありますが、元の縫い目はありません。確かに、UVは頂点から補間されていると思います。コードは今問題になっています。
omikun 2013年

回答:


4

投稿したシェーダーコードに基づいて、頂点からUVを補間するのではなく、3D位置(fragVert)を補間して、球面座標に変換してUVを計算しているように見えます。

ミップマップの選択は隣接するピクセルで使用されるUVから数値的に推定される導関数に基づいているため、不連続性があるときに最小のミップマップが選択されるという点で、分析は正しいです。1つのピクセルにu = 0があり、別のピクセルにu = 1がある場合、非常に大きな導関数が得られます。試みられた修正には、u = 0.01とu = 0.99付近で大きな導関数が発生するという同じ問題があります。そのため、元のシームの両側に2つのシームが表示されます。

問題を修正するための比較的単純なアプローチは、どのミップレベルを使用するかを決定し、textureLodそれを直接サンプリングするために呼び出すことです。惑星が常にカメラのかなり近くにある場合は、ミップレベルを0にハードコードすることができます(または、さらに言えば、テクスチャにミップレベルをまったく含めないでください)。それ以外の場合は、カメラからのポイントの距離のlog2に基づいて、いくつかの適切な係数でスケーリングされます。これは異方性フィルタリングを効果的に無効にすることに注意してください。

より「正しい」アプローチは、より高品質の導関数を計算することです。代わりに使用したのdFdxdFdy起因する不連続性を持ったUV、上atan2、あなたが適用できるdFdxdFdyfragVertUV誘導体を得るために式を見つけるために、その後、いくつかの微積分(チェーン・ルール)を使用する(球の周りのすべての方法の連続になります)位置デリバティブから。これはより複雑で遅くなりますが、異方性フィルタリングが機能するという利点があります。

最後に、OpenGLは初めてなので、球座標からUVを計算することは球をテクスチャリングするための完全に有効な方法ですが、ほとんどの人が選択する「通常の」方法ではないことに注意してください。頂点ごとにUVが指定され、頂点シェーダーからピクセルシェーダーに単純に渡される(各三角形に線形補間される)球体メッシュを作成するのがより一般的です。頂点はこのようにシームに沿って配置され、各頂点の2つのコピーがまったく同じ位置にありますが、u = 0の半分は片側の三角形に接続され、もう半分はu = 1に接続されます反対側の三角形。これにより、目に見える継ぎ目がなくなり、ピクセルシェーダーでのトリックを必要としません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.