2017-10-04 11 views
1

J'essaie de mettre en œuvre une FFT et une FFT inverse associée dans WebGL en utilisant des fragment shaders. J'utilise le code shader de ce site github: https://github.com/jbouny/fft-ocean/blob/master/js/shaders/FFTOceanShader.js. Je crois que je fais la FFT correctement car j'obtiens des résultats qui semblent corrects mais mon implémentation pour la FFT inverse ne me donne pas le résultat initial comme il se doit. Ma compréhension de la FFT inverse est juste pour changer le signe sur l'argument du facteur de tripoter:Mise en œuvre FFT WebGL inverse

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

Y at-il sur le plan conceptuel que je fais mal ici?

Code FFT Shader:

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

inverse FFT Shader code:

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

Répondre

0

L'erreur que je voyais était liée à une faute de frappe dans un autre programme de shaders que je courais (non shader programmes affichés dans la question). Je l'ai fonctionné maintenant. Les shaders dans la question fonctionnent pour FFT et iFFT.