This is the documentation for Enlighten.

7.7. カスタムの直接光


Enlighten には、以下の標準のライト タイプが含まれています。

タイプ

説明

Directional

フォールオフのない、無限遠の光源です。

Spotlight

球状フォールオフを持つ点光源で、円錐状の光を発します。 

Point

球状フォールオフを持つ点光源で、全方向に光を発します。

Rectangle

長方形のエリア ライトです。

Box Spotlight

球状フォールオフを持つ点光源で、四角錐状の光を発します。

Frustum

平行なフォールオフを持つ点光源で、錐台状の光を発します。

非物理フォールオフ モデルを使用するエンジンの場合、これらのライト タイプを1047232826とともに使用してください。

大きく異なる光線形状を持つ光源の場合、1047232826を実装します。

カスタム ライト フォールオフ

Enlighten は、シーンで間接光をバウンスするために物理的に実現可能 (調整可能なアルベドおよびバウンス スケール値の対象) なアルゴリズムを使用していますが、直接光モデルについては特定の推定を行いません。実際には、スポット ライトとポイント ライトに非物理フォールオフ モデルを使用することが便利な場合が多くあります。扱いが比較的簡単で、アーティファクトを減らすことができ、出力表示の制限がある場合には、想定する効果を得られる唯一の方法になります。そのため、Enlighten では Enlighten::InputLightFalloffTable を使用したポイント ライトおよびスポット ライト向けのカスタム距離のフォールオフの指定が可能になっています。

直接の画面上のライティングに使用されるモデルと、Enlighten で入力ライティングを作成するためのモデルの間に完全な対応関係は必要ありません。モデルの対応関係が近ければ近いほど、全体としてライティング モデルの自己整合性が上がります。一方、Enlighten の入力ライティングが完全な非物理モデルを使用する場合、直感に反した効果が生成される場合があります。たとえば、一定の強度の光源がジオメトリに近づく、または離れるにつれて、シーンの光の量が大きく変化する場合があります。モデルが非物理であるため、エネルギーが保持されるとは限らないからです。

Enlighten は適切なフォールオフ テーブルを生成するための 2 つの API 関数を提供しています。Enlighten::GenerateUnrealCompatibleLightFalloffTable and Enlighten::GenerateInverseSquaredLightFalloffTable.また、Enlighten::InputLight クラスもご覧ください。

カスタム ライト タイプ

カスタム ライト タイプを追加するには、まず EnlightenLights.heLightType 列挙体を変更します。

//Begin Customer Light types//End Customer Light types の間にカスタム ライト タイプの列挙体を挿入します。

以下の例は、LIGHT_TYPE_CUSTOM_LIGHT_TYPE を追加する変更を示しています。

EnlightenLights.h のライト タイプ列挙体
//--------------------------------------------------------------------------------------------------
/// Enlighten 入力ライトのさまざまなタイプ
enum eLightType
{
    LIGHT_TYPE_INVALID              = -1,   ///< 無効なライト タイプ
    LIGHT_TYPE_SPOT_LIGHT           = 0,    ///< スポット ライト
    LIGHT_TYPE_POINT_LIGHT          = 1,    ///< ポイント ライト
    LIGHT_TYPE_DIRECTIONAL_LIGHT    = 2,    ///< ディレクショナル ライト
    LIGHT_TYPE_RECTANGLE_LIGHT      = 3,    ///< 長方形のエリア ライト (PC でのみ利用可能)
    LIGHT_TYPE_FRUSTUM_LIGHT        = 4,    ///< 錐台ライト
    LIGHT_TYPE_BOXSPOT_LIGHT        = 5,    ///< ボックススポット ライト 
 
#if defined(GEO_FEATURE_EXTENDED_INPUT_LIGHTING)
    // Begin Customer Light types
    LIGHT_TYPE_CUSTOM_LIGHT_TYPE,
    // End Customer Light types 
 
    LIGHT_TYPE_NUM_TYPES //これは enum の最後の入力である必要があります
#endif //defined(GEO_FEATURE_EXTENDED_INPUT_LIGHTING)
};

次に、InputLightBaseから派生するライト クラスを作成します。以下の例は、必要なメンバーを示しています。

カスタム ライト クラス テンプレート
class CustomLightType : public Enlighten::InputLightBase
{
public:
    CustomLightType()
        : InputLightBase(LIGHT_TYPE_CUSTOM_LIGHT_TYPE)
    {
    };
 
    //デストラクタを追加します
    ~CustomLightType() {}
 
    //..ここにライト メンバー データを追加します 
 
    //..ここに CachedData というクラスを追加します。これがすべての処理を行う主要なオブジェクトです。
    // 入力ライティング フレームワークは、DoDirectInputLighting() 関数パラメーターに渡されるライト ポインターから
    // この CachedData オブジェクトを自動的に生成します。
    struct CachedData : public Enlighten::InputLightBase
    {
        //メイン ライト タイプを唯一のパラメーターとして取るコンストラクターを追加します
        CachedData(CustomLightType& srcLight, void* visibilityPointer)
            : InputLightBase(LIGHT_TYPE_CUSTOM_LIGHT_TYPE)
        {
            // シェード関数に必要なデータをすべてキャッシュします
        }
 
        //パフォーマンスを最大にするため、最適化されたデータを含むメンバーをここに追加します。 
 
        //===================================================
        // 以下のシグネチャのメンバー関数を追加します
        //===================================================
 
        //法線を共有する 4 つのポイントをシェーディングする関数です。quad idx と cluster idx は、可視性バッファで可視性を調べるために使用できます。
        GEO_FORCE_INLINE Geo::v128 ShadeQuad(const Geo::v128& positionsX,
            const Geo::v128& positionY,
            const Geo::v128& positionZ,
            const Geo::v128& normal,
            Geo::u32 clusterIdx,
            Geo::u32 quadIdx) const
        {
        }
 
        //ライトがシステムのバウンディング ボックスと交差するかどうかをテストします
        GEO_FORCE_INLINE bool   IsIntersectingSystem(const Geo::v128& bbMin, const Geo::v128& bbMax) const
        {
            return true;
        }
 
        //ライトがクラスタのグループのバウンディング ボックスと交差するかどうかテストします。追加の法線ベクトルにより、方向に対するカリングが可能になります。
        GEO_FORCE_INLINE bool   IsIntersectingClusterGroup(const Geo::v128& bbMin, const Geo::v128& bbMax, const Geo::v128& minNormalFlipped, const Geo::v128& maxNormalFlipped) const
        {
            return true;
        }
 
        //ライトが単一のクラスタと交差するかどうかをテストします。追加の法線ベクトルにより、方向に対するカリングが可能になります。
        GEO_FORCE_INLINE bool   IsIntersectingCluster(const Geo::v128& bbMin, const Geo::v128& bbMax, const Geo::v128& minNormalFlipped, const Geo::v128& maxNormalFlipped) const
        {
            return true;
        }
 
        //ライト データをハッシュ化します
        void Hash(Helpers::Hasher &hash, Geo::u32 clusterVisSize, Geo::u32 quadVisSize)
        {
        }
    };
};

その他の例については、PointLight.h、Spotlight.h、DirectionalLight.h をご覧ください。

Enlighten が新しいライト タイプを使えるようにするためには、CustomLightType の宣言の直後に LIGHT_TYPE_CUSTOM_LIGHT_TYPE から CustomLightType クラスへのマッピングを追加します。

カスタム ライト タイプ を Enlighten で使用可能にする
template<>
struct TypeIdToType<LIGHT_TYPE_CUSTOM_LIGHT_TYPE>
{
    typedef CustomLightType Type;
};