Какова точность операций с плавающей запятой в GLSL ES 2.0 (для iPhone / iPod touch / iPad)? - PullRequest
29 голосов
/ 11 декабря 2010

У меня есть шейдер, которому в идеале нужно 28 бит мантиссы, хотя я могу использовать меньше и ухудшать производительность. Как я могу определить, какова точность highp в OpenGL ES? Вероятно, это FP24 с 16-битной мантиссой, но я не могу понять наверняка или как спросить OpenGL. Есть идеи?

Ответы [ 3 ]

32 голосов
/ 13 декабря 2010

Из справочника OpenGL ES Shading Language :

  • highp - 16-битный диапазон с плавающей запятой: -2 ^ 62 до 2 ^ 62, целочисленный диапазон: от -2 ^ 16 до 2 ^ 16
  • mediump - 10 бит, плавающий диапазон точек: от -2 ^ 14 до 2 ^ 14, целое число диапазон: от -2 ^ 10 до 2 ^ 10
  • lowp - 8 бит, диапазон с плавающей запятой: от -2 до 2, целочисленный диапазон: от -2 ^ 8 до 2 ^ 8
15 голосов
/ 05 января 2015

В моем тестировании на моей линии дорогих игрушек:

Как для чисел, так и для чисел с плавающей точкой, точность и диапазоны для фрагментных и вершинных шейдеров одинаковы.

Так что я не буду перечислять все комбинации исчерпывающе.

Также обратите внимание, что точность целых чисел всегда равна 0.

PowerVR SGX543MP3 (iPhone 5):

  • поплавки
    • Низкий: точность = 8, диапазон = от 0 до 0 (Не уверен, но я думаю, это означает, что мы не можем ожидать, что lowp действительно сможет представлять значение, достигающее точно 2 или -2, I на самом деле не знаю отличного способа проверить это, и при этом мы не должны чрезмерно беспокоиться об этих ограничениях, просто используйте mediump, когда это может быть проблемой)
    • Средний: точность = 10, диапазон от 15 до 15 (соответствует спецификации)
    • Высокий: точность = 23, диапазон от 127 до 127 (превышает спецификации)
  • Ints
    • Низкий: диапазон = от 23 до 23 (превышает спецификации)
    • Средний: диапазон от 23 до 23 (превышает спецификации)
    • Высокий: диапазон = от 23 до 23 (превышает спецификации)

A7 и PowerVR G6430 (iPad Air):

  • поплавки
    • Низкий: точность = 10, диапазон от 15 до 15 (превышает спецификации)
    • Средний: точность = 10, диапазон от 15 до 15 (соответствует спецификации)
    • Высокий: точность = 23, диапазон от 127 до 127 (превышает спецификации ES 2.0, соответствует спецификации 3.0)
  • Ints
    • Низкий: диапазон = от 15 до 14 (превышает спецификации)
    • Средний: диапазон от 15 до 14 (превышает спецификации ES 2.0, соответствует спецификации ES 3.0)
    • Высокий: диапазон = от 31 до 30 (превышает спецификации ES 2.0, соответствует спецификации ES 3.0)

A8 и PowerVR GX6450 (iPhone 6 Plus):

  • поплавки
    • Низкий: точность = 10, диапазон от 15 до 15 (превышает спецификации)
    • Средний: точность = 10, диапазон от 15 до 15 (соответствует спецификации)
    • Высокий: точность = 23, диапазон = 127 до 127 (превышает спецификации ES 2.0, соответствует спецификации 3.0)
  • Ints
    • Низкий: диапазон = от 15 до 14 (превышает спецификации)
    • Средний: диапазон от 15 до 14 (превышает спецификации ES 2.0, соответствует спецификации ES 3.0)
    • Высокий: диапазон = от 31 до 30 (превышает спецификации ES 2.0, соответствует спецификации ES 3.0)

Вот пример того, как вы можете запросить значения.

int range[2], precision;
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, &precision);
NSLog(@"Fragment shader high precision float range: %d %d precision: %d", range[0], range[1], precision);
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, range, &precision);
NSLog(@"Fragment shader medium precision float range: %d %d precision: %d", range[0], range[1], precision);
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_LOW_FLOAT, range, &precision);
NSLog(@"Fragment shader low precision float range: %d %d precision: %d", range[0], range[1], precision);

glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_INT, range, &precision);
NSLog(@"Fragment shader high precision int range: %d %d precision: %d", range[0], range[1], precision);
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_INT, range, &precision);
NSLog(@"Fragment shader medium precision int range: %d %d precision: %d", range[0], range[1], precision);
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_LOW_INT, range, &precision);
NSLog(@"Fragment shader low precision int range: %d %d precision: %d", range[0], range[1], precision);

glGetShaderPrecisionFormat(GL_VERTEX_SHADER, GL_HIGH_FLOAT, range, &precision);
NSLog(@"Vertex shader high precision float range: %d %d precision: %d", range[0], range[1], precision);
glGetShaderPrecisionFormat(GL_VERTEX_SHADER, GL_MEDIUM_FLOAT, range, &precision);
NSLog(@"Vertex shader medium precision float range: %d %d precision: %d", range[0], range[1], precision);
glGetShaderPrecisionFormat(GL_VERTEX_SHADER, GL_LOW_FLOAT, range, &precision);
NSLog(@"Vertex shader low precision float range: %d %d precision: %d", range[0], range[1], precision);

glGetShaderPrecisionFormat(GL_VERTEX_SHADER, GL_HIGH_INT, range, &precision);
NSLog(@"Vertex shader high precision int range: %d %d precision: %d", range[0], range[1], precision);
glGetShaderPrecisionFormat(GL_VERTEX_SHADER, GL_MEDIUM_INT, range, &precision);
NSLog(@"Vertex shader medium precision int range: %d %d precision: %d", range[0], range[1], precision);
glGetShaderPrecisionFormat(GL_VERTEX_SHADER, GL_LOW_INT, range, &precision);
NSLog(@"Vertex shader low precision int range: %d %d precision: %d", range[0], range[1], precision);

Мне пока не ясно, можно ли ожидать ощутимых улучшений производительности, выбрав тип с более низкой точностью (даже на некоторых телефонах, которым сейчас 3 года).

Очевидно, что существует тенденция к сближению с настольным оборудованием, поскольку видно, что последние графические процессоры полностью исключили 8-битные типы и перерабатывают mediump для lowp.

12 голосов
/ 11 декабря 2010

Вы хотите, чтобы GetShaderPrecisionFormat запрашивал диапазон и точность типов шейдеров

int range[2], precision;
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, &precision);

даст вам диапазон и точность хайп плавающего.

...