GLSL 着色器:极坐标中的映射条

GLSL Shader: Mapping Bars in Polar-Coordinates

我想创建此着色器的极坐标表示:https://www.shadertoy.com/view/4sfSDN

所以它看起来像这个截图: http://postimg.org/image/uwc34jxxz/

我知道极坐标系的基础知识:如何计算 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;
}

这会产生一种适合的效果,但如果需要,您可以硬编码一个或另一个。如果可用 (uv = uv/min(iResolution.x, iResolution.y))),可以使用 min 来删除条件。

所以此时 uv 向量从中心指向在一维归一化的坐标系中的像素位置。

现在要获得角度,您可以简单地使用 atan(uv.y, uv.x)。要获得半径,您需要 length(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);
}