web-dev-qa-db-ja.com

OpenGL ES 2.0 / GLSLでは、精度指定子はどこで必要ですか?

値を詰め込んでいる変数は、等号の右側で、使用している精度を決定しますか?

たとえば、次の精度指定子には意味の違いがありますか?

gl_FragColor = lowp vec4(1);

別の例を次に示します。

lowp float floaty = 1. * 2.;
floaty = lowp 1. * lowp 2.;

そして、いくつかの浮動小数点数を取得し、それらからベクトルまたは行列を作成する場合、そのベクトルまたは行列は、それを詰め込んだ値の精度を引き継ぐか、それらの値は別の精度レベルに変換されますか?

これを最適化すると、質問に最もよく答えると思います:

dot(gl_LightSource[0].position.xyz, gl_NormalMatrix * gl_Normal)

つまり、可能な限り高速にしたい場合はここまで行く必要がありますか、それとも役に立たないのですか?

lowp dot(lowp gl_LightSource[0].position.xyz, lowp gl_NormalMatrix * lowp gl_Normal)

Floatのデフォルトの精度を定義できること、そしてこれは後でベクトルと行列に使用されると思われます。教育を目的として、これを以前に定義したと仮定します。

precision highp float;
48
Jessy
  1. 定数/リテラル​​の精度指定子は必要ありません。なぜなら、それらは割り当てられているものに対してコンパイル時間を評価されるからです。さらに、gl_FragColorの精度はレンダーターゲットの深さに基づいて既に定義されているため、それに割り当てる精度は重要ではありません。

  2. 頂点シェーダーでは、デフォルトで次の精度が宣言されています:(4.5.3 Default Precision Qualifiers

    precision highp float;
    precision highp int;
    precision lowp sampler2D;
    precision lowp samplerCube;
    

    フラグメントシェーダーでは次のようになります。

    precision mediump int;
    precision lowp sampler2D;
    precision lowp samplerCube;
    

    これは、フラグメントシェーダーでフロートを宣言する場合、lowpまたはmediumpであるかどうかを言う必要があることを意味します。デフォルトのfloat/int精度も行列/ベクトルに拡張されます。

  3. highpは、GL_FRAGMENT_PRECISION_HIGHマクロが1に定義されているシステムでのみサポートされます。残りの部分では、コンパイラエラーが発生します。 (4.5.4 Available Precision Qualifiers

  4. 式の精度の規則は、バインドされている割り当て/パラメーターの型に自動的にキャストされることです。したがって、ドットについては、デフォルトで入力タイプの精度が使用され、追加のlowpは不要です(および構文的に正しくありません)。型をより低い精度にダウンキャストする場合、それを行う唯一の方法は、明示的により低い精度に割り当てることです。

これらの答えはすべてKhronos GLSL仕様からのもので、こちらで見つけることができます(関連セクションは4.5.2および4.5.3です): http://www.khronos.org/registry/gles/specs/2.0/ GLSL_ES_Specification_1.0.17.pdf

71
Mikola