2Dマゞックの詳现。 パヌト4。 æ°Ž


-プロゞェクトのために氎を掗いたした。
-ああ、かっこいい なぜフラットなのですか 波をあげお
...
-聞いお、それからあなたは波に぀いお話したした、芚えおいたすか それをチェックしおください
「はい、良い波ですが、ただ屈折ずコヌスティクスを行っおいたすか」
...
-こんにちは、私はUnityで䞀晩䞭遊んでいたす。反射ずコヌド化されたコヌスティクスを芋おください
-ダロバ、本圓にいい そしお、あなたの氎が沞隰しおいるずき、反射はバグではありたせんか
...
-ハむ、぀いに沞隰を実珟したした。
-そうだね ほら、沞隰する波を凍らせたらどれだけクヌルなの
...
-写真をキャッチしお、氷が䜕かを思い぀いたようでしたか
-普通に聞いおください。氷が凍っおいたすが、䜓積が増えおいたすか ずころで、い぀からゲヌムプレむを始めたすか
友人ずのログのテヌマのバリ゚ヌション。

はい、あなたはすでに理解したした、最埌に私はプロゞェクトでの氎の実斜に぀いおお話したす。 始めたしょうか


前の蚘事


パヌト1 光。
パヌト2 構造。
パヌト3。 グロヌバルなカバレッゞ。
パヌト4。 æ°Ž


目次


  1. 3Dのぞき芋
  2. りィッシュリスト
  3. 最初のパンケヌキはゎツゎツしおいる
  4. 静力孊
  5. 氎生成
  6. ダむナミクス
  7. 枩床
  8. 結論ず陰謀

3Dのぞき芋


たず、「倧人の男」があらゆる皮類の倧芏暡な3Dプロゞェクトから氎を䜜る方法を芋おみたしょう。
䞀般に、3Dからアむデアをドラッグするこずは優れた蚈画であり、2Dクラスアルゎリズムでは倧幅に少なくなりたす。


したがっお、最も単玔なものからより耇雑なものぞ



りィッシュリスト


倧芏暡なプロゞェクトからの参照ができたので、プロゞェクトに䜕を実装したいかを倢芋たす。


蚘事の冒頭のナヌモラスな玹介を芚えおいたすか これは冗談ではありたせん-別のデモからスクリヌンショットやビデオを友人に投げるたびに、圌は完党にクレむゞヌなアむデアを提䟛しおくれたした。 たた、これらのアむデアのほずんどが実装され、開発の芳点からプロゞェクトがさらに面癜くなったため、これは玠晎らしいこずです。 したがっお、以䞋のリストは、メヌルストヌンず蚈画なしで繰り返しコンパむルされたした。

そしお、これがりィッシュリストのリストです。


  1. 新しいボリュヌムの氎を远加したり、既存のボリュヌムを「蒞発」させるリアルタむムの機胜。
  2. 氎面の波。
  3. 枩床、凍結および沞隰氎の可胜性。
  4. 他のモゞュヌルずの盞互䜜甚颚、身䜓、倩気。
  5. 照明システムずの密接な盞互䜜甚腐食性、光散乱、反射。
  6. ゚ディタヌでカスタマむズする機胜。

そしお、モゞュヌルずの盞互䜜甚に぀いお-トピックはほが無限です。 自分の目で確かめおください-光に関する蚘事で、私はプロゞェクトに神の光線を含める機䌚があるず蚀いたした-空気䞭の塵のために目に芋える光線。 そしお今、私が氎を沞隰し終わったずき、これらの神の光線が芋える蒞気粒子を生成するこずを劚げるものは䜕もありたせん しかし、颚は粒子ず盞互䜜甚する可胜性がありたす。぀たり、お湯の䞊にある蒞気が矎しく消散したす。 そしお、そのような盞互䜜甚が非垞に倚いため、プロトタむプを䜜成するのではなく、蚘録する時間がありたせん。

最初のパンケヌキはゎツゎツしおいる


Hydrophobiaが液䜓を「正盎に」シミュレヌトするようにしたチヌムずは䞀緒に行きたせん。この方法はリ゜ヌスを必芁ずしたす。 簡玠化する必芁がありたす。 pixelartはプロゞェクト内にあるため、すべおの平面は氎平たたは垂盎です。 たた、レベルの空きスペヌスは長方圢のセットずしお衚珟できたす。 ここで圌らず協力したす。
レベルの最初の前凊理で


  1. レベル䞊のすべおの空きスペヌスを長方圢のばらばらのボリュヌムに分割したす。
  2. ボリュヌムの盞互接続を芋぀け、氎の「流れ」のグラフを䜜成したす。

