В OpenGL ES 2.0 / GLSL, где вам нужны спецификаторы точности? - PullRequest
48 голосов
/ 20 марта 2011

Указывает ли переменная, в которую вы вводите значения, с какой точностью вы работаете, справа от знака равенства?

Например, есть ли какое-либо различие в значении спецификатора точности здесь:

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)

Я знаю, что вы можете определить точность по умолчанию для числа с плавающей запятой, и что это предположительно используется для векторов и матриц впоследствии. Предположим для целей образования, что мы определили это ранее:

precision highp float;

1 Ответ

71 голосов
/ 14 июня 2011
  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;
    

    Это означает, что если вы объявляете float в фрагментном шейдере, вы должны указать, является ли он 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

...