敵の火を避けながら、船内で洞窟を飛行します。 しかし、すぐに敵が多すぎることに気づき、これで終わりだと思われます。 生き残るための必死の試みでは、ボタンを押します。 はい、そのボタンに。 特別な日のために用意したもの。 あなたの船は、敵全体に致命的な雷を次々と投入して放出し、敵の艦隊全体を破壊します。
少なくともそれは計画です。
しかし、ゲーム開発者として、あなたはどのようにそのような効果をレンダリングしますか?
稲妻を生成する
結局のところ、2つのポイント間に稲妻を生成することは驚くほど簡単な作業です。 Lシステムとして生成できます(生成中に少しランダム性があります)。 以下は、単純な擬似コードの例です(このコードは、この記事の他のすべてと同じように、2d稲妻を指します。通常、これで十分です。3dでは、その変位がカメラ平面に対して相対的になるように稲妻を生成します。 3次元すべての雷-選択はあなた次第です)
segmentList.Add(new Segment(startPoint, endPoint)); offsetAmount = maximumOffset; // for each iteration // ( ) for each segment in segmentList // , segmentList.Remove(segment); // midPoint = Average(startpoint, endPoint); // midPoint midPoint += Perpendicular(Normalize(endPoint-startPoint))*RandomFloat(-offsetAmount,offsetAmount); // , // () segmentList.Add(new Segment(startPoint, midPoint)); segmentList.Add(new Segment(midPoint, endPoint)); end for offsetAmount /= 2; // end for
実際、各反復、各セグメントは半分に分割され、中心点がわずかにシフトします。 繰り返しごとに、このシフトは半分になります。 したがって、5回の反復で、次の結果が得られます。
悪くない。 すでに少なくとも稲妻のように見えます。 ただし、稲妻には多くの場合、異なる方向に実行されるブランチがあります。
それらを作成するには、ジッパーセグメントを分離するときに、2つのセグメントを追加する代わりに、3つ追加する必要があります。 3番目のセグメントは、1番目のセグメントへの稲妻の連続です(わずかにランダムにずれています)。
direction = midPoint - startPoint; splitEnd = Rotate(direction, randomSmallAngle)*lengthScale + midPoint; // lengthScale < 1. 0.7 . segmentList.Add(new Segment(midPoint, splitEnd));
その後、次の反復で、これらのセグメントも分割されます。 ブランチの明るさを減らすことも良いでしょう。 ターゲットにのみ接続されているため、メインの照明のみが完全な明るさを持つ必要があります。
これは次のようになります。
今ではもっと稲妻のように見えます! まあ...少なくともフォーム。 しかし、残りはどうでしょうか?
光を追加
ゲーム用に開発された元のシステムは、丸い光線を使用していました。 各ライトニングセグメントは、3つの四角形を使用してレンダリングされ、各四角形には、光が適用されたテクスチャがありました(丸い線のように見えるようにするため)。 丸いエッジが交差してジョイントを形成します。 それはかなり良さそうでした:
...しかし、ご覧のとおり、かなり明るくなっています。 そして、稲妻が減少するにつれて、明るさは増加しました(交差点が近づくにつれて)。 輝度を下げようとすると、別の問題が発生しました-雷全体に小さな点のように 、移行が非常に顕著になりました。
オフスクリーンバッファーで稲妻をレンダリングできる場合は、オフスクリーンバッファーに最大ブレンディング(D3DBLENDOP_MAX)を適用し、メイン画面に結果を追加するだけでレンダリングできます。 これにより、上記の問題が回避されます。 このような機会がない場合は、ジッパーポイントごとに2つの頂点を作成し、それぞれを2D法線の方向に移動することにより、ジッパーから切り取られた頂点を作成できます(法線は、この頂点に向かう2つのセグメント間の中央方向に垂直です)。
次のようなものが得られるはずです。
アニメート
そして、これは最も興味深いです。 このことをどのようにアニメーション化しますか?
少し実験してみたところ、次のことが役立ちました。
各ジッパーは、実際には一度に2つのジッパーです。 この場合、1/3秒ごとに雷の1つが終了し、各雷のサイクルは1/6秒です。 60 FPSでは、これが得られます。
- フレーム0:Lightning1は完全な明るさで生成されます
- フレーム10:部分的な明るさでLightning1が生成され、完全な明るさでLightning2が生成されます
- フレーム20:完全な明るさで新しいlightning1が生成され、部分的な明るさでlightning2が生成されます
- フレーム30:新しいlightning2は完全な明るさで生成され、lightning1は部分的な明るさで生成されます
- フレーム40:完全な明るさで新しいlightning1が生成され、部分的な明るさでlightning2が生成されます
- 等
つまり、交互になります。 もちろん、単純な静的減衰はあまり見栄えが良くないため、各フレームはすべてのポイントを少しシフトするのが理にかなっています(エンドポイントをより強くシフトすると特にクールに見えます-これによりすべてがよりダイナミックになります)。 その結果、以下が得られます。
そしてもちろん、エンドポイントを移動することもできます...例えば、ターゲットの移動を目指している場合:
そしてそれだけです! ご覧のとおり、かっこいいジッパーを作るのはそれほど難しくありません。