シェーダーを介した2Dの3D惑星

シェーダーについて書くように頼んだことを覚えていますか? 覚えてる? いや? しかし、私は覚えていて、書きさえしました。 お願いをします。美しいものについて話しましょう。



今日は、爆発ゲーム用の体積回転惑星の作成方法についてお話します。 それは、もちろん、それらは完全に平らで、ほんの2、3の三角形ですが、体積のように見えます。







に興味がありますか? 猫をお願いします。 写真はまともです。



序文



映画やゲームで視聴者やプレイヤーを欺く方法について説明するのは私にとってではありません。 特殊効果が常にではなく、むしろ逆に、物理学と自然のすべての規則と法則に従って行われることはめったにありません。 いたるところに、単純化、トリック、または錯覚があります。 一方、技術的な制限があり、視聴者は失敗します。たとえば、本当のブラックホールがどのように見えるか、たとえば対空ミサイルからの実際のヘリコプター爆発を誰もが想像できるわけではありません。



なんで? そうそう、私の効果は最も正直で信頼できると主張するものでもありません。 厳密に言えば、私はそれがいかに正しいかを気にしません。 これまたはその効果を開発するとき、私はその品質の比率(私がそれを好むと好まざると)だけでなく、その作業の速度とその実行の複雑さによってより導かれます。 これは、特に論争を避けるためです。 おそらく、説明やソースコードを提供しなかったとしても、「目で」私の欺ceptionにほとんど気付かないでしょう。



一般的に、多くの人が自問します-「アーティストを雇わないのはなぜですか」または「3Dではないのはなぜですか」。 まあ、真剣に、なぜですか? 私たちは大人であり、インディーズ開発者はゲームを楽しみのために作成し、苦労して作成することを知っています。 新郎と大事。 そしてもちろん、彼らは自転車がとても好きです。 私も例外ではありません、私はそれらを愛し、定期的にそれらを行います。 独立を装ってジャックポットを削減しようとする「疑似インディー」開発者がいたはずですが、それは省略します。 だから、あなたは世界を作り、あなたが望むものとあなたが望む方法を作成します。 最終的な画像のすべてのピクセルに責任があり、本来あるべきものを作成できるのはあなただけです!



2Dフルハイト



今日は、爆発ゲーム用の体積回転惑星の作成方法についてお話します。 それは、もちろん、それらは完全に平らで、ほんの2、3の三角形ですが、体積のように見えます。 私たちのゲームは完全に2次元であるため、この効果を実装するためのオプションはあまりありません。 古いゲームで行われていたように、惑星ごとに多くのフレームを再レンダリングしてから、フレームごとに変更するオプションは切断できます。 それはかさばり、例えば、動的雲、惑星の表面の雷雨、または照明の方向の変更を許可しません。 それはもちろん、それは与えますが、このためにあなたは各惑星の種類のためのスプライトの束をするだけです。 もちろん、これは受け入れられません。



解決策は明白でした。 その場ですべてを行う必要があります、シェーダー。 多くの人はすぐに思いつきます。「ニフィガは自明です! 明らかに、これは3D惑星のために3Dを行うことですよね?」 いや ゲームはもっぱら二次元だからです。 残っている唯一の問題は、方法です。 テクスチャジオメトリを確実に変更することは、オフセットマップを使用しない場合にのみ、かなり面倒なコードです。 ディスプレイスメントマップを使用すると、コードがより単純になり、その結果、はるかに高速になります。



ディスプレイスメントマップといえば、ベクトルが含まれており、各色成分が8ビットしかないため、128ピクセル以下でディスプレイスメントをエンコードできると簡単に計算できます。 もちろん、各グラデーションが2ピクセルであることを考慮に入れてから、各方向に最大256ピクセルのオフセットをエンコードできます。 ただし、この場合、通常のディスプレイスメントマップのサイズで十分でした。 シェーダーでの線形フィルタリングにより、サイズの増加を補正しました。

ここでは、現時点でクアッドエンジンエンジンがA8R8G8B8形式のテクスチャのみをサポートするように予約する必要があります。



コンベヤー



シェーダーは、惑星の表面だけでなく、雲、影、光など、惑星をレンダリングするときに使用するすべてのものを歪ませる必要があります。 惑星のテクスチャをグリッドテクスチャに置き換えると、目に見えない同じ歪みが簡単にわかります。



