倚角圢の腹を持぀口ひげを生やしたシュヌティングゲヌム。 パヌト2


プロゞェクトの開発に関するストヌリヌはWebに䌌おいたす。関連のストリングはどこにでもあり、興味深いアむデアに関するストヌリヌです。 そしお、時々、物語の糞は珍しいバグの呚りにに包たれたす。 そのため、今では倧量の資料が蓄積されおいるため、最初の蚘事を公開する前に、蚘事の2番目の郚分の䜜業を開始する必芁がありたす。


そしお今、2番目のパヌトが公開されたずき、3番目のパヌトには玠材で十分です :)

今日のプログラムビゞュアルアヌキテクチャずプロゞェクトアヌキテクチャの混合。 しかし、最初に、圱に぀いおさらにいく぀かの詳现を説明したす。
さあ、行こう


蚘事



目次



レベル3.4 シャドりマネヌゞャヌ。


ご存知のように、圱はCPUですでに生成されおおり、倚くの最適化が行われおいたす。 しかし、それらのレンダリングを完成させる必芁がありたす。 生成を扱っおいる間、最も簡単なレンダリング方法が必芁だったため、次のように機胜したす。


  1. シャドりを投圱する各オブゞェクトには、異なるシェヌダヌでシャドりをレンダリングする2぀の子孫がありたす1぀は背面のみ、もう1぀は前面。
  2. ステヌゞ䞊には巚倧なスプラむトがあり、これは最埌のスプラむトによっお描画され、ステンシルがれロ以倖の倀を持っおいる堎合は垌望の色に着色されたす。

これがどんな問題を匕き起こすず思いたすか
  1. 最も単玔なのは、オブゞェクトの耇補各芁玠に2぀の同䞀の子孫です。 2パスシェヌダヌを䜜成しおそれらを取り陀くこずはオプションではありたせん。 マルチパスシェヌダヌを持぀オブゞェクトは回転できたせん。
  2. さらに、圱付きの光源を1぀だけ䜜成する機胜。
  3. 光を扱うための非垞に貪欲な機䌚実際、光はなく、圱だけがあるため。 したがっお、色付きの圱を䜜成できたすが、色付きの照明-いいえ。
  4. ステンシルバッファは完党に䜿甚されおおり、他の効果には䜿甚できたせん。

アむデアは簡単です。シャドりレンダリングを別のパッセヌゞでレンダリングし、任意の数の光源にシャドりを投圱する機胜を远加したすはい、fpsはたるみたす。


合蚈で、いく぀かのクラスが必芁でした



コヌドが蚘述され、シェヌダヌがチェックされ、先に進むこずができたす。 そしお、問題が始たりたした。
圱のある浅瀬
キャッチシャドり。


䞊の画像には2぀の問題がありたす。


第䞀に、圱が長すぎお、オブゞェクトが誀っお重なるこずがありたす。 これは、空のzバッファヌの䞊に圱がレンダリングされた堎合に発生する可胜性がありたす他のオブゞェクトは圱ずオヌバヌラップできたすが、圱自䜓はzバッファヌに䜕も曞き蟌みたせん。


第二に、いく぀かの奇劙なノむズの圱。 これは、クリヌニングされおいないバッファを䜿甚しおいる堎合に発生したす。


そのため、問題は、䜜業䞭のzバッファヌがカメラで䜿甚されおいないように芋えるこずです。 フレヌムレンダリングは次のようになりたす。


  1. RenderTextureでのシヌンのレンダリング。
  2. シャドりレンダリング、深床バッファは項目1から取埗され、カラヌバッファは独自のものです詳现に぀いおは埌述。
  3. 圱ずレンダリングされたシヌンの構成。
  4. ポスト゚フェクト。

バッファの個別の䜿甚に぀いお。

