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