У меня есть шейдер, который идеально нуждается в 28 бит мантиссы, хотя я могу использовать меньше и ухудшать производительность. Как определить, какая точность "highp" находится в OpenGL ES? Вероятно, это FP24 с 16-битной мантиссой, но я не могу точно определить, как спросить OpenGL. Любые идеи?
Какова точность высокоскоростных поплавков в GLSL ES 2.0 (для iPhone/iPod touch/iPad)?
Ответ 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 (превышает спецификацию)
- Low: precision = 8, range = 0 to 0 (Не уверен, но я думаю, что это означает, что мы не можем ожидать, что
- 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
.