Geometry 如何将着色器转换为等方位角

Geometry 如何将着色器转换为等方位角,geometry,glsl,projection,Geometry,Glsl,Projection,我有一个等矩形投影 我可以用什么样的GLSL着色器将其转换为图形 另见: 我会在片段着色器中执行此操作。 将等矩形纹理绑定为二维纹理 绑定投影着色器 绘制覆盖屏幕或目标纹理的四边形 存储或使用结果 在顶点着色器中,我会: varying vec2 pos; void main() { pos=gl_Vertex.xy; gl_Position=gl_Vertex; } uniform sampler2D txr; varying vec2 pos; void m

我有一个等矩形投影

我可以用什么样的GLSL着色器将其转换为图形

另见:

我会在片段着色器中执行此操作。

  • 将等矩形纹理绑定为二维纹理
  • 绑定投影着色器
  • 绘制覆盖屏幕或目标纹理的四边形
  • 存储或使用结果
  • 在顶点着色器中,我会:

    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;
        }
    
    只需将顶点坐标作为
    变量传递给片段着色器(此处没有使用矩阵的点,您可以直接使用范围
    中的x、y坐标)

    在片段着色器中,我会:

    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;
        }
    
  • 从点
    (0,0)
    计算插值
    顶点的
    方位角
    距离
    (简单
    长度
    atan2
    调用)
  • 然后将它们转换为纹理的坐标(仅缩放…)
  • 最后用选定的纹理渲染片段,如果超出范围则将其抛出
  • [edit1]只是举了一个小例子:

    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;
        }
    
    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);
    
    顶点:

    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;
        }
    
    片段:

    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;
        }
    
    统一采样器2d-txr;
    可变vec2位置;
    void main()
    {
    常量浮点pi2=6.283185307179586476925286766559;
    vec4c=vec4(0.0,0.0,0.0,1.0);
    vec2 uv;//纹理坐标=缩放球坐标
    浮点a,d;//方位角,距离
    d=长度(位置);
    
    if(dthanks!会试试这个,然后很快回来看看结果如何