20

シェーダーを使用する OpenGL アプリケーションのソースを見ています。特定のシェーダーは次のようになります。

uniform float someConstantValue;
void main()
{
    // Use someConstantValue
}

ユニフォームはコードから一度設定され、アプリケーションの実行中に変更されることはありません。

someConstantValueas ではuniformなく as として宣言するのはどのような場合const floatですか?

編集: 明確にするために、定数値は物理定数です。

4

3 に答える 3

26

大きな理由:

エラー: ループ インデックスは非定数式と比較できません。

私が使用する場合

uniform float myfloat;
...
for (float i = 0.0; i < myfloat; i++)

myfloatではないため、エラーが発生constant expressionします。


ただし、これは完全に有効です。

const float myfloat = 10.0;
...
for (float i = 0.0; i < myfloat; i++)

なんで?

GLSL (および HLSL も) が GPU アセンブリ命令にコンパイルされると、ループは非常に冗長な (まだジャンプなどを使用して最適化されている) 方法で展開されます。つまり、myfloat値はコンパイル時にループを展開するために使用されます。その値が a の場合uniform(つまり、各レンダー呼び出しを変更できる場合)、そのループは実行時まで展開できません (GPU は、少なくとも WebGL では、そのような JustInTime コンパイルを行いません)。

于 2014-05-11T17:01:24.467 に答える
12

まず、uniform を使用する場合と定数を使用する場合のパフォーマンスの違いは、おそらく無視できる程度です。第二に、値が本質的に常に一定であるからといって、プログラム内で常に一定であることを望んでいるわけではありません。プログラマーは、物理的な値を微調整して、現実と一致しない場合でも、最も見栄えの良い結果を生成することがよくあります。たとえば、特定のタイプのゲームでは、ペースを速くするために重力による加速度が大きくなることがよくあります。

コードでユニフォームを設定する必要がない場合は、GLSL でデフォルト値を指定できます。

uniform float someConstantValue = 12.5;

そうは言っても、変更する価値がほとんどない pi のようなものに const を使用しない理由はありません....

于 2013-07-04T22:04:20.173 に答える
2

次の 2 つの理由が考えられます。

  1. 開発者は、いくつかのアプリケーションでシェーダーのライブラリを再利用します。そのため、開発者はアプリごとに各シェーダーをカスタマイズするのではなく、それらを一般的なものに保とうとします。

  2. 開発者は、この変数が後でユーザー制御の設定になると予想しています。したがって、それをユニフォームとして宣言することは、その次の機能の準備です.

私が開発者であり、上記のいずれにも当てはまらない場合は、代わりに「const」として宣言します。パフォーマンス上の利点が得られ、コードからユニフォームを設定する必要がないからです。

于 2013-07-01T10:50:54.030 に答える