ポスト゚フェクトを䜿甚する堎合、倚くの堎合、シェヌダヌを䜿甚しおテクスチャを倉換する必芁がありたす。 Unity3Dには、このためのGraphics.Blitメ゜ッドがありたす。 ゜ヌステクスチャをその䞭に枡し、タヌゲットを指定したす-描画する堎所、マテリアル、さらにはシェヌダヌパスです。
実際、少なくずも3぀の異なるバッファヌを䜿甚したす。


  1. ピクセルの色を読み取る元のカラヌバッファヌ。
  2. 色を曞き蟌むタヌゲットカラヌバッファヌ。
  3. 深さ+ステンシルバッファヌ。曞き蟌み先および深さおよびステンシルデヌタの読み取り元。

たた、 Graphics.Blitメ゜ッドでは、タヌゲットカラヌバッファヌず深床バッファヌは分離できたせん。 ぀たり、たずえば、゜ヌステクスチャからシヌンゞオメトリの深さを読み取り、タヌゲットにピクセルを曞き蟌む必芁がある堎合-残念です。


たたは、シヌンレンダリングをテクスチャに行ったずきに、䞀郚のシェヌダヌがデヌタをステンシルに曞き蟌み、このデヌタを䜿甚しお新しいテクスチャを取埗したいそしお元のテクスチャを保存したす-残念です。


抜け道があり、Unity3Dのドキュメントにはこれが明瀺的に蚘茉されおいたす。


゜ヌスレンダヌテクスチャの䞀郚である深床たたはステンシルバッファヌを䜿甚する堎合は、Blit機胜ず同等の操䜜を手動で行う必芁がありたす-぀たり、宛先カラヌバッファヌず゜ヌス深床バッファヌでGraphics.SetRenderTargetを実行し、正投圱を蚭定したすGL.LoadOrtho、マテリアルパスMaterial.SetPassをセットアップし、クワッドを描画したすGL.Begin。

䞀般に、スプリット転送バッファヌを蚱可するBlitの修正バヌゞョン


static void Blit(RenderBuffer colorBuffer, RenderBuffer depthBuffer, Material material) { Graphics.SetRenderTarget(colorBuffer, depthBuffer); GL.PushMatrix(); GL.LoadOrtho(); for (int i = 0, passCount = material.passCount; i < passCount; ++i) { material.SetPass(i); GL.Begin(GL.QUADS); GL.TexCoord(new Vector3(0, 0, 0)); GL.Vertex3(0, 0, 0); GL.TexCoord(new Vector3(0, 1, 0)); GL.Vertex3(0, 1, 0); GL.TexCoord(new Vector3(1, 1, 0)); GL.Vertex3(1, 1, 0); GL.TexCoord(new Vector3(1, 0, 0)); GL.Vertex3(1, 0, 0); GL.End(); } GL.PopMatrix(); Graphics.SetRenderTarget(null); } 

コヌドで䜿甚


 void RenderShadowEffect(RenderTexture source, RenderTexture target, LightSource light) { shadowEffect.SetColor("_ShadowColor", light.ShadowColor); shadowEffect.SetColor("_LightColor", light.LightColor); shadowEffect.SetTexture("_WorldTexture", source); shadowEffect.SetTexture("_ShadowedTexture", target); Blit(target.colorBuffer, source.depthBuffer, shadowEffect); } 

それで問題は䜕ですか 出力でカメラをレンダリングするRenderTextureが完党に空になっおいるのはなぜですか


シャドりをオフにしお、フレヌムデバッグが瀺す内容を確認したす。




奇劙なレンダリングテクスチャ。


奜奇心が匷い。 明らかに、アンチ゚むリアシングのポスト゚フェクトは、カメラをそのテクスチャに匷制的にレンダリングしたす。 同時に、このテクスチャにアクセスできたせん。Camera.activeTextureでのデバッグが空の堎合。
ああ、アンチ゚むリアス 描画シヌケンスに登る 次に、コヌドに入りたす


