WebGL inverse FFT implementation



我正在尝试使用Fragment着色器在WebGL中实现FFT和相关的逆FFT。我正在使用此GitHub站点的着色器代码。我相信我正在正确执行FFT,因为我得到的结果看起来正确,但是我对逆FFT的实现并没有像应该一样给我最初的结果。我对逆FFT的理解只是为了改变Twiddle因子参数的符号:

FFT twiddleArgument = -2.0 * PI * (index / u_subtransformSize)
iFFT twiddleArgument = 2.0 * PI * (index / u_subtransformSize)

我在这里做错了什么?

FFT着色器代码:

//GPU FFT using a Stockham formulation
#define HORIZONTAL
precision mediump float;
const float PI = 3.14159265359;
uniform sampler2D u_input_complex;
uniform float u_transformSize;
uniform float u_subtransformSize;
varying vec2 vUV;
vec2 multiplyComplex (vec2 a, vec2 b) {
    return vec2(a[0] * b[0] - a[1] * b[1], a[1] * b[0] + a[0] * b[1]);
}
void main(void){
    #ifdef HORIZONTAL
        float index = vUV.x * u_transformSize - 0.5;
    #else
        float index = vUV.y * u_transformSize - 0.5;
    #endif
    float evenIndex = floor(index / u_subtransformSize) * (u_subtransformSize * 0.5) + mod(index, u_subtransformSize * 0.5);
    //transform two complex sequences simultaneously
    #ifdef HORIZONTAL
        vec4 even = texture2D(u_input_complex, vec2(evenIndex + 0.5, gl_FragCoord.y) / u_transformSize).rgba;
        vec4 odd = texture2D(u_input_complex, vec2(evenIndex + u_transformSize * 0.5 + 0.5, gl_FragCoord.y) / u_transformSize).rgba;
    #else
        vec4 even = texture2D(u_input_complex, vec2(gl_FragCoord.x, evenIndex + 0.5) / u_transformSize).rgba;
        vec4 odd = texture2D(u_input_complex, vec2(gl_FragCoord.x, evenIndex + u_transformSize * 0.5 + 0.5) / u_transformSize).rgba;
    #endif
    float twiddleArgument1D = -2.0 * PI * (index / u_subtransformSize);
    vec2 twiddle1D = vec2(cos(twiddleArgument1D), sin(twiddleArgument1D));
    vec2 outputA = even.xy + multiplyComplex(twiddle1D, odd.xy);  //even.xy
    vec2 outputB = even.zw + multiplyComplex(twiddle1D, odd.zw); //even.zw
    gl_FragColor = vec4(outputA,outputB);
}

逆FFT着色器代码:

precision mediump float;
const float PI = 3.14159265359;
uniform sampler2D u_input;
uniform float u_transformSize;
uniform float u_subtransformSize;
varying vec2 vUV;
vec2 multiplyComplex (vec2 a, vec2 b) {
    return vec2(a[0] * b[0] - a[1] * b[1], a[1] * b[0] + a[0] * b[1]);
}
void main(void){
    #ifdef HORIZONTAL
        float index = vUV.x * u_transformSize - 0.5;
    #else
        float index = vUV.y * u_transformSize - 0.5;
    #endif
    float evenIndex = floor(index / u_subtransformSize) * (u_subtransformSize * 0.5) + mod(index, u_subtransformSize * 0.5);
    //transform two complex sequences simultaneously
    #ifdef HORIZONTAL
        vec4 even = texture2D(u_input, vec2(evenIndex + 0.5, gl_FragCoord.y) / u_transformSize).rgba;
        vec4 odd = texture2D(u_input, vec2(evenIndex + u_transformSize * 0.5 + 0.5, gl_FragCoord.y) / u_transformSize).rgba;
    #else
        vec4 even = texture2D(u_input, vec2(gl_FragCoord.x, evenIndex + 0.5) / u_transformSize).rgba;
        vec4 odd = texture2D(u_input, vec2(gl_FragCoord.x, evenIndex + u_transformSize * 0.5 + 0.5) / u_transformSize).rgba;
    #endif
    float twiddleArgument1D = 2.0 * PI * (index / u_subtransformSize);
    vec2 twiddle1D = vec2(cos(twiddleArgument1D), sin(twiddleArgument1D));
    vec2 outputA = even.xy + multiplyComplex(twiddle1D, odd.xy);
    vec2 outputB = even.zw + multiplyComplex(twiddle1D, odd.zw); //even.zw
    gl_FragColor = vec4(outputA, outputB);
}

我看到的错误与我正在运行的另一个着色器程序中的错字有关(不是问题中发布的着色器程序)。我现在正在工作。问题上的着色器适用于FFT和IFFT。

当您具有FFT函数时,可以使用它创建IFFT函数。

r:实际号码。

i:虚构数字。

cri的复杂号码。

carrc的数组。

cswap(carr)carr中的每个 c s交换 ri

cnorm(carr)carr中的每个 c s归一化为 carr的长度。

fft(carr):快速傅立叶转换carr

然后

ifft(carr)cnorm(cswap(fft(cswap(carr))))

相关内容

  • 没有找到相关文章

最新更新