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

glsl шейдер, discard внутри а снаружи if. Упрощение.

Страницы: 1 2 Следующая »
#0
0:07, 13 мая 2015

Шейдер в несколько проходов рисует текстурки uSourceImage. Проблема в том, что если в какой нибудь текстурке color.a==0 то все предыдущие проходы становятся gl_FragColor = 0.Чтобы сохранять предыдущие проходы(на канвасе) сделал discard для розового цвета. Как можно избавиться от if?

Спасибо.
 

precision mediump float;
uniform sampler2D uSourceImage;
uniform float u_opacity;
varying vec2 v_texCoords;
void main () { 
        vec4 color = texture2D(uSourceImage, v_texCoords);
        if(color.rgb==vec3(1.0,0.4,0.8))discard;
  gl_FragColor = vec4(color.rgb, u_opacity * color.a);
}
 


#1
0:09, 13 мая 2015

...от розового цвета можно вот так избавиться.

precision mediump float;
uniform sampler2D uSourceImage;
uniform float u_opacity;
varying vec2 v_texCoords;
void main () { 
  vec4 color = texture2D(uSourceImage, v_texCoords);
        if(color.a==0.0)discard;
        gl_FragColor = vec4(color.rgb, u_opacity * color.a);
}
#2
0:36, 13 мая 2015

Ну, отсекать пиксели с a==0 можно с помощью блендинга, тогда if и discard не нужны. Но чем тебе так if не понравился?

#3
0:42, 13 мая 2015

Да с блендингом тоже не могу толком разобраться. Делаю glblendEquation(FUNC_ADD); glblendFunc(SRC_ALPHA, DST_ALPHA); Но возникает следующий вопрос: как блендить несколько проходов так, что если последний с a = 1, не было эффекта смешивания с предыдущими?

#4
0:56, 13 мая 2015

Вот так,только в обратном порядке получается: glblendEquation(FUNC_ADD); glblendFunc(ONE_MINUS_DST_ALPHA, DST_ALPHA);

#5
2:19, 13 мая 2015

kipar
> Но чем тебе так if не понравился?
Ну, видимо динамический бранчинг в шейдере, да еще и на OpenGL ES, и судя по всему на iPhone (PowerVR GPU) - это совсем не гуд.

#6
8:40, 13 мая 2015

Sergio
Но мне сложно представить что блендинг может оказаться быстрее - ведь в этом случае ни один пиксель не отбрасывается, т.е. объём вычислений получается тот же.

#7
10:47, 13 мая 2015

Turbochist
Сделай 2 шейдера один с дискардом, другой без.
дискард очень сильно бьет по производительности Img PVR, а это овер 50% рынка мобильных гпу.

kipar
> Но мне сложно представить что блендинг может оказаться быстрее - ведь в этом
> случае ни один пиксель не отбрасывается, т.е. объём вычислений получается тот
> же.
Тут все дело в архитектуре гпу, если кратко - то из-за дискарда приходится делать write back в буфер глубины и это стопорит весь пайплайн

#8
10:53, 13 мая 2015

Я думал, что умножение быстрее, чем ветвление. И бутылочным горлышком может оказаться fillrate. Посему стоит смотреть, что будет дешевле в каждом конкретном случае.

#9
11:26, 13 мая 2015

Посмотрите пожалуйста, приготовил картинки.
Суть такова есть подложка с натянутой картой, ее видно бледноголубое, на нее накладывается текстура полученная в результате двух проходов первый для текстуры с большими прямоугольниками(на всю карту), и второй для небольшого прямоугольника в центре(внутри которого повернутый набок прямоугольник - картинка на фоне rgba = 0,0,0,0).
Алгоритм проходов такой:

    glclearColor(1.0, 1.0, 1.0, 0.0);
    glclear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT);
    glenable(BLEND);
    glblendEquation(FUNC_ADD);

    glblendFunc(ONE_MINUS_DST_ALPHA, DST_ALPHA);

    //пробегаем по заданным картинкам(у меня это одна с наклоненной внутри картой на фоне rgba=0,0,0,0 и та которая на весь экран)
    while (i--) {
  //в результате planetSegment получается текстура которую буду накладывать на карту
        planetSegment.drawImage(geoImagesArray[i]);
    }

    glDisable(gl.BLEND);

1.Без discard это выглядит так
без дискарда | glsl шейдер, discard внутри а снаружи if. Упрощение.
2. А вот discard для a=0
с дискардом | glsl шейдер, discard внутри а снаружи if. Упрощение.
3. Делаю полупрозрачной одну картинку, вторую делаю непрозрачной. В проходе непрозрачная рисуется последней Получается вот что:
норм1 | glsl шейдер, discard внутри а снаружи if. Упрощение.
4.Здесь все непрозрачные
норм2 | glsl шейдер, discard внутри а снаружи if. Упрощение.
5. Вот тут косяк, который не знаю как решить. полупрозрачная рисуется на непрозрачной, но видна карта подложки, так как будто бы обе полупрозрачные...а надо чтобы та что рисовалась перед полупрозрачной оставалась непрозрачной, т.е. подложки с картой не должно быть видно.
не норм | glsl шейдер, discard внутри а снаружи if. Упрощение.

Вот, если есть еще какие нибудь советы, буду рад. Спасибо.

#10
13:10, 13 мая 2015

Turbochist
А нельзя текстуру сделать ровную, а потом кодом квад повернуть на нужный угол?

#11
13:26, 13 мая 2015

Executor
Да, можно, так оно впрчем и работает, а квадратные снимки получаются в результате перепроецирования....и я не могу сейчас доказать не будет ли проекция неверно отображаться скажем ближе к полюсам...вобщем геодезическая проблема. Может и все нормально должно быть, но я этого не доказывал, поэтому предварительно перепроецирую и получаю в таком виде. Это уж точно работает. На самом деле можно эту задачу декалами решить, но я боюсь что скажет 1000 снимков будет накладно декалить. А создать в отдельном потоке общую картинку из 1000 проходов вполне реально.
Все таки это другой вопрос.
Хотелось бы разобраться с блендингом.

#12
16:01, 13 мая 2015

Turbochist
Discard сильно гасит производительность. AlphaBlend работает шустро, если большинство пикселей a=0 или a=1.

Можно без всего этого обойтись. Ты сразу все необходимые текстуры выставляй в шейдере (сейчас можно до 16). И смешивай их как хочешь.
Рисуешь это всё в RT один раз. Если больше 16, можно группировать.

#13
16:17, 13 мая 2015

Kroll
Кстати отличная идея с группировкой, я тоже так думаю. Но вот про блендинг пока я не могу решить эту проблему...

#14
17:41, 13 мая 2015

Я имею ввиду, что делать вообще без блендинга. Отрисовал всё непрозрачное в одну RT. Полупрозрачный слой в другую RT (того же размера).
Потом эти два слоя смешиваешь как хочешь в шейдере.

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

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