ПрограммированиеФорумГрафика

Тупит GLSL на айфоне и айпаде, где искать источник проблемы?

Страницы: 1 2 Следующая »
#0
12:18, 30 апр 2016

Коротко: шейдер не работает, но если в конец шейдера добавить glFragColor.a += 0.001 то он внезапно работает (почти) правильно.

Причём вот так не работает:

uniform vec3 u_color;
...
float a = ...;
vec4 v = vec4( u_color, a + 0.0001 );
gl_FragColor = v;

А так - работает:

vec4 v = vec4( u_color, a );
gl_FragColor = v;
gl_FragColor.a += 0.0001;

Но это не все проблемы.
upd.: Вторая проблема уже решена, в коде где-то был вызов glDrawArrays с параметром count=0, из-за этого устройство Эппл немножко тупит. Убрал вызов, глюки прекратились. О второй проблеме:

При первом запуске рисуемый меш мелькает в разных частях экрана (цвет правильный, но в позициях вершин как будто мусор), в процессе работы рисуется другой меш (корректно), а потом снова первый (теперь уже корректно). И проблемы исчезает. Выглядит как что-то нециниализированное, но нет, всё инициализировано.

Стабильно воспроизводится только на айфоне и айпаде. ПК и разные Андроиды работают без проблем. Без += 0.0001 вообще ничего не отрисовывается, как будто полная прозрачность.

Ошибок и предупреждений при компиляции шейдера нет.
glGetError() пустой.
#version 100, пробовал и без версии.

Вот как такое ловить?

Полный код шейдеров. VS:

#ifdef GL_ES
  precision mediump float;
#endif

uniform mat4 u_proj;

uniform vec4 u_pos_modif;

attribute vec4 a_pos;
attribute vec4 a_uv;

varying vec4 v_uv;

void main() {
  
  gl_Position = ( a_pos + vec4(u_pos_modif.x, u_pos_modif.y, 0.0, 0.0) );
  
  gl_Position = u_proj * gl_Position;
  
  gl_Position = gl_Position  * vec4( u_pos_modif.z, u_pos_modif.z, 1.0, 1.0 ); /* scale */
  
  v_uv = a_uv;
}

FS:

#ifdef GL_ES
  precision mediump float;
#endif

uniform sampler2D u_sampler;
varying vec4 v_uv;

uniform vec4 u_pos_modif;
uniform vec3 u_color;

void main() {

  float a = texture2D(u_sampler, v_uv.st ).r * u_pos_modif.a;

    vec4 v = vec4( u_color, a );
    
    gl_FragColor = v;
  
  gl_FragColor.a += 0.0001;

}
#1
12:24, 30 апр 2016

впиши в outcolor.a единицу вот и все.
сдается что у тебя там ноль на выходе

#2
12:33, 30 апр 2016

barnes
Там не ноль, там данные с текстуры. Данные правильные, т.к. прибавление 0.0001 их почти не изменяет, а визуально видно, что они корректные.

#3
12:47, 30 апр 2016

я думаю стоит искать ошибку не в шейдере

#4
13:03, 30 апр 2016

вот вот, в альфу явно что-то не то падает

#5
13:34, 30 апр 2016

По поводу второй проблемы (мусор на экране) - обнаружил, что где-то вызывается glDrawArrays() с count=0. Если этот вызов убрать, то мусор пропадает. Можно сделать предварительный вывод, что именно glDrawArrays() с count=0 вызывает эти проблемы.

А странное поведение шейдера победить еще не удалось.

> вот вот, в альфу явно что-то не то падает
Как в неё может попадать не то, если прибавления 0.0001 я вижу правильную картинку? Ну, то есть, возможно где-то сработала неправильная оптимизация и без последней строчки в альфу каким-то образом попадает ноль. Вопрос - каким.

#6
13:47, 30 апр 2016

Роман Шувалов
используй glBlendFunc(GL_ONE, GL_ZERO), чтобы посмотреть, какой цвет действительно выдаёт шейдер, не учитывая блендинг.

#7
14:03, 30 апр 2016

Suslik
Попробовал. Цвет правильный (вижу тот, что указан в u_color).

Как будто "оптимизация" устанавливает альфу в 0.

#8
14:12, 30 апр 2016

А теперь почувствуйте силу магии.

Не работает:

gl_FragColor = vec4( u_color, a ); 

Не работает:

gl_FragColor = vec4( u_color, a + 0.0 ); 

Работает:

gl_FragColor = vec4( u_color, a ) + vec4(0.0, 0.0, 0.0, 0.0); 

(?!)

#9
14:12, 30 апр 2016

По поводу проблемы вроде ничего сразу на ум не приходит, а вот организация данных у тебя стремная.
Во первых: зачем ты хранишь альфу в u_pos_modif, а не в u_color? Тогда можно было бы сделать вот так:

gl_FragColor = u_color;
gl_FragColor.w *= texture2D(u_sampler, v_uv.st).x;

Во вторых, сделай v_uv vec2, зачем тебе еще и swizzle делать, если zw не используется (плюс, при mediump может немного медленнее работать, чем при highp).

#10
14:17, 30 апр 2016

Попробуй засунуть шейдер в PVRShaderEditor, и посмотреть во что превращается шейдер в разных вариантах.

#11
14:21, 30 апр 2016

Sergio
> Во первых: зачем ты хранишь альфу в u_pos_modif,
Потому что цвет выставляется 1 раз перед вызовом нескольких DrawCall'ов, а альфа вместе с другими компонентами pos_modif выставляется для каждого DrawCall'а индивидуально. Но в шейдере, конечно, было бы удобнее делать как ты сказал. Но тогда оба юниформ-вектора придется перед каждым DrawCall'ом устанавливать, с одними и теми же RGB компонентами каждый раз.

Sergio
> Во вторых, сделай v_uv vec2,
Да, это я уже заметил и сделал. Свиззла больше нет. ZW когда-то использовались для отладки, поэтому и был изначально vec4.

Sergio
> плюс, при mediump может немного медленнее работать, чем при highp
Серьезно? Я как-то проводил испытания. lowp тормозучий как слон. Разницу между mediump и highp точно не помню, но, кажется, highp работала медленнее на некоторых устройствах. Могу ошибаться. Возможна ли ситуация, чтобы highp работало медленнее, чем mediump? Речь сейчас не только про айфоны.

#12
14:26, 30 апр 2016

Роман Шувалов
> Возможна ли ситуация, чтобы highp работало медленнее, чем mediump? Речь сейчас
> не только про айфоны.
Да, возможно. Но swizzle на нем всегда работает быстрее

#13
14:27, 30 апр 2016

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

Supports PowerVR Series5, Series5XT and Series6 offline GLSL ES compilers

Посмотрим-с.

Коду, кстати, уже много лет, он был использован в нескольких проектах, в т.ч. в конкурсных. И тут внезапно на iOS вот такая хрень.

> Да, возможно. Но swizzle на нем всегда работает быстрее
Тогда от греха подальше избавлюсь от swizzle и оставлю mediump.

#14
14:34, 30 апр 2016

Не передаешь ли ты в альфу какой-нибудь nan или inf?

Страницы: 1 2 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.