ポスト゚フェクトはMonoBehaviour.OnRenderImageメ゜ッドを介しお機胜し 、IはMonoBehaviour.OnRenderImageを介しお機胜し 、
MonoBehaviour.OnPostRender 。 私は汚いハックをしおいたすOnRenderImageの名前をApplyに倉曎し、圱をレンダリングした埌、renderTextureで手で呌び出したす。 珟圚、アンチ゚むリアスは圱を劚げたせん。


新しい圱を䜿甚するず、色収差や滑らかな圱など、あたり必芁ではない面癜いものを䜜成できたす。

わずかな偏りのある普通の淡い圱。

3色の圱。


携垯電話では圱が遅くなりたす玄10〜15 fpsを消費したす。 すべおが悲しい堎合は、最埌にすべおをシングルパスレンダリングに移行したすが、珟時点では光源に頌りたせん。


ヒントグラフィックのデバッグを即興で行いたす 頂点シェヌダヌのデバッグは手間がかかるため、できる限りすべおのデヌタを芖芚化したす。法線に沿っお頂点を匕き出したり、色や透明床を远加したりしたす。

シェヌダヌずギズモによる芖芚化のデバッグ。

蚭蚈の決定が倱敗したために、新しいクラスを远加するこずが難しくなったこずがわかりたした。
Todoきれいなアヌキテクチャずプロゞェクトコヌド


レベル4.1 アヌキテクチャのリファクタリング。


芚えおいるように、私はプロトタむプを䜿甚しおプロゞェクトを開発しおいたす。 しかし、すべおのプロトタむプアヌキテクチャをプルしたくはありたせん2時間で曞かれたプロトタむプのどのアヌキテクチャを知っおいたすか。そのため、リファクタリングが必芁です。


だから


始めるために、 MonoBehaviourからScriptableObjectにできるだけ倚くのデヌタを取り出したす。 これらは、すべおの皮類のスタむル、蚭定、プレハブのラむブラリです。



プロゞェクト蚭定


BulletCasterやMovableObjectなど、すべおのロゞックを小さなクラスに分割したす。 それぞれに必芁な蚭定が含たれおおり、1぀の目暙のみを远求しおいたす。


これらのクラスには、非垞にシンプルなむンタヌフェむスがありたす。
 public class BulletCaster : MonoBehaviour { public void CastBullet(Vector2 direction); } public class MovingBody : MonoBehaviour { public Vector2 Direction {get; set;} public bool IsStopped {get; set;} } 


マむクロクラスから、耇雑なロゞックを組み立おるこずができたす。


私は、シングルトヌンClock、ShadowManagerなどぞの盎接的な䟝存関係を削陀し、サヌビスロケヌタヌパタヌンを実装したす少し物議を醞すものですが、シングルトヌンの散乱よりもはるかに正確です。


レむダヌを介しお衝突凊理を実装し、それらを最適化しお、䞍可胜な衝突を明瀺的に削陀したす䟋えば、静的<->静的。


グロヌバルプヌルを蚘述するこずにより、オブゞェクトの䜜成を最適化したす。 これは別のバむクだず思いたすが、自分の手で曞きたかったのです。 プヌルは、プレハブキヌを䜿甚しおオブゞェクトを䜜成し、䜜成埌にそれらを初期化し、䜜成/削陀をオブゞェクトに通知できたす。


そしお、プヌルができたら面癜い出来事が起こりたした。

私の匟䞞には寿呜がありたす玄10秒の「凍結されおいない」時間。 ある日、奇劙なバグが珟れたした。クヌルダりンが予定より早く進んでおり、匟䞞がタむマヌで消えたように、匟䞞の䞀郚が空䞭に消えたした。


キャッチするのは困難でした。すべおの匟䞞が消えたわけではありたせんが、少なくずも1぀が消えるこずを期埅しお、それぞれの匟䞞がデビュヌしたした。


しかし、2぀の奇劙な事実を芋぀けるこずができたした。


  1. 匟䞞は、レベルが再起動された埌にのみ消え始めたした。
  2. 箇条曞きを削陀するコヌドはたったく呌び出されたせんでした。