リアルタむムで


  1. 各ボリュヌムに぀いお、衚面の波を個別に蚈算したす波の助けを借りお氎がボリュヌムからボリュヌムぞ流れるこずができるずいう事実を無芖したす。
  2. グラフを䜿甚しお氎の流れを蚈算したす。


氎柱


しかし、実を蚀うず、䜕も起こりたせんでした。 萜ずし穎が非垞に倚いので、5階建おの建物をいく぀か建おるこずができたす。 たずえば、波を同期したり、通信する船舶の圧力に察凊したりする必芁がありたす。 しかし、銀色の裏地がありたす-リヌゞョンツリヌの実装は、このメ゜ッドの実装のために、か぀おプロゞェクトのどこででも䜿甚されおいたした。


静力孊


完党に動的な氎ではうたくいかなかったので、私たちの生掻を簡玠化したしょう-゚ディタヌで氎を調敎し、ダむナミクスの幻想のために波を残したす。 実際、オプションのリストからオプション3に進みたしょう。


氎は流れる方法を知っおいるため、非垞に物議を醞すものです。「これらのポむントに氎があるだろう」ず蚀うこずはできず、そこに液䜓メッシュを眮き、良い写真を撮りたす。 さお、レベルデザむナヌ将来的にはが氎が確実にあるべき重芁なポむントをいく぀か配眮するず、゚ンゞンはその予備から正確にキヌポむントのレベルたで氎を泚ぎたす。 もちろん、1぀の「アンカヌ」を別の「アンカヌ」の䞋に眮くこずができたすが、これぱンゞンの問題ではなく、私たちにずっお未知のレベル蚭蚈者の問題です。


別の機胜は、「バブル」を䜜成するための個別のアンカヌです。 アルゎリズムがそのようなアンカヌを芋぀けるず、それは氎で満たさないようにし、きちんずした空掞に空気を残したす。


どんな結果が埗られるのか理解できたので、今床はアルゎリズムを開発したす。


氎生成


䞀般に、氎はレベル党䜓を埋めるこずができたす。 壁は長方圢の砎片で構成され、どこにでも配眮できるため、氎量は穎のない非凞面の長方圢ポリゎンです。 なんおこった。 もっずシンプルな圢に分けたしょう。


明確にするための小さなスポむラヌ。 前凊理の結果ずしお、波を簡単に蚈算できる氎量を取埗する必芁がありたす。 実際、1぀の氎量は1ピクセルの厚さの氎柱のセットです。

液䜓が存圚する可胜性のある空きスペヌスを扱いたす。 過去の蚘事で話した壮倧な地域ツリヌは、倚くの助けになりたす。 壁で占められおいないすべおの長方圢のボリュヌムを取埗したす。


  1. ツリヌの䞀番䞋最初は巊のコヌナヌから始めお、䞊から最初の空の領域を探したす。
  2. 芋぀かった空の領域から始めお、䞊から最初の空でない領域を探したす。
  3. 結果のセグメントをリストに远加したす。
  4. ツリヌの最䞊郚幟䜕孊的な意味の境界に到達したら、1ピクセル右に移動したす。
  5. ツリヌの右偎の境界線に到達しおいない堎合は、ポむント1に進みたす。
  6. セグメントのリストから長方圢を収集したすそしお、それらはかなり正垞に゜ヌトされたす。
  7. 隣接する長方圢間の接続を構築したす。


千の蚀葉の代わりに


ほずんどの堎合、これらの長方圢をより矎しい方法で取埗できたす。 このトピックに぀いおコメントさせおいただきたす。

実際、長方圢は最良の遞択ではありたせん。 パヌツの数が倚いためタワヌの歯など、長方圢の氎量が倚くなりたす。 そしお、これはパフォヌマンスを䜎䞋させたす。 穏やかな氎は平らであり、底郚の圢状は私たちにずっお重芁ではないため、次のように隣接する長方圢を組み合わせたす。


A ( B), B - ( A) - .


この段階の埌、リブ付きの底のある少量の氎が残りたす。䞋の図では、はっきりず芋えおいたす。



マップ䞊の空きスペヌスのマヌクアップリンク付き


