【问题标题】:WebGL inverse FFT implementationWebGL 逆 FFT 实现
【发布时间】:2018-03-16 10:04:03
【问题描述】:

我正在尝试使用片段着色器在 WebGL 中实现 FFT 和相关的逆 FFT。我正在使用来自this github site 的着色器代码。我相信我正在正确地进行 FFT,因为我得到的结果似乎正确,但是我对逆 FFT 的实现并没有像应有的那样给我最初的结果。我对逆 FFT 的理解只是改变 twiddle Factor 参数的符号:

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);
}

【问题讨论】:

    标签: glsl webgl fft ifft


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      r:实数。

      i:虚数。

      cri 的集合的复数。

      carrc 的数组。

      cswap(carr):交换carr中每个cs的ri

      cnorm(carr):将carr 中的每个cs 标准化为carr 的长度。

      fft(carr)carr 的快速傅里叶变换。

      然后

      ifft(carr):cnorm(cswap(fft(cswap(carr)))).

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-12
        • 2013-05-22
        • 2015-11-15
        • 2015-08-20
        相关资源
        最近更新 更多