问题描述
我有一个
[注释]
垂直线是由于在源纹理上未使用 GL_CLAMP_TO_EDGE
造成的。它可以通过在展台两侧使用1像素的纹理坐标范围进行修复,或者使用 GL_CLAMP_TO_EDGE
扩展名(如果有的话)。
怪异 atan()
操作数是向左旋转90度以匹配北方位角度为UP的结果。
I have a 360 texture in Equirectangular Projection.
With what GLSL shader can I convert it into a azimuthal equidistant projection?
See also:http://earth.nullschool.net/#current/wind/isobaric/500hPa/azimuthal_equidistant=24.64,98.15,169
I would do it in Fragment shader.
- bind Equirectangular texture as 2D texture
- bind projection shader
- draw Quad covering the screen or target texture
- store or use the result.
In Vertex shader I would:
Just pass the vertex coordinates as varying
to fragment shader (no point using matrices here you can directly use x,y coordinates in range <-1,+1>
)
In fragment shader I would:
- compute
azimuth
anddistance
of interpolatedvertex
from point(0,0)
(simplelength
andatan2
call) - then convert them to
(u,v)
coordinates of texture (just scale...) - and lastly render fragment with selected texel or throw it out if out of range ...
[edit1] just did bust a small example:
GL draw
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;
}
Fragment:
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;
}
Input texture:
Output render:
[notes]
The vertical line is caused by not using GL_CLAMP_TO_EDGE
on source texture. It can be repaired by using texture coordinates range shifted by 1 pixel on booth sides or use GL_CLAMP_TO_EDGE
extension if present.
Weird atan()
operands are result of rotating left by 90 degrees to match North azimuth to be UP.
这篇关于如何做着色器转换为azimuthal_equidistant的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!