これは少し複雑ですが、非常に単純な問題になることを願っています。その方法は次のとおりです。Unity を使用して、実行時に頂点、面、UV、テクスチャ参照などを多数含む bsp ファイルからマップ ゲームオブジェクトを生成しています。作成されたメッシュは本来あるべき姿であり、すべてのテクスチャは問題なく表示されます。ただし、問題が 1 つあります。非常に多くのマテリアルで非常に多くのメッシュが作成されているため、多くのドロー コールが発生し、プログラムが遅くなります。そこで、ドローコールを減らす方法を探したところ、解決策が見つかりました。すべてのメッシュを 1 つの大きなメッシュに結合し、使用されるすべてのテクスチャを組み合わせてテクスチャ アトラスを作成します。メッシュの組み合わせはうまく機能し、テクスチャの組み合わせもうまくいきます。次に、UV マッピングの問題に直面しました。そこで、NVidia のホワイト ペーパーから、tex2d 関数を使用してテクスチャからテクセルを補間するカスタム シェーダーを作成するソリューションを見つけました。UV 位置とその導関数を使用します。これでうまくいくと思いますが、私のメッシュには本当に奇妙な三角形があり、このソリューションが台無しになっていると思います。下の画像では、メッシュが結合されている場合と分離されている場合の違いを見ることができます。
変更された UV とカスタム シェーダーを使用した結合されたメッシュ
これは、モデルの色を設定するためにシェーダーで使用しているコードです。
o.Albedo = tex2D (_MainTex, IN.uv2_BlendTex, ddx(IN.uv_MainTex), ddy(IN.uv_MainTex)).rgb;
ご覧のとおり、元の UV の非タイル バージョンである 2 つ目の UV を追加しました。frac() 関数を使用してこれを行いますが、シェーダーではなく C# コードで行います。テクスチャはさまざまなサイズになる可能性があるため、その時点でテクスチャ サイズにアクセスできるため、シェーダーに到達する前に UV を計算する必要がありました。
2 つの UV を計算するために使用したコードは次のとおりです。
Rect surfaceTextureRect = uvReMappers[textureIndex];
Mesh surfaceMesh = allFaces[i].mesh;
Vector2[] atlasTiledUVs = new Vector2[surfaceMesh.uv.Length];
Vector2[] atlasClampedUVs = new Vector2[surfaceMesh.uv.Length];
for (int j = 0; j < atlasClampedUVs.Length; j++)
{
Vector2 clampedUV = new Vector2((surfaceMesh.uv[j].x - Mathf.Floor(surfaceMesh.uv[j].x)), (surfaceMesh.uv[j].y - Mathf.Floor(surfaceMesh.uv[j].y)));
float atlasClampedX = (clampedUV.x * surfaceTextureRect.width) + surfaceTextureRect.x;
float atlasClampedY = (clampedUV.y * surfaceTextureRect.height) + surfaceTextureRect.y;
atlasTiledUVs[j] = new Vector2((surfaceMesh.uv[j].x * surfaceTextureRect.width) + surfaceTextureRect.x, (surfaceMesh.uv[j].y * surfaceTextureRect.height) + surfaceTextureRect.y);
atlasClampedUVs[j] = new Vector2(atlasClampedX, atlasClampedY);
if (i < 10) { Debug.Log(i + " Original: " + surfaceMesh.uv[j] + " ClampedUV: " + clampedUV); }
}
surfaceMesh.uv = atlasTiledUVs;
surfaceMesh.uv2 = atlasClampedUVs;
配列 uvReMappers は、Texture2D 関数 PackTextures() を使用するときに作成される Rect の配列です。
長くなって申し訳ありませんが、私の質問は次のとおりです。テクスチャがゆがむのはなぜですか。メッシュの三角形化の方法によるものですか、それともカスタム シェーダーの書き方によるものですか。そして最後に、どうすれば修正できますか。
お時間をいただきありがとうございます。何度も書いて申し訳ありませんが、以前に質問を投稿したことがありません。私はいつもオンラインでほぼすべての問題の答えを見つけていますが、この問題を解決する方法を何日も探していました. 具体的すぎて答えが見つからないかもしれないと思います。十分な情報を提供できたことを願っています。