次に、レベルマップ䞊で蚭蚈者が残したすべおのマヌクを芋぀け、レベルごずにワヌクピヌスを「トリミング」する必芁がありたす。 このようなアルゎリズムはこれを凊理したす


  1. すべおの氎䜍マヌク 、倀の降順でy座暙で䞊べ替えたす。
  2. 各ラベルに぀いお
    2.1。 ラベルが属する長方圢を芋぀けたす。
    2.2。 長方圢が芋぀からない堎合、ラベルは壁にあり、無芖しおptに進みたす。 2。
    2.2。 長方圢の高さをラベルのレベルたで䞋げたす。
    2.3。 長方圢の高さがれロになった堎合-長方圢を削陀したす。
    2.4。 䞋端がマヌクの䞊にあるすべおの隣接する長方圢を芋぀けお削陀したす。
    2.5。 他のすべおの隣接する長方圢を芋぀け、ptに進みたす。 2.3氎䜍に埓っおすべおの長方圢を再垰的に切り取りたす。
  3. 気泡のすべおのラベルを収集したす 、倀の降順でy座暙で䞊べ替えたす。
  4. 各ラベルに぀いお
    4.1。 ラベルが属する長方圢を芋぀けたす。
    4.2。 長方圢が芋぀からない堎合、ラベルは壁にあり、無芖しおptに進みたす。 4。
    4.2。 長方圢の高さをラベルのレベルたで䞋げたす。
    4.3。 長方圢の高さがれロになる堎合-長方圢を削陀したす。
    4.4。 䞋端がマヌクの䞊にあるすべおの隣接する長方圢を芋぀けお削陀したす。
    4.5。 ラベルのレベルの䞊に䞊端がある他のすべおの隣接する長方圢を芋぀け、n 4.3に進みたす気泡のレベルに応じおすべおの長方圢を再垰的にカットしたす。

ご芧のずおり、りォヌタヌマヌクず気泡マヌクの違いは、前者がすべおの隣人を再垰的に通過し、埌者が隣人が完党にバブルレベルを䞋回るず停止するこずです。


そしお今、写真で



マップに氎䜍マヌカヌを远加したした



リンクず同じこず



氎䜍でクリップされた長方圢



䜙分なリンクず長方圢を削陀したした



受け取った氎の量を栌安で芖芚化


小さいが重芁なメモ

マヌクのレベルに応じお長方圢を切り取るずいう事実にもかかわらず、それぞれの長方圢で元の高さの配列氎面䞊の倩井のy座暙を保持したす。 将来的には、波を制限するためにこれらの高さが必芁になりたす-さもなければ、波は壁を通過できたす。


゚ディタでどのように芋えるかを芋おみたしょう。



ダむナミクス


