I'd like to create a polar representation of this shader: https://www.shadertoy.com/view/4sfSDN
So that it looks like in this screenshot: http://postimg.org/image/uwc34jxxz/
I know the basics of the polar-system: How to calculate r and ϕ, but i can only use those values with a texture2d() load function on a image.
When i only have a amplitude value like in the shader above, i dont get it working.
r should somehow be based of the amplitude, but then i dont know how to draw the circle without the texture2d() function... i can draw a circle with r only, but then there are no different amplitudes. Or do i even need to fill a matrix with the generated bars in a loop and load the circle from there?
Im quite sure it is possible, because of the insane shaders on shadertoy, but i dont quite get it... Can anyone point me out to a solution?
答案 0 :(得分:0)
从你发布的着色器中我认为只需将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)
。要获得半径,您需要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);
}