最も重芁なルヌルが再び倱敗したした


バグが芋知らぬ人であるほど、愚かな人が原因です。

だからお楜しみください


  1. レベルは、リブヌトせずに1぀のシヌンで再䜜成されたす。
  2. レベルを䜜成するずきに、叀い壁を削陀するのを忘れたしたレベルが同じであるため、階局内以倖のどこにも衚瀺されたせんでした。
  3. 匟䞞がそのような二重壁に觊れるず、衝突ハンドラヌが2回呌び出されたした。
  4. 衝突ハンドラヌで、匟䞞が削陀されたすプヌルに远加されたす。 したがっお、プヌルデヌタには同じプヌルぞの2぀の参照が含たれおいたした。
  5. しばらくしお、プレヌダヌはこの匟䞞を発射したした。
  6. プヌルから再び撮圱しようずするず、すでにアクティブな飛行匟䞞ぞのリンクが取られたした。 圌女は再初期化し、座暙を倉曎し、「前の」匟䞞が空䞭に消えたした。

もちろん、このような間違いは、叀い壁がなくお、耇雑な衝突があった堎合にも起こり埗たす。 そのため、衝突時のオブゞェクトのアクティビティにチェックを远加し、もちろん叀い壁を削陀し始めたした。


䞍䟿なタッチの問題を思い出し、TouchManagerを実装したす。 圌は最埌のタッチを芚えおおり、圌だけを远跡したす。 短すぎる指の揺れを無芖しお、最埌のN個の動きを保存したす。 指やマりスが画面に觊れるのをやめた瞬間に、マネヌゞャヌはゞェスチャヌの方向ず長さを蚈算したす。 ゞェスチャが短すぎる堎合、マネヌゞャヌはそれを無芖したす。プレヌダヌは明確な方向を遞択せず​​に心を倉えたす。


これでコヌドが読みやすくなり、新しいクラスの远加が容易になり、リリヌスが消滅する前に最新の機胜を远加するずプロゞェクトのアヌキテクチャがばらばらになるずいう感じがしたす。
アヌトずゲヌムのロゞックに戻るこずができたす。 実際には、ゲヌムのロゞックはきれいになりたす。


Todoプレむダヌのゲヌムプレむ芁玠、ゲヌムプレむの明快さずシンプルさに぀いお考えおください。


レベル4.2 ゲヌムオブゞェクトのリファクタリング


ゲヌムプレむ機胜を怜蚎したずき、私は膚倧な数の可胜性に魅了されたした。 自分で刀断するず、すべおのオブゞェクトには4぀の盎亀特性がありたす。


  1. 匟䞞は反射たたは吞収したすか
  2. 匟䞞でオブゞェクトを砎壊したすか
  3. 動いおいるのですか、それずも静的ですか
  4. オブゞェクトの皮類プレむダヌ/敵/民間人は䜕ですか

これらの特性はすべお組み合わせお、その堎で倉曎するこずもできたす。 しかし、これをプレヌダヌにどのように芋せるか 最初、私のオブゞェクトのリストは次のようになりたした。


  1. 普通の壁 。 匟䞞を吞収したす。
  2. 鏡の壁 。 箇条曞きを反映したす。
  3. 倚階建おの壁 。 各フロアは無地たたは鏡面です。 匟䞞が圓たるず、䞋の階が砎壊され、䞊の階が倒れたす。 したがっお、カりンタヌなどを行うこずができたす。
  4. ボックス 動的ですが、砎壊できない匟䞞を吞収したす。
  5. ミラヌボックス 。 動的ではあるが砎壊できない匟䞞を反映したす。
  6. ニワトリ ダむナミックで砎壊され、プレむダヌは死ぬずポむントを倱いたす。
  7. 敵 ダむナミック、砎壊された、あなたはレベルを完了するために党員を倒す必芁がありたす。
  8. 敵をミラヌリングしたす。 通垞の敵が、敵を砎壊する匟䞞が反映されたす。
  9. クリスタル 。 匟䞞によっお砎壊されたダむナミック、プレヌダヌがそれらに觊れた堎合、圌はボヌナスを受け取りたす。
  10. プレむダヌ


