Из опубликованного вами шейдера я думаю, что должно быть достаточно просто преобразовать uv
в полярные координаты.
Итак, что вы ищете, это угол и радиус от центра. Сначала давайте преобразуем uv
, чтобы он давал вектор, указывающий из центра:
uv = fragCoord - (iResolution*.5);
Затем попытайтесь нормализовать его. Поскольку вид не квадратный, преобразование нормализации должно быть только по 1 координате, так что
if(iResolution.x>iResolution.y)
{
uv = uv/iResolution.y;
}
else
{
uv = uv/iResolution.x;
}
Это создаст эффект подгонки, но вы можете просто жестко запрограммировать одно или другое, если вам нужно. min
можно использовать, если доступно (uv = uv/min(iResolution.x, iResolution.y))
), чтобы удалить условие.
Таким образом, в этой точке вектор uv
указывает от центра к положению пикселя в системе координат, нормализованной в одном измерении.
Теперь, чтобы получить угол, вы можете просто использовать atan(uv.y, uv.x)
. Чтобы получить радиус, вам нужно length(uv)
.
Радиус в вашем случае будет для более короткого размера в диапазоне [0, .5], поэтому вы можете умножить его на 2,0, но это фактор, который вы можете позже изменить, чтобы получить желаемый эффект, чтобы максимальное значение не достигало границы но, может быть, 80% или около того (просто поиграйте с этим).
Угол находится в диапазоне [-Pi, Pi], плюс в документах говорится, что он не работает для X = 0
, с которым вам нужно будет справиться самостоятельно. Итак, теперь угол должен быть преобразован в диапазон [.0, 1.0], чтобы получить доступ к координате текстуры:
angle = angle/(Pi*2.0) + .5
Итак, теперь создайте новый uv
uv = vec2(angle, radius)
И используйте тот же шейдер, что и раньше.
Вы также должны иметь в виду, что радиус может быть больше 1,0 в углах, что может привести к неправильному доступу к текстуре. В таких случаях лучше всего отказаться от фрагмента.
Из шейдерной игрушки:
#define M_PI 3.1415926535897932384626433832795
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy - (iResolution.xy*.5);
uv = uv/min(iResolution.x, iResolution.y);
float angle = atan(uv.y, uv.x);
angle = angle/(M_PI*2.0) + .5;
float radius = length(uv);
uv = vec2(angle, radius*2.0);
float bars = 24.;
float fft = texture2D( iChannel0, vec2(floor(uv.x*bars)/bars,0.25) ).x;
float amp = (fft - uv.y)*100.;
fragColor = vec4(amp,0.,0.,1.0);
}
person
Matic Oblak
schedule
02.09.2015