Забудем про экран, в шейдере есть понятие полигон.
Если надо, чтобы эффект был на весь экран, просто растягиваем полигон на весь экран.
В пиксельном шейдере мы рисуем на полигоне, а не на экране, соответственно и координаты у нас в системе полигона, относительные (0-1), а не конкретные (0px-1280px).
У нас есть текущие x,y и текстура, которую нужно "закрутить".
Задача в том, чтоб вывести пикселы из текстуры, с
определённым смещением.
В обычном выводе мы просто пишем:
(Синтаксис утрирован)
буфер = текстура(v0.xy);
А надо:
буфер = текстура(спираль(v0.xy, strength));
То-есть, задача сводится к тому, что-бы просто написать формулу этой самой спирали, которая будет принимать x, y, strength и возвращать новые x, y. Повторю, диапазон значений xy от нуля до единицы.
Допустим, для волны мы бы могли использовать синус:

Код AS3:
function(x:Number, y:Number, strength:Number):Point {
return new Point(Math.sin(x * strength, y)); // Вертикальная волна с амплитудой длиною в текстуру.
}
Я специально написал на as3, чтоб понятнее было. Сперва создаёте формулу, отлаживаете, а потом переносите на agal.
При этом, знать о том, что там с экраном, какое у него разрешение и т.п. пиксельной программе не нужно.