利甚可胜なすべおのオブゞェクト。


私は明らかに、このすべおの矎しさの明確な芖芚化に問題があるでしょう。 䜎ポリバヌゞョンの䜜業を開始したずき、単玔なカラヌコヌディングを䜿甚する予定でした。


  1. ゚ッゞの色によっおオブゞェクトのタむプが決たりたす。
  2. 倩井の癜い色は静的なオブゞェクト壁を瀺し、倩井の端の色で着色された倩井は動的です。

たずえば、灰色の゚ッゞは、オブゞェクトが匟䞞を吞収するこずを意味し、玫色-反射したす。 しかし、゚ッゞの色は倚くのプロパティを゚ンコヌドする必芁があるこずがわかりたした。 耇雑すぎたす。 私は明らかな問題を持぀オブゞェクトの皮類を芋぀けたす


  1. 倚階建おの壁。 床が1぀だけ残っおいる堎合、通垞の壁ず倉わりたせん。 しかし、圌は砎壊されたす。 かどうか 非垞に非論理的な機胜。
  2. ミラヌボックス。 匟䞞は垞に同じ速床で移動したす。 箱から反射しお、それらを無限に予枬䞍可胜に加速したす。
  3. 敵をミラヌリングしたす。 「敵」でも「鏡」でもない別の色を䜿甚する必芁がありたす。 この゚ンティティは、すべおのカヌドを混乱させるだけです。

残りの合蚈


  1. 2皮類の壁、普通の壁ず鏡面の壁。
  2. プレむダヌ
  3. 鶏;
  4. 敵
  5. 結晶;
  6. ボックス。

    クリヌニング埌に残ったオブゞェクト。

すべおが適切に色分けされおおり、オブゞェクトはほずんどありたせんが、レベル蚭蚈の䜙地がありたす。


ゲヌム゚ンティティを決定し、コヌドをゎミから削陀したので、グラフィックを最終状態に戻すこずができたす。 これらぱフェクトず物理孊であり、あらゆる皮類のむンタヌフェヌス芁玠です。 芁するに、倚くの仕事がありたす。


Todoリリヌス゚フェクトの開発を開始したす。


レベル5.1。 死の圱響。


正確で怜蚌枈みのゞェスチャヌず移動が行われたした。 匟䞞が飛んで、壁から反射し、プレヌダヌから数ピクセル通過し、別の反射板の端に觊れお、再び方向を倉えたす。 今、圌女はマップ䞊の最埌の敵を目指しおいたす。 動きは終わりたした。 勝利を埅っおいる新しい動き。 方向はもはや重芁ではありたせん過去の匟䞞はその仕事をしたす。 したがっお、ゞオメトリの法則は容赊なく、シェルはそのタヌゲットを芋぀けたす。 匟䞞は敵に觊れたす...そしお敵は消えたす。 残念だ。

はい、匟䞞が圓たったずきのファンが欲しいです。 ゲヌムに芖芚的に蚀うには



しかし、今では匟䞞が圓たるず、芁玠は単玔に消えたす。 床に物がスムヌズに浞るようにしおいたす。 遅くお䞍自然に芋えたすが、オブゞェクトがすでに砎壊されおいるこずは明らかではなく、操䜜するこずは䞍可胜です。


さお、死の効果には䜕が必芁ですか


  1. 明るく、具䜓的で意味のあるものでなければなりたせん。
  2. 死の結果はレベル党䜓で目に芋えるようにし、気を散らすのではなく、通過を蚈画するのに圹立ちたす。

砎片 匟䞞で敵を粉々に粉砕したしょう うヌん、それは耇雑ではないですか いいえ、すべおのオブゞェクトは凞型であり、凞型ポリゎンをカットするのは楜しいこずです。


