2017-12-05 7 views
2

私は自分のシーンに複数の光源を置きたいと思っています。基本的な考え方は、位置、色、方向、カットオフ、必要なw/eなど気にする光のすべてのプロパティを持つ(均一な)構造体の配列を単純に持つことです。私の問題は、どのライトをオン/オフにするかを表現する方法です。私が考えることができるすべての方法を列挙します。 P1OpenGLで光源の状態を表現するには

  • ライトの構造が一意になっていて、オン/オフを示すことができます。
  • 光の構造体の数が2、3、または4の倍数に一致するようにして、多くのブールベクトルを使用してその状態を示すことができます。たとえば、16ライト= 4x4 bvec4。
  • 代わりに多くのフラグや枝を使用するのではなく、常にすべての単一の光によって私はのように最後のオプションに傾いてる色

のために(0,0,0,0)に設定し、オフのものと一緒に行きますそれは分岐を持っていません...しかし、私はすでに、現代のグラフィックスカードがより分岐していることを読んでいます。

答えて

2

どの光源がアクティブで、どれがアクティブでないかをシェーダが評価する必要があるため、あなたのアイデアは本当に良いものではありません。また、シーン情報(シーン内にあるライト)とレンダリングに必要なデータ(シーン上のライトが点灯している)を区別する必要があります。シーン情報は不要であり、シェーダの速度を遅くするだけなので、シェーダに格納しないでください。

次のようになることができる唯一の有効なものとのシーンで複数の光源を処理し、レンダリングのためのより良い方法:

  • はライトがオンになっているCPU側の評価:すべてのフレームで

    を。アクティブなライトの合計数とともにシェーダユニフォームに入っているライトだけを渡します。擬似コードで:

    シェーダ:

    uniform lightsources active_lightsources[MAX_LIGHTS]; 
    uniform int light_count; 
    

    CPU:

    i = 0 
    foreach (light in lightsources) 
    { 
        if (light.state == ON) 
        { 
         set_uniform("active_lightsources[i]", light); 
         i++ 
        } 
    } 
    set_uniform("light_count", i); 
    
  • 断片を照明シェーダに次の操作を行い

    シェーダ:

    for (int i = 0; i < light_count; i++) 
    { 
        //Calculate illumination from active_lightsources[i] 
    } 
    

このアプローチの主な利点は、シェーダ内に少ないライトを格納し、シェーダ内のループが現在のフレームに関連する光源だけをループすることです。ライトが関係する評価は、シェーダの頂点/フラグメントごとに1回ではなく、CPU上でフレームごとに1回実行されます。

+0

シェーダで動的変数をループすることはできないと思っていましたが、分岐は高価ですか? – ChaoSXDemon

+0

light_countは動的変数ではありません。 glsl 120では、すでにユニフォームのルーピングが可能でした。現在では、ダイナミック式をループすることも問題ありません。ブランチングは高価になる可能性がありますが、均一な条件ではそれほど多くはありません。しかし、提案されたGPUコードには分岐がなく、分岐はCPUコードで発生します。 – BDL

+0

一般的なアドバイスは次のとおりです。シェーダの呼び出し前に事前に計算できるものは決してシェーダで計算しないでください。 – BDL

関連する問題