Opengl es GLSL着色器:极坐标中的贴图栏
我想创建此着色器的极轴表示: 所以在这个截图中看起来像: 我知道极坐标系的基本知识:如何计算r和ψ,但我只能在图像上使用texture2d()加载函数来使用这些值 当我只有一个振幅值,就像上面的着色器一样,我无法让它工作 r应该以振幅为基础,但是如果没有texture2d()函数,我不知道如何画圆。。。我只能用r画一个圆,但是没有不同的振幅。或者我甚至需要用循环中生成的条填充矩阵,然后从那里加载循环 我很确定这是可能的,因为shadertoy上有疯狂的着色器,但我不太明白。。。Opengl es GLSL着色器:极坐标中的贴图栏,opengl-es,fragment-shader,polar-coordinates,Opengl Es,Fragment Shader,Polar Coordinates,我想创建此着色器的极轴表示: 所以在这个截图中看起来像: 我知道极坐标系的基本知识:如何计算r和ψ,但我只能在图像上使用texture2d()加载函数来使用这些值 当我只有一个振幅值,就像上面的着色器一样,我无法让它工作 r应该以振幅为基础,但是如果没有texture2d()函数,我不知道如何画圆。。。我只能用r画一个圆,但是没有不同的振幅。或者我甚至需要用循环中生成的条填充矩阵,然后从那里加载循环 我很确定这是可能的,因为shadertoy上有疯狂的着色器,但我不太明白。。。 有人能给我指出
有人能给我指出一个解决方案吗?从你发布的着色器中,我认为它应该足以简单地将
uv
转换为极坐标
所以你要找的是从中心开始的角度和半径。首先,让我们变换uv
,使其给出从中心指向的向量:
uv = fragCoord - (iResolution*.5);
接下来,尝试将其正常化。由于视图不是正方形,因此规格化变换应仅为1个坐标,以便
if(iResolution.x>iResolution.y)
{
uv = uv/iResolution.y;
}
else
{
uv = uv/iResolution.x;
}
这将产生一种适合的效果,但如果需要,您可以硬编码其中一种min
如果可用(uv=uv/min(iResolution.x,iResolution.y))
可用于删除该条件
因此在这一点上,uv
矢量从中心指向一维标准化坐标系中的像素位置
现在只需使用atan(uv.y、uv.x)即可获得角度。要获得半径,则需要长度(uv)
在您的例子中,半径将用于范围[0.5]中较短的尺寸,因此您可以将其乘以2.0,但这是一个系数,您可以稍后更改以获得所需的效果,以便最大值不会碰到边界,但可能有80%左右(只需使用它)
角度在[-Pi,Pi]加上的范围内,在文档中,它表示它不适用于X=0
,此时您需要自行处理。因此,现在必须将角度变换为范围[.0,1.0]才能访问纹理坐标:
angle = angle/(Pi*2.0) + .5
因此,现在构建新的uv
uv = vec2(angle, radius)
并使用与以前相同的着色器
您还需要记住,拐角处的半径可能大于1.0,这可能会产生错误的纹理访问。在这种情况下,最好丢弃片段
从着色器玩具:
#define M_PI 3.1415926535897932384626433832795
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy - (iResolution.xy*.5);
uv = uv/min(iResolution.x, iResolution.y);
float angle = atan(uv.y, uv.x);
angle = angle/(M_PI*2.0) + .5;
float radius = length(uv);
uv = vec2(angle, radius*2.0);
float bars = 24.;
float fft = texture2D( iChannel0, vec2(floor(uv.x*bars)/bars,0.25) ).x;
float amp = (fft - uv.y)*100.;
fragColor = vec4(amp,0.,0.,1.0);
}
非常感谢,这成功了!美好的但我必须使用“angle=angle/(Pi*2.0)+0.5”(而不是1.0)将角度值映射到[0.0-1.0]。。。是这样吗?我用jfiddle检查了这些值:是的,你是对的。我在脑子里写的时候犯了一个错误。让我来解决这个问题。在frag颜色行之前添加if(ceil(uv.xbar)-uv.xbar<.1)amp=.0;