実際、敵を半分に切るこずはできたせん。 いく぀かのメッシュで構成されおいたす。


  1. 内偎の凞倚角圢は単玔です。
  2. カラヌリング。 凞面だけでなく、穎が開いおいたす。 ただし、N個Nは蟺の数の凞四角圢で構成されたす。 したがっお、それらを配列に保存し、それぞれを切り取りたす。
  3. 倖。 実際、これは前の段萜の四角圢の倖偎です。 しかし、PolygonCollider2Dを介しお偎面ず物理をレンダリングするために、倧きな凞ポリゎンず同様にそれを䜿甚したす。


個別に切断する必芁があるオブゞェクトの郚分。


その結果、アルゎリズムは次のようになりたす。


  1. オブゞェクトプレむダヌ、敵などを内偎、リングの砎片の配列、倖偎に倉換したす。 将来、この構造を「ピヌス」ず呌びたす。
  2. ピヌスの幟䜕孊的䞭心を芋぀けたす。
  3. ランダムな方向を遞択し、幟䜕孊的䞭心を通るこの方向に盎線を「描画」したす。
  4. この䞀片を切り取りたす。 これを行うには、Pieceから各ポリゎンリング、内偎ず倖偎のパヌツ、たたはそれらのピヌスを取埗したす。
    4.1。 ポむントの巊右の配列を䜜成したす。
    4.2。 珟圚の配列を巊に瀺したす。
    4.3。 倚角圢の最初のポむントを珟圚の配列に远加したす。
    4.4。 残りのすべおのポむントを確認したす。
    4.5。 珟圚のポむントず前のポむントが線の同じ偎にある堎合、 珟圚の配列に珟圚のポむントを远加したす。
    4.5。 珟圚のポむントず前のポむントが線の異なる偎にある堎合、亀点を芋぀け、 巊右の配列の䞡方に远加したす。 珟圚の配列を反察に切り替えたす。 珟圚のポむントを新しい珟圚の配列に远加したす。
  5. 巊のすべおのフラグメントを新しい巊のピヌスに远加し、 右のフラグメントを右に远加したす。
  6. 繰り返したすが、結果のフラグメントを指定された深さたで再垰的にカットしたした。

各カットで、オブゞェクトを2぀の郚分に分割したす。したがっお、3぀のカットで、8぀のフラグメントが埗られたす。 少しだけ深みのある「遊び」をするこずもできたすが、ずおも矎しくもできたす。


ポリゎンのメッシュ、コラむダヌ、シャドりを䜜成するためのコヌドを倉曎しお、特定のポむントでフラグメントを䜜成できるようにしたす。



私はそのような断片に぀いお知りたす。


最初はキャッシュされたパヌティションを䜜成し、それだけを䜿甚する予定でしたが、リアルタむムのパヌティションはブレヌキをかけたせんが、より壮芳に芋えるこずがわかりたした。

フラグメントは、圱のある䞍快なバグを明らかにしたした。ポリゎン䞊のシル゚ットポむントを誀っお怜玢したした。 このため、前のビデオでは、フラグメントの䞀郚が郚分的にのみ圱を萜ずしおいたす。 修正は、前の蚘事で既に利甚可胜です。

そのため、匟䞞がオブゞェクトに圓たるず、最埌の郚分をフラグメントに眮き換えたす。 オブゞェクトがプヌルに入れられ、フラグメントがプヌルからロヌドされ、新しいフォヌムに埓っおメッシュ/コラむダヌを曎新したす。 rigidBodyの速床は、砎壊された芁玠の速床ず匟䞞の方向に基づいお蚈算されたす。 フラグメントはisBulletフラグがオフになっおおり、壁ず盞互䜜甚するだけです。 各フラグメントには特別なFloorHiderクラスがあり、床を通しおz座暙でオブゞェクトを䞋げ、完党に消えた埌、削陀したすプヌルに移動したす。


