2014-09-19 8 views
3

Мне нужно преобразовать текстуру прямоугольника в текстуру с полярными координатами. Для того, чтобы распространить свет на мою проблему, я собираюсь проиллюстрировать:GLSL ES - Отображение текстуры от прямоугольных до полярных координат с повторением

У меня есть образ: original image

, и я должен деформировать его, используя шейдер что-то вроде этого: result

затем Я собираюсь отобразить его в самолете. Как я могу это сделать? Любая помощь будет оценена!

ответ

3

Это не особо сложно. Вам просто нужно преобразовать координаты текстуры в полярные координаты и использовать радиус для направления текстуры s и азимутальный угол в направлении t.

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

Итак, в фрагментном шейдере вам просто нужно преобразовать интерполированные texcoords (используя для этого tc) в полярные координаты. SInce центр будет в (0,5, 0,5), мы должны сначала компенсировать это.

vec2 x=tc - vec2(0.5,0.5); 
float radius=length(x); 
float angle=atan(x.y, x.x); 

Теперь все, что вам нужно сделать, это отобразить диапазон обратно в [0,1] пространство текстур. Максимальный радиус здесь будет 0,5, поэтому вы просто можете использовать 2*radius как координату s, а угол будет в [-pi, pi], поэтому вы должны сопоставить это значение с [0,1] для координаты t.

Update1

Есть несколько деталей, я оставил так далеко. Из вашего изображения ясно, что вы не хотите, чтобы внутренний круг отображался на текстуру. Но это легко может быть отменено. Я просто предполагаю здесь два радиуса: r_inner, который является радиусом внутреннего круга, и r_outer, который является радиусом, на который вы хотите отобразить внешнюю часть. Позвольте мне набросать простой фрагментный шейдер для этого:

#version ... 
precision ... 

varying vec2 tc; // texcoords from vertex shader 
uniform sampler2D tex; 

#define PI 3.14159265358979323844 

void main() 
{ 
    const float r_inner=0.25; 
    const float t_outer=0.5; 

    vec2 x = v_tex - vec2(0.5); 
    float radius = length(x); 
    float angle = atan(x.y, x.x); 

    vec2 tc_polar; // the new polar texcoords 
    // map radius so that for r=r_inner -> 0 and r=r_outer -> 1 
    tc_polar.s = (radius - r_inner)/(r_outer - r_inner); 

    // map angle from [-PI,PI] to [0,1] 
    tc_polar.t = angle * 0.5/PI + 0.5; 

    // texture mapping 
    gl_FragColor = texture2D(tex, tc_polar); 
} 

Теперь все еще отсутствует одна деталь. Сгенерированное отображение генерирует texcords, которые находятся вне диапазона [0,1] для любой позиции, где у вас есть balck на вашем изображении. Но выборка текстуры не будет автоматически давать черный здесь. Самое простое решение - добавить черный пиксель на левом и правом конце текстуры и установить режим текстуры GL_TEXTURE_WRAP_S на GL_CLAMP_TO_EDGE. Таким образом, вы получите черный цвет почти бесплатно. Другим способом было бы добавить плечо в шейдер и проверить, что tc_polar.s находится ниже 0 или выше 1.

+0

Не могли бы вы предоставить полный код шейдера? – Nolesh

+0

@ Nolesh: Я обновил свой ответ. – derhass

+0

Знаете ли вы, как изменить этот шейдер, чтобы сделать результат из сегментов? Поэтому мне нужно повторить данную текстуру, а не растягиваться. – Nolesh

0

Я нашел расширенную версию шейдера выше: polarpixellate glsl. Эта статья для тех, кто хочет более гибкого шейдера.

 Смежные вопросы

  • Нет связанных вопросов^_^