我正在使用OpenGL编写2D游戏,我计划了一个阴影投射算法,需要将纹理从极坐标转换为直角坐标。期望的效果如下:
由此:
对此:
我知道在Polar和Rectangular系统之间转换坐标的公式,但我在编写着色器时遇到了问题,以达到预期的效果。
我的着色器接收纹理作为输入,并应将扭曲的纹理绘制到屏幕上。我计划了以下内容(知道片段着色器一次对一个片段起作用):
我的最终结果是顺时针旋转90度的相同输入纹理。我认为我在步骤3中遗漏了一些东西。我可能只是得到当前片段的相同x和y,因为我只是使用变换和逆变换公式。 我该如何进行预期的结果?
这是我的着色器:
#version 120
uniform sampler2D tex;
void main() {
vec2 fragCoords = gl_FragCoord.xy - vec2(128, 128); //shift the coordinates so that 0, 0 is in the center of the screen (the final texture is 256 * 256)
fragCoords /= vec2(256, 256);
float r = sqrt(pow(fragCoords.x, 2) + pow(fragCoords.y, 2));
float theta = atan(fragCoords.y, fragCoords.x);
if (fragCoords.y/fragCoords.x <= 0.5 && fragCoords.y/fragCoords.x >= -0.5) {
r *= 1/(256*sin(theta));
} else {
r *= 1/(0.5*256*cos(theta));
}
vec2 texCoords = vec2(r, theta);
vec4 texFrag = texture2D(tex, texCoords);
gl_FragColor = texFrag * vec4(1.0, 0.0, 0.0, 1.0);
}
答案 0 :(得分:1)
在着色器中,您首先要转换为极坐标
float r = sqrt(pow(fragCoords.x, 2) + pow(fragCoords.y, 2));
float theta = atan(fragCoords.y, fragCoords.x);
然后你不会把它们翻译成笛卡儿式的
float tX = r * sin(theta);
float tY = r * cos(theta);
您希望保持极坐标,只需将r
和theta
插入纹理坐标
vec2 texCoords = vec2(r , theta);
vec4 texFrag = texture2D(tex, texCoords);
然而,通过您粘贴的图像的外观,涉及一些重整化步骤,因此(r, theta)
将覆盖矩形区域。如果我没有完全弄错的话,那么r将通过从中心底部射出的光线与矩形区域相交的距离来缩放。如果我们假设theta = 0是直线上升,则对于[-atan(0.5)... atan(0.5)]范围,它按1 /(height * sin(theta))缩放,在该范围外缩小1 /(0.5 *宽度* COS(THETA))