珟圚のリアルタむムの氎を攟棄しおいるので、少なくずも矎しい波を䜜りたしょう。 氎を生成するず、次のような氎管理者が埗られたす。


 namespace NewEngine.Core.Water { public class WaterManager : MonoBehaviour { //     // ... WaterPolygon[] waters; CombineInstance[] combineInstances = null; Mesh mesh; public void Generate() { if (tree == null) return; waters = WaterGenerator.Generate(tree, waveCeil); Debug.Log("Regenerate water"); } void FixedUpdate() { if (waters == null) return; var viewportRect = cameraManager.ViewRect; WaterPolygon.Update(waters, ref combineInstances, viewportRect, /*   ,      ,    */); mesh.Clear(); mesh.CombineMeshes(combineInstances); } } } 

これたでのずころ、このすべおのコヌドの䞭で、私たち たたはストヌリヌテラヌずしおの私 はWaterPolygonにのみ興味がありたす。 これらは、あなたが波を䜜るこずができる非垞に最小限の氎です。 たた、これらの芁玠は盞互に接続されおいたすグラフに関する情報は、これらのポリゎンで匕き続き利甚可胜です。 重芁でない詳现を芋逃した堎合、このクラスは次のようになりたす。


途方もないコヌド
 namespace NewEngine.Core.Water { public class WaterPolygon { //  "" -       //    (   y, ),   (,  ) class Line { public int min; // y-    public int max; // y-    public int target; // y-   ,     public int height; // y-     (,    MAX_WAVE_HEIGHT,  ) public float speed; float lastDelta; public void Add(float additionalWater); public void Sleep(); public void Update(float tension, float dampening, float foamThreshold, float foamForce, float foamDampening, float airTemperature, float airTranscalency, float verticalTranscalency, float minBoilTemperature, float minBoilBubble, float maxBoilBubble, float boilFrequency); } //   y   Line,    ,         x int x; //   ;      WaterPolygon[] left; WaterPolygon[] right; //   "" Line[] lines; //      bool sleeping; int sleepingFrames; //      AABB int minWaterY; float maxWaterY; //    UnityEngine Mesh mesh; //     ,      ,  :) public static void Update(WaterPolygon[] water, ref CombineInstance[] combineInstances, Geom.IntRect viewportRect, int outsideCameraSleepOffset, float heightSleepThreshold, float speedSleepThreshold, float tension, float dampening, float spread, int steps, float foamThreshold, float foamForce, float foamDampening, float airTemperature, float airTranscalency, float verticalTranscalency, float horisontalTranscalency, float minBoilTemperature, float minBoilBubble, float maxBoilBubble, float boilFrequency, int sleepingUpdateFrames); //  AABB    offset public bool IsOutside(Geom.IntRect viewportRect, int offset); //    - ,        lines void UpdateFirst(Geom.IntRect viewportRect, int outsideCameraSleepOffset, float tension, float dampening, int steps, float foamThreshold, float foamForce, float foamDampening, float airTemperature, float airTranscalency, float verticalTranscalency, float minBoilTemperature, float minBoilBubble, float maxBoilBubble, float boilFrequency, int sleepingUpdateFrames); //    -     ,       (left  right) void UpdateSecond(float heightSleepThreshold, float speedSleepThreshold, float spread, int steps, float foamThreshold, float foamForce, float foamDampening, float horisontalTranscalency, float airTemperature, float minBoilTemperature); //        void Sleep(bool withClear); //      (    ),    void FindLine(bool isRight, out Line line, out WaterPolygon water); //       public void CreateMesh(ref CombineInstance combineInstance); } } 、フロヌト緊匵、フロヌト湿し、int型の段階、フロヌトfoamThreshold、フロヌトfoamForce、フロヌトfoamDampening、フロヌト空気枩床、フロヌトairTranscalency、フロヌトverticalTranscalency、フロヌトminBoilTemperature、フロヌトminBoilBubble、フロヌトmaxBoilBubble、フロヌトboilFrequency、 namespace NewEngine.Core.Water { public class WaterPolygon { //  "" -       //    (   y, ),   (,  ) class Line { public int min; // y-    public int max; // y-    public int target; // y-   ,     public int height; // y-     (,    MAX_WAVE_HEIGHT,  ) public float speed; float lastDelta; public void Add(float additionalWater); public void Sleep(); public void Update(float tension, float dampening, float foamThreshold, float foamForce, float foamDampening, float airTemperature, float airTranscalency, float verticalTranscalency, float minBoilTemperature, float minBoilBubble, float maxBoilBubble, float boilFrequency); } //   y   Line,    ,         x int x; //   ;      WaterPolygon[] left; WaterPolygon[] right; //   "" Line[] lines; //      bool sleeping; int sleepingFrames; //      AABB int minWaterY; float maxWaterY; //    UnityEngine Mesh mesh; //     ,      ,  :) public static void Update(WaterPolygon[] water, ref CombineInstance[] combineInstances, Geom.IntRect viewportRect, int outsideCameraSleepOffset, float heightSleepThreshold, float speedSleepThreshold, float tension, float dampening, float spread, int steps, float foamThreshold, float foamForce, float foamDampening, float airTemperature, float airTranscalency, float verticalTranscalency, float horisontalTranscalency, float minBoilTemperature, float minBoilBubble, float maxBoilBubble, float boilFrequency, int sleepingUpdateFrames); //  AABB    offset public bool IsOutside(Geom.IntRect viewportRect, int offset); //    - ,        lines void UpdateFirst(Geom.IntRect viewportRect, int outsideCameraSleepOffset, float tension, float dampening, int steps, float foamThreshold, float foamForce, float foamDampening, float airTemperature, float airTranscalency, float verticalTranscalency, float minBoilTemperature, float minBoilBubble, float maxBoilBubble, float boilFrequency, int sleepingUpdateFrames); //    -     ,       (left  right) void UpdateSecond(float heightSleepThreshold, float speedSleepThreshold, float spread, int steps, float foamThreshold, float foamForce, float foamDampening, float horisontalTranscalency, float airTemperature, float minBoilTemperature); //        void Sleep(bool withClear); //      (    ),    void FindLine(bool isRight, out Line line, out WaterPolygon water); //       public void CreateMesh(ref CombineInstance combineInstance); } } 

1぀の優れたチュヌトリアルで波を䜜ったので、流䜓物理孊に぀いおは説明したせん。 簡単に蚀うず、珟圚の高さ、速床、最適な高さがバネでわかっおいる接続されたバネの圢で氎を衚したす。 ばねは振動し、振動を隣人に䌝えたす。 デザむンのスプリングの幅は1ピクセルです。

ただし、重芁な远加事項が1぀ありたす。 チュヌトリアルには「氎トレヌニングの堎」が1぀しかありたせんが、グラフ党䜓がありたす。 そしお、波を正しく同期する必芁がありたす。 䟋はより明確です



このレベルがあるずしたしょう



3぀の氎域で構成されたす



ある時点で、青いポリゎンに波が珟れたす



アルゎリズムは、巊の列の高さに基づいお適切な近傍を芋぀け、波を同期したす



非垞に倧きな波では、アルゎリズムは別のネむバヌを遞択したす


最適化の数分。 次の波を蚈算するこずは意味がありたせん。


  1. 画面倖のポリゎン。
  2. 波のないポリゎン。

次の波の蚈算では、すべおの波がしきい倀よりも小さいかどうかをチェックし、そうであれば、就寝時間を確認したす ポリゎンが画面から完党に倖れおいる堎合、しきい倀はわずかに高くなりたす。 したがっお、接続されたポリゎンたたは他のモゞュヌル物理孊、颚などの圱響により、氎を起こすこずができたす。


これたでのずころ、氎にheする理由はありたせん。 圌女の平和、戊争魔術垫の戊い、平凡なハリケヌンを劚げるものは䜕もありたせん。 Morraの䞭心ずしおの寒さ。 氷を溶かす時間。


枩床


䞍必芁なささいなこずをややman病な研究にもかかわらず、私は珟実の熱力孊にさらに6か月の開発を費やしたくはありたせん。 したがっお、完党に単玔化したす。 そしおもう少し。


りェザヌマネヌゞャヌから始めたしょう。 い぀の日か嵐ず穏やかさがそこにありたすが、今はこれだけです


 namespace NewEngine.Core.Weather { public class WeatherManager : MonoBehaviour { [SerializeField, Range(-100, 200)] float airTemperature; public float AirTemperature { get { return airTemperature; } } } } 

コンセプトは次のずおりです。


  1. 氎枩は最初は気枩ず同じです。
  2. 0°C未満の枩床では、氎が凍結したす。
  3. 100°Cの枩床では、氎が沞隰したす。
  4. 氎の䜓積は互いに枩床を亀換したす。
  5. 氎の䜓積は、倧気の䜓積幟䜕孊的な意味でを考慮しお、倧気ず枩床を亀換したす。
  6. 最適化ず最適化解陀
    6.1沞隰した氎は決しお眠りたせん。
    6.2。 氎が「目芚める」ず、睡眠䞭の液䜓の枩床倉化の簡単な蚈算が行われたす。

WaterPoligon.Lineの枩床は、 氎柱の䞊端ず䞋端にのみ保存されたす。


 class Line { public int min; public int max; ... public float minTemperature; public float maxTemperature; ... } 

非垞に䞍正確な方法-結局のずころ、すべおの投皿の高さが異なりたすが、それは私たちに合っおいたす。


最初は、列をいく぀かの断片に分割し、これらの断片間の熱䌝達を蚈算するずいうアむデアがありたした1぀の列ず隣接する列の䞡方。 この堎合、珟圚の実装では䞍可胜な「局状の氎」氷/æ°Ž/氷を䜜成するこずができたす。

枩床䌝達は、3぀の異なる「方向」で実行されたす。 最初の明癜なこずは、氎柱の端の間です。


 if (length > 0) { ... float avgTemperature = (maxTemperature + minTemperature) * 0.5f; float ratioTranscalency = verticalTranscalency / length; maxTemperature = maxTemperature + (avgTemperature - maxTemperature) * ratioTranscalency; minTemperature = minTemperature + (avgTemperature - minTemperature) * ratioTranscalency; } 

二番目はもっず面癜いです。 空気ずカラムの䞊端の間の熱䌝達。 氎を生成するずき、実際には、倩井の座暙である高さを取埗したした。 したがっお、い぀でも、氎面䞊の空隙の高さを取埗できたす。 氎面䞊の空気が倚いほど、熱䌝達が速くなりたす。 物議を醞す声明。 しかし、戞倖では、氎は䜎い掞窟よりも速く冷华/暖たりたす


 float length = height - min; if (length > 0) { if (height < max) { float airVolume = Mathf.Min(max - height, MAX_AIR_VOLUME); maxTemperature = maxTemperature + (airTemperature - maxTemperature) * Mathf.Clamp01(airTranscalency * airVolume); } ... } 

隣接する列間の熱䌝達を維持したす。 枩床情報は柱の端にのみ保存されるため、線圢補間がシヌンに入りたす。



写真奜きの方ぞ


コヌド愛奜家向け
 static void UpdateTemperatureDelta(float horisontalTranscalency, float[] minTemperatureDelta, float[] maxTemperatureDelta, int i, Line line, Line other) { if (line.height <= line.min || other.height <= other.min) { minTemperatureDelta[i] = 0; maxTemperatureDelta[i] = 0; return; } float height = line.height - line.min; float otherHeight = other.height - other.min; if (Mathf.Max(line.height, other.height) - Mathf.Min(line.min, other.min) >= height + otherHeight) { minTemperatureDelta[i] = 0; maxTemperatureDelta[i] = 0; return; } float minY = Mathf.Max(line.min, other.min); float maxY = Mathf.Min(line.height, other.height); float minT = (minY - line.min) / height; float maxT = (maxY - line.min) / height; float otherMinT = (minY - other.min) / otherHeight; float otherMaxT = (maxY - other.min) / otherHeight; float minTemperature = Mathf.Lerp(line.minTemperature, line.maxTemperature, minT); float maxTemperature = Mathf.Lerp(line.minTemperature, line.maxTemperature, maxT); float otherMinTemperature = Mathf.Lerp(other.minTemperature, other.maxTemperature, otherMinT); float otherMaxTemperature = Mathf.Lerp(other.minTemperature, other.maxTemperature, otherMaxT); float ratio = horisontalTranscalency * Mathf.Clamp01(height / otherHeight); minTemperatureDelta[i] = ratio * (minTemperature - otherMinTemperature); maxTemperatureDelta[i] = ratio * (maxTemperature - otherMaxTemperature); } 

枩床の亀換の構造は波の亀換に䌌おいたすが、波は各偎の隣接する1぀のWaterPolygonにのみ送信され、隣接するそれぞれに熱が送信されたす。


そしお最埌の仕䞊げは、氎を沞隰させお凍らせるこずです。 枩床が100°C以䞊の堎合-ランダムなスプリング速床を液䜓カラムに远加し、枩床が高いほど速床分散が倧きくなりたす実際、100°Cではなく、氎が少し早く泡立ち始めたす。


さお、枩床が0°C以䞋の堎合、スプリング速床をれロに保ち、隣接するスプリングコラムからの速床の䌝達ぞの応答を停止したす。


たたは蚀い換えるず


 if (height < max) { if (maxTemperature >= minBoilTemperature) { float depth = target - min; float ratio = Mathf.Clamp01((maxTemperature - minBoilTemperature) / (100 - minBoilTemperature)); float heightValue = Mathf.Min(depth * 2, Mathf.Max(minBoilBubble, ratio * maxBoilBubble)); float frequency = Mathf.Lerp(0, boilFrequency, ratio * ratio); if (Random.value > 1 - frequency) height += Random.Range(-heightValue, heightValue); } } if (maxTemperature <= 0) { speed = 0; return; } 


埐々に沞隰する氎


結論ず陰謀


䞊蚘のすべおの埌、氎がプロゞェクトに珟れ、゚ディタヌのレベルに「泚ぐ」こずができたす。 寒い生呜を䞎える湿気で刺激的、沞隰、硬化


たくさんのコヌドを曞いおい画像を取埗するのは残念です。 反射、屈折、コヌスティクス-私たちのすべお そのため、ここでも、倪いシェヌダヌ、照明システムずの盞互䜜甚、テクスチャぞのレンダリングなどすべおが行われたす。


しかし、それに぀いおは次の蚘事で詳しく説明したす。 :)



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


All Articles