次のステップは、大気と惑星の陰影を適用することです。 これはシェーダーなしですでに実行できますが、シェーダーをここに適用して、ライトポイントのパラメーターを入力することで複雑にすることもできます。 事前に描画されたテクスチャを使用した、よりシンプルなソリューションで管理しました。 もちろん、惑星は、たとえば、大気や雲がなくてもかまいません。 惑星は部分に分割され、その表面全体に光を放出し、間欠泉と火山を持ち、都市や技術構造で覆われます。 選択するための多くのオプションがあります。



必要に応じて、惑星の表面の輝きを操作したり、惑星の昼と夜の部分にさまざまなテクスチャを実装することもできます。 たとえば、夜の都市の輝き。



いくつかの歌詞
この記事を書いているとき、興味深い考えが浮かびました。 しかし、星と一緒に背景を動かし、惑星を反対方向に回転させて、その上の照明を変更するとどうなりますか? その後、私たちの惑星の周りを飛んでいるような完全な錯覚があります。 後ろの行からプロンプトが表示されるので、この場合、フォーカスを忘れてはならず、歪みを追加して、それがあまりに信じられないようにしないでください。





ツールキット







シェーダー
float2 Velocity : register(c0); sampler2D DiffuseMap : register(s0); sampler2D DuDvMap : register(s1); float4 std_PS(vertexOutput Input) : COLOR { float2 source = Input.TexCoord; source.y -= 2.0 / 512.0; source.y = max(source.y, 0.0); source.x += 2.0 / 512.0; float4 right = (tex2D(DuDvMap, source) * 2.0) - 1.0; source.x -= 4.0 / 512.0; source.y = max(source.x, 0.0); float4 left = (tex2D(DuDvMap, source) * 2.0) - 1.0; source.y += 4.0 / 512.0; float4 left2 = (tex2D(DuDvMap, source) * 2.0) - 1.0; source.x += 4.0 / 512.0; float4 right2 = (tex2D(DuDvMap, source) * 2.0) - 1.0; float4 middle = right / 4.0 + left / 4.0 + right2 / 4.0 + left2 / 4.0; float2 coord = middle.rg; coord.x = coord.x / 4.0; coord.y = coord.y / 2.0; coord += Velocity; float4 result = tex2D(DiffuseMap, coord); return float4(result.rgb, middle.a * result.a) * Input.Color; }
      
      









理論から実践へ



グリッドの使用を開始します。 グリッドを使用すると、自分に合った結果にどれだけ近いかを理解できます。 惑星には両側があるため、幅のテクスチャの長さは高さの2倍の長さにする必要があることを考慮してください。 標準では、1024x512ピクセルの解像度のテクスチャを使用します。







2番目に必要なテクスチャは、エンコードされたベクトルを持つ同じdUdVカードです。 512x512ピクセルに相当します。 ここではサイズが小さくなっています。 なんで? シェーダーによって歪められた正方形のメッシュのみが表示されるためです。 そのため、シェーダーに、グリッドのどの正方形部分を与えるかを正確に伝える必要があります。 シフトに伴って正方形を徐々に変更することにより、回転の効果が得られます。







シェーダーを適用し、2番目のテクスチャを使用して元のメッシュテクスチャを変形します。







スクリーンショットでは、ノイズの多い黒い線がはっきりと見えます。 それらはピクセル波に覆われているように見えました。 ビジョンはあなたを欺くものではなく、問題はdUdVテクスチャの制限にあります。 ディスプレイスメントマップには256階調しかありません(上で書いたように)。つまり、128のプラスとマイナスです。 これは、A8R8G8B8形式のテクスチャの制限です。 また、テクスチャサイズは512ピクセルです。 このため、グラデーションは段階的に、ピクセルが繰り返される場所で行われます。 その結果、画像は全体的に歪んでいますが、ピクセルレベルではアーティファクトが含まれています。 もちろん、惑星のサイズとそのテクスチャーにより、この視覚的なアーティファクトを無視することができますが、それは残念です。



技術的な詳細
シェーダーでは、dUdVカードから特定のピクセルのベクトルではなく、いくつかの隣接するピクセルのベクトルを取得して補間することにより、効果を少し弱めようとしました。 したがって、値を平均化します。 ビデオカードには256階調の制限がないため(すべての計算はそこで浮動小数点数を使用して実行されます)、結果は望みのものに近くなります。



dUdVカードには、2つではなく3つのチャネルがあります。 RGB アルファはシェーダーに惑星の形状を伝え、エッジの周りを滑らかにするため、考慮されません。 RとGは、オフセットのエンコードに使用されます。 別の1バイトは空のままです。 色ごとに追加の4ビット(8 + 4)をエンコードするために使用できます。 これにより、精度が大幅に向上し、ちらつきや歪みの問題が回避されます。 明らかに、これはエフェクトの開発における次のステップです。