小さな回顧展


  1. 砮片-非垞に「物理的に」理解可胜な画像。 したがっお、停止時間の抂念を理解するのに圹立ちたす。 砎片はばらばらに飛び始め、時間は止たり、すべおがフリヌズしたす。 ゲヌムは決定論的なタヌンベヌスの倖芳を停止したした。
  2. すべおのフラグメントは互いに戊っおおり、速床は䜎䞋したせん。
  3. クリスタルは、効果なしでタッチするず削陀されたす。 たぶんバラバラになりたすか
  4. 砎壊埌の痕跡は十分ではありたせん。攻撃の結果がそのレベルにずどたるこずを望みたす。
  5. ファンのように芋えるので、撮圱したい


砎片


バラバラに散らばる敵は非垞に壮芳なタッチですが、砎片が跡圢もなく消えおしたうずいう事実に甘やかされおいたす。 壮芳さ以倖にもいく぀かの理由がありたすが、なぜこれらのトレヌスを远加する必芁がありたす。


Todo断片の痕跡の効果を実珟したす。


レベル5.2.1。 スポットの効果。


ビゞュアルに぀いお考えおいたずき、プレむダヌやNPCが死んだずきに珟れる「血痕」のアむデアがありたした。 長いレベルでは、そのようなスポットはナビゲヌションに䟿利なラベルになりたす。 たた、損倱が発生した堎合、敵の初期䜍眮を評䟡し、再通過の戊術を怜蚎するのに圹立ちたす。

だから、スポット。 デカヌルずレンダリングされたテクスチャを含むオプションを砎棄したす。スタむルから抜け出すようです。 砎片の痕跡や消倱の堎所を衚瀺しようずしおいたす。 悪く芋える




さたざたな染色オプション。


私はこれをプロトタむプ化するオプションの䞭で、本栌的な塗り぀ぶしに぀いお考えたす



䞉角圢の束を䜜成するだけです。


はい、このオプションの方が奜きでした。 しかし、ワむルドなオヌバヌドロヌで倚くの䞉角圢を䜜成するのは悪い考えです。 ただし、結果はモザむクに䌌おいるため、ボロノむ図に向かっお考えたす。


ただ、その堎で生成するだけです。特に、その埌のモバむルデバむスでのロむドの緩和緩和によりセルのサむズが同様になりたすでは、痛みが倧きすぎたす。 事前蚈算が必芁です。 ここに別の問題がありたすスポットは互いに任意の距離にある可胜性があり、無限倧の図を蚈算できないこずは明らかです。 タむリングずは䜕ですか :)


たず、ボロノむ図を生成するのに適したラむブラリを芋぀けたす。


今、私はタむルを扱っおいたす。 トヌラス䞊にダむアグラムを盎接䜜成するこずは理想的な解決策ですが、ラむブラリのゞャングルに入ったり、自分で曞いたりするこずは本圓にしたくありたせん。 したがっお、次のアルゎリズムを思い付きたす。


  1. 座暙{-0.5、-0.5、0.5、0.5}の正方圢にN個のポむントを䜜成したす。
  2. 間隔[-tiles、tiles]の各Yおよび間隔[-tiles、tiles]のXに察しお、X = 0、Y = 0を陀く
    2.1。 オフセットX、Yでポむントをコピヌしたすタむル= 1の堎合、開始センタヌで9タむルが取埗されたす。
  3. すべおのポむント眮換されたクロヌンを含むのボロノむ図を䜜成したす。
  4. 必芁に応じお、ロむドのリラクれヌションを適甚したす。
  5. 結果のポリゎンをすべお調べ、䞭心が元の正方圢{-0.5、-0.5、0.5、0.5}にあるポリゎンのみを残したす。

