みなさんこんにちは。 ご存知のように、Unity3Dには2Dゲームの照明サポートがありません。 この
ようなシステムはAsset Storeで見つけることができます
が、 1つの欠点があります-CPU上で実行され、多くのリソースを消費します(各光源のフレームごとに64-4096 reykast)。 そのため、私は自分の照明を作ることにしました。その性能はモバイル機器に十分なものになるでしょう。 このため、計算はGPUに転送されました。 テラリアやスターバウンドの光のようなものになりました。
デモへのリンク。 矢印-移動、スペースバー-シャーシ、R-再起動。 それから取られたスクリーンショット。
すべての照明は小さなテクスチャでカウントされ、この例では160x88ピクセルが使用されます。 解像度を上げると、非常に細かいグリッドを実現できますが、これはモバイルプラットフォーム用ではありませんが、気づきにくいものです。 このような小さなテクスチャで計算が実行されるため、かなり重いシェーダーを使用できます。
照明の操作には、3つのカメラが使用されます。各カメラは、システムの一部(光源、光の障害物、環境光)を担当します。 次に、光源と環境光が混合され、ゲームカメラに重ねられます。
次に、描画順序でさらに詳しく説明します。
光の障害
光閉塞テクスチャ。 RGBチャンネル。 これと類似のテクスチャのスケールは400%ですこれは、カメラが与えるテクスチャです。 黒い領域は完全に透明で、白い領域は完全に不透明です。 色付きの領域もサポートされています。たとえば、完全に赤いピクセルが光の赤い部分をブロックし、緑と青を通過させます。
環境照明
環境光源環境の光源。 アルファチャンネル繰り返し生成される環境光テクスチャ通常の光源がない、わずかに増幅された周囲光のように見えますそれはすべてもう少し複雑です。 光源のない空間にかすかな光を加えるために、このタイプの照明を実装しました。 例では、それを使用して、空き領域全体の薄暗い強調表示が実装されています。 RGBチャンネルは色を制御し、アルファチャンネルは光度を制御します。 このタイプの光源と従来の光源の主な違いは、反復光源と見なされ、方向性がないことです。
1ピクセルの計算アルゴリズム:- 前の反復テクスチャから初期ピクセル値を取得します。
- 障害物のテクスチャからピクセルから障害物の力を引きます。
- 環境の光源のテクスチャからの光度をピクセルに追加します。
- 隣接するピクセルの平均値をピクセルに追加します
光源
光源従来の光源は照明システムの主要部分です。 スプライトに似たものを使用して描画します。 必要に応じてポイントを任意の場所に移動できますが、すべての色は中心から来ます。
光源の場合、パスのトレースを含むシェーダーとパスのないシェーダーを使用できます。 トレースシェーダーは、トレースされるポイントの数が異なります。 これらのうち2つを使用します。1つは9ポイントで、Shader Model 2.0で動作し、もう1つは20ポイントでShader Model 3.0で動作します。 パストレースを使用しないシェーダーは、追加の情報を必要としないため、パーティクルシステムに使用されます。
パストレースアルゴリズム:- テクスチャからピクセルの明るさを取得します。
- 光源の位置と障害物テクスチャの現在のピクセルを見つけます。
- 前のステップの2つのポイントの間にある障害物のピクセル値だけ現在の輝度を下げます。
9ポイントトレースシェーダーShader "Light2D/Light 9 Points" { Properties { _MainTex ("Light texture", 2D) = "white" {} _ObstacleMul ("Obstacle Mul", Float) = 500 _EmissionColorMul ("Emission color mul", Float) = 1 } SubShader { Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} LOD 100 Blend OneMinusDstColor One Cull Off ZWrite Off Lighting Off Pass { CGPROGRAM
光のブレンドとブレンド
光源+環境光ソースのライトと環境のライトがレンダリングされた後、それらを互いに混合できます。 これを行うには、テクスチャにアルファを掛けて追加します。 次に、これらすべてがゲームの画像にスーパーインポーズされ、画面に表示されます。
結果のスクリーンショット、クリック時の高解像度。そして最後に、賛否両論
長所:
- GPUで計算が行われます。
- 光源はそれぞれ通常のスプライトであり、任意の形状の光源を作成できます。
- 各光源が消費するリソースはごくわずかです。
- Nexus 4では、モバイルデバイスで動作し、1フレームあたり約8ミリ秒を消費します。
- 完全に動的な照明。 生産性を損なうことなく、障害物をその場で作成および破壊できます。
- 環境光のサポート。
- システム自体が6つのDrawCallsを生成します。すべての光源は、周囲光用にもう1つ追加できます。
- マルチカラーの光源と障害物。
- パーティクルシステムで光源を放出する機能。 パフォーマンスは通常のパーティクルとほとんど変わりません。
- 柔軟な品質設定。
短所:
- システムはグリッド上で点灯するため、小さな障害物は無視できます。 強力なプラットフォームでは、グリッドを非常に小さくすることができます。
- 環境光と障害物のメッシュを生成する必要があります。
- スクリーンの背後にある光源が正しく表示されるように、照明が作成されるカメラのサイズはゲームカメラのサイズよりも大きくなければなりません。
- システムの計算の複雑さは、ソースの数にほとんど依存していません。 つまり、10個の光源でフレームあたり8ミリ秒を消費する場合、光源なしでは約8ミリ秒を消費します。
PSコミュニティの関心がある場合、私はそれを完成させてアセットストアに掲載します。
PPSが投稿されました。
ここにリンクがありますPPPSが無料でオープンソースになりました。
Github