それでは、先に進みましょう! シェーディングを追加します。 これはシェーダーでも実行できますが、この段階では絶対に重要ではないため、減算モードで半透明のテクスチャを適用します。







惑星の表面のテクスチャを変更し、すでにそれで遊び始めます:







ここで欠けているもの、つまり雰囲気は誰にとっても明らかではありません。 したがって、さまざまなタイプの惑星を描画するための普遍的なクラスを作成するときに、これに直接雲を追加します。 雲は、惑星テクスチャ自体と同じ歪み方法を使用して追加されますが、別のレイヤーに追加されるため、雲は惑星の表面とは反対方向に移動およびねじれます。







雲を既存の惑星と組み合わせます。 雲を惑星よりも1.5%広くしてみましょう。雲はそれほど低くはありません。 そして最後に、ここでそのようなわいせつを得る:







何が起こったのか、なぜすべてがそんなに悪いのか? 雲があり、スクリーンショットの違いにも気付くことができますが、目立たないため、すべてが本当に非常に悪いです。 そして、すべてが悪いのは、惑星が明るくなり、灰色の雲が非常に貧弱に見えるという事実を考慮しなかったからです。 一方で、これは正しいですが、雲は惑星の表面に影を落としますが、私たちはそうしません。 このレイヤーの下に別の暗い雲レイヤーを追加します。







今、雲は光と暗い惑星の両方ではっきりと見える。 しかし、雲が存在する場合、欠落しているのは大気だけです。 彼女を追加する必要があります。 雰囲気は日当たりの良い側で少し輝きを作成する必要がありますので、混合ではなく、色を追加するモードで追加する必要があります。







まったく別の問題。



ただし、上記に戻ります。つまり、クラスは普遍的です。 惑星が傷跡、輝く傷跡で覆われていると想像しましょう。 例えば、明るい溶岩、街の明かり、あるいは、どうやって自分の何かを思いつくのかわかりません。 そして空中には、彼女は明るい雲ではなく、黒い煙のパフを持っています。 ゲームの美しさのために何ができませんか? 私たちは惑星にそのようなテクスチャを生成し、すべての重ねられた効果をそのまま残します:







ここ。 ほとんど美しいですが、1つだけあります-惑星の暗い側には、何も輝きません。 グローマップ(サーフェステクスチャと共に生成される)を取得し、同様に追加します。 すべての上にグローを追加して、影が光に影響を与えないようにするのは理にかなっていますよね?







いいえ、そうではありません! 私はそれが美しいとそれが必要であると言うだろうが、雲(煙)はグローと重ならない、そしてレイヤーのシーケンスは間違っている。



当然、丸いシェーダーを追加して、レイヤーが光っているかどうかに応じて結果に影を適用する必要があります。 そうしないと、レイヤーを再配置しないと、希望する効果が得られません。



多分それは火星ですか? まあ、またはそのようなものですが、雰囲気と大きな滑走路が真ん中にありますか? いいえ、これはバグではありません。最初は思われるかもしれませんが、それはそのようなテクスチャです。







火星や地球のようなものに来たとき、それはここにあり、雲は彼らにとってより白くなるはずだったという疑問が生じました。 すぐに言ってやった! そして、故郷の惑星がなければ、デモは完全に理解できないと思います。 それで、地球もやってみましょう、それはすでにそこにあります!



まあ、同時に、惑星の上と下からう虫を取り除く必要があります。 よりきれいになるように修正しましょう。







単一の惑星ではない



同じ方法を使用して、電動ガンまたはマナを充電するためのスケールを作成しましょう。 これは誰もがそれを好む方法です。 明確にするために、上から一片を切り取り、すでにいくらかの電気を費やしています。 必ずビデオを見てください。これは回転しており、静的なものとは少し違って見えます。



Diablo3:







私たちの実装:







結論



はい、ここは何ですか。 シェーダーはクールです。 以上が結論です! 真剣に、シェーダーなしで、非常に美しくダイナミックなゲームを作るのは大変な労力のようです。 ほとんどすべてのグラフィックス(地球の表面を除く)が生成され、アーティストの介入は必要ありません。 これにより、外部の人々の関与を最小限に抑えてゲームを作成できます。



最後に、ビデオを提供します。






All Articles