2015-10-08 3 views

ответ

1

Я хотел бы сделать это в пиксельный шейдер.

  1. связывают текстуры, как равные прямоугольники 2D текстуры
  2. проекции связывает шейдер
  3. дро Quad покрывать экран или целевую текстуре
  4. магазин или использовать результат.

В вершинном шейдере, я бы:

Просто передать координаты вершин, как varying в пиксельный шейдер (без точки с помощью матрицы здесь можно непосредственно использовать х, у координаты в диапазоне <-1,+1>)

В пиксельный шейдер я бы:

  1. вычислительном azimuth и distance интерполируемой vertex с точки (0,0) (простой length и atan2 вызова)
  2. затем преобразовать их в (u,v) координаты текстуры (только масштаб ...)
  3. и, наконец, вынести фрагмент с выбранным тексела или выбросить его, если из диапазона ...

[edit1] просто сделал бюст небольшой пример:

GL рисовать

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

GLint id; 
glUseProgram(prog_id); 
id=glGetUniformLocation(prog_id,"txr"); glUniform1i(id,0); 

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glMatrixMode(GL_TEXTURE); 
glLoadIdentity(); 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 

glDisable(GL_DEPTH_TEST); 
glEnable(GL_TEXTURE_2D); 
glBindTexture(GL_TEXTURE_2D,txrmap); 

glBegin(GL_QUADS); 
glColor3f(1,1,1); 
glVertex2f(-1.0,-1.0); 
glVertex2f(-1.0,+1.0); 
glVertex2f(+1.0,+1.0); 
glVertex2f(+1.0,-1.0); 
glEnd(); 
glDisable(GL_TEXTURE_2D); 
glBindTexture(GL_TEXTURE_2D,0); 

glUseProgram(0); 
glFlush(); 
SwapBuffers(hdc); 

Vertex:

varying vec2 pos; 
void main() 
    { 
    pos=gl_Vertex.xy; 
    gl_Position=gl_Vertex; 
    } 

Фрагмент:

uniform sampler2D txr; 
varying vec2 pos; 
void main() 
    { 
    const float pi2=6.283185307179586476925286766559; 
    vec4 c=vec4(0.0,0.0,0.0,1.0); 
    vec2 uv;  // texture coord = scaled spherical coordinates 
    float a,d;  // azimuth,distance 
    d=length(pos); 
    if (d<1.0)  // inside projected sphere surface 
     { 
     a=atan(-pos.x,pos.y); 
     if (a<0.0) a+=pi2; 
     if (a>pi2) a-=pi2; 
     uv.x=a/pi2; 
     uv.y=d; 
     c=texture2D(txr,uv); 
     } 
    gl_FragColor=c; 
    } 

Входной текстуры:

earth rectangular

Выход визуализации:

earth azimuthal equidistant

[ноты]

Вертикальная линия вызвана использованием GL_CLAMP_TO_EDGE на исходной текстуре. Его можно отремонтировать, используя диапазон координат текстур, сдвинутый на 1 пиксель на боковых сторонах, или используйте расширение GL_CLAMP_TO_EDGE, если оно присутствует.

Weird atan() Операнды являются результатом поворота налево на 90 градусов, чтобы соответствовать северному азимуту как UP.

+0

спасибо! попробуем это и вернемся, как это получилось достаточно скоро – zproxy

+0

работает! https://www.youtube.com/watch?v=jUqiRsRxWD8 – zproxy