Подтвердить что ты не робот

Какова точность высокоскоростных поплавков в GLSL ES 2.0 (для iPhone/iPod touch/iPad)?

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

4b9b3361

Ответ 1

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

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

предоставит вам диапазон и точность float highp.

Ответ 2

В диалоговом окне 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

Ответ 3

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

Как для int, так и для float, префиксы и диапазоны между фрагментами и вершинными шейдерами одинаковы.

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

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

PowerVR SGX543MP3 (iPhone 5):

  • Поплавки
    • Low: precision = 8, range = 0 to 0 (Не уверен, но я думаю, что это означает, что мы не можем ожидать, что lowp действительно сможет представить значение, достигающее точно 2 или -2, я действительно не знаю отличный способ проверить это, и мы не должны чрезмерно относиться к этим ограничениям, просто используйте 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 года).

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