Привет всем!
В пиксельном шейдере производится чтение из текстур огромнейшее количество раз... Естественно, это тормозит работу. Поэтому я решил производить эти операции не для каждого пикселя, а только для определенных. Но это ничуть не прибавляет FPS! Сейчас обрабатывается вместо 640x480 пикселей всего не больше 1000, а кадров больше ни на один не стало.
Это что ж получается, все пиксели обрабатываются параллельно? Тогда почему кол-во кадров увеличивается, если уменьшить размер текстуры?
З.Ы.
1. Отбор пикселей делаю с помощью трафарета - операция простая, тормозить не должна.
2. Это все отложенный шейдинг, поэтому сложность сцены не имеет никакого значения на этот этап рендеринга.
luckyleo769
Имей в виду, что пиксели читаются блоками. Читать 640x480 пикселей в 1000 блоках и 1000 пикселей в 1000 блоках будет одинаково по скорости.
-Eugene-
> Имей в виду, что пиксели читаются блоками.
Где об этом по подробней почитать можно? Как именно это происходит и способы оптимизации
luckyleo769
> Как именно это происходит
Что значит как? Берется блок текстуры, 4х4 или какой-то там еще, и читается.
> способы оптимизации
Оптимизации чего? Чтения из текстуры? Сделать текстуру по-меньше, читать данные, лежащие рядом.
вот поэтому различные условия в шейдере это зло еще то, т.к. обработка идет блоками.
конкретно напиши, где и как ты скипаешь пиксели
luckyleo769
> 1. Отбор пикселей делаю с помощью трафарета - операция простая, тормозить не
> должна.
Пиксели обрабатываются блоками 8х8, 16х16, 32х32 и т.п., поэтому если ты внутри блока скипаешь пиксели — конвейер все равно считает их все.
Для того, чтобы стало хорошо, тебе надо преобразовать (расслоить) G-buffer следующим образом: все нечетные строки оставить на верху, все четные — внизу (или иным аналогичным образом).
Выполняешь над ним необходимые операции, а затем делаешь обратное преобразование.
Mephisto std
> конкретно напиши, где и как ты скипаешь пиксели
приведу псевдокод
float4 PS(input) { if (stencil.Sample(samp, input.uv) == 0) return 0; float4 result = 0; for (int i = 0; i < ...; i++) { ... result += ...; } return result; }
В общих чертах так выглядит код. Смысл в том, что благодаря первой строке функции этот шейдер обрабатывает на порядок меньше пикселей, но процесс не ускоряется.
luckyleo769
> ысл в том, что благодаря первой строке функции этот шейдер обрабатывает на
> порядок меньше пикселей,
Только если все пиксели в блоке пропущены.
Тьфу, я то думал ты через стенсиль нормально делаешь, а ты в шейдере его сэмплишь.
-Eugene-
да это экспериментирую. вообще желательно, конечно, чтобы все пиксели были задействованы. это так жест отчаяния
-Eugene-
Кстати оффтопный вопрос, чтоб форум не засорять. Сообразить не могу, как быстрее будет?
Так:
for (int y = 0; y < resy; y++) for (int x = 0; y < resx; x++) { ... }
Или так:
for (int i = 0; i < resy * resx; i++) { y = i / resx; x = i % resx; ... }
тебе надо рендерить в меньшем разрешении, а потом растягивать текстуру.
rendering in down sample
upsample ( resize)
luckyleo769
> 640x480
очень маленькое разрешение, сколько у тебя фпс и на какой видеокарте? Может не стоит экономить на спичках?
luckyleo769
1) integer операции на GPU могут быть медленными. Лучше всегда использовать uint.
> if (stencil.Sample(samp, input.uv) == 0) return 0;
попробуй так:
if (...)
discard;
{
...
}
или так:
[branch] if ()
{
...
}
else
{
...
}
luckyleo769
> Сообразить не могу, как быстрее будет?
Те же яйца. Черт знает, тестить надо. 95%, что одинаково.
MAMOHT-92
Кадров 6-7. Видеокарта - одно название Radeon 6470m - на ноуте. Без этого шейдера в 28-32
Тема в архиве.