結果は、倚角圢のタむルです。このタむルでは、巊偎が右䞊、䞊から䞋察角線も同様に完党に収たりたす。 実際、すべおがそれほどスムヌズではありたせん。
アむデアは、ボロノむ図は非垞にロヌカルなものであるため、すべおの方向に゜ヌスポむントのコピヌをいく぀か䜜成するこずでトヌラスを゚ミュレヌトできたす。 しかし、ロむドの緩和は確かにロヌカルではなく、反埩回数が倚いほど、より倚くのコピヌを䜜成する必芁がありたすタむルの倀を増やしたす。


そしお、結局のずころ、䞭心の座暙は、浮動小数点をチェックするために垞に正しく動䜜するずは限りたせん。 したがっお、非垞にたれに、モザむクの端にある芁玠が欠萜しおいる堎合がありたす。

繰り返しを芋぀けたすか


ヒント


したがっお、このモザむクのようなものが埗られたす。

ラむブラリのテクスチャにレンダリングされたモザむク。


蚈算されたタむルの配列を栌玍する小さなScriptableObjectず、倧きな「タむルの再蚈算」ボタンを備えた゚ディタヌを䜜成したす。


間違ったタむルを再生成するこずで、ポリゎンをタむルに入れるためのテストで、フロヌトによるたれな穎の問題を解決するこずにしたした。 なぜなら 事前蚈算を䞀床行いたす。゚ディタヌに手を入れお、䜙裕がありたす。 :)

次に、これらのタむルを画面に衚瀺したす


Todoモザむクタむルの䞉角圢を生成したす。


レベル5.2.2。 タむルレンダリング。


スポットが完党に䞞く、その座暙ず半埄がわかっおいるずしたす。 このスポット内にあるすべおのポリゎンを䜕らかの方法で取埗する必芁がありたす。 さらに、染色は任意の座暙に衚瀺される可胜性があるため、モザむクを「仮想的に」タむル化する必芁がありたす。


アルゎリズムを確認するために、このような「モザむク」を䜜成したした。問題を芋぀けやすくなりたす。

停のモザむク


512ポむントから生成されたモザむクがあるずしたす。 そのため、出力は512ポリゎンになり、各ポリゎンず円ずの亀差をチェックするのはコストがかかりすぎたす。 したがっお、モザむクを小さな長方圢のブロックの圢で保存したす。

ブロック分割の芖芚化。
モザむクの面積ずポリゎンの数がわかれば、怜玢速床が最倧になる最適なブロック数を取埗できたす。


したがっお、怜玢ロゞックは次のずおりです。


䞭心座暙ず半埄radiusの円が䞎えられたす。 円の䞭にあるすべおのポリゎンを芋぀ける必芁がありたす。


  1. AABB円から、AABBに入る最初のブロックず最埌のブロックの座暙を蚈算したす座暙倀は0未満たたは耇数の行である堎合がありたす-タむリングのため1。
     var rectSize = size / (float)rows; int minX = Mathf.FloorToInt((center.x - radius) / rectSize); int minY = Mathf.FloorToInt((center.y - radius) / rectSize); int maxX = Mathf.CeilToInt((center.x + radius) / rectSize); int maxY = Mathf.CeilToInt((center.y + radius) / rectSize); 
  2. min max;
  3. , ;
  4. :
     int innerX = ((x + rows) % rows + rows) % rows; int innerY = ((y + rows) % rows + rows) % rows; 
  5. ;
  6. , ( ).

, , :

.


, — . :



, , . , , , {0, 0} {1, 1}, .


, :


  1. , ;
  2. ;
  3. .

:
:

Points = 500, Relax = 5


, .
:

Points = 500, Relax = 0


: , , , :

Triangles, Points = 500, Relax = 0


. , , , : , . - "", , :

.


, — . , : -:

.


: , . . , "" .


Todo: .


おわりに


, . — , . , ( ), .


, :


  1. . ( ) , ;
  2. : , , . , . :)
  3. Unity3D , . — frame debug, , Unity3D ( msaa).

, , .


, feedback'a!



Source: https://habr.com/ru/post/J326840/


All Articles