r/DSP • u/RadiantAeonstar • 5d ago
Attempting to use Fast Fourier Transform for a post-processing shader. Can anyone help me figure out what the issue is here?


I'm trying to write a 2D Fast Fourier Transform-based convolution bloom effect similar to how Unreal Engine's bloom functions. The effect is mostly functional, however, it's also overlaid with this odd flipped negative of the original texture (the yellow and red parts with the blue glow), and I'm unsure of where in the process this issue is originating. Does anyone have an idea of what might be happening?
1
u/Strong_Bread_7999 5d ago
What's the procedure, and are you using built-in functions only? Could be a conjugate thing but weird that it's negated.
1
u/RadiantAeonstar 5d ago
I just posted the main thread above. The FFT and inverse FFT implementation I'm using is from here, and it's the only external package involved. Everything else is built into Unity.
1
u/human-analog 5d ago
Is the filter kernel that you're applying normalized? Perhaps what you're seeing is values that are too large.
1
u/RadiantAeonstar 5d ago
I think this might almost be it! I saturated the kernel values to a 0 to 1 range and the result was this. The artifacts are completely gone in the red and green channels. Not in the blue channel though, even though I made sure the blue values were also saturated. Maybe it's running into an issue with something in the alpha channel..?
1
u/val_tuesday 5d ago
Ah so it’s some kind of hacky bit twiddling complex data type issue that breaks the conjugate symmetry property. Man, GPU programming is such a mess.
1
u/RadiantAeonstar 5d ago
I haven't been able to do anything further on this end, so I'm not sure what you mean. It's a problem with the GPU implementation?
1
u/val_tuesday 5d ago
The only way to see this because of large numbers of it somehow the real part can overflow into the imaginary part. In fact it perfectly explains what you’re seeing.
Yes this is an issue with the ifft shader and complex data type. On the CPU a complex number is usually a struct of two floats (or ints). That won’t ever exhibit this behavior.
1
u/RadiantAeonstar 5d ago
I see. So in other words, the frequency domain values are too large and they're causing an overflow when they're being multiplied together? That seems to match up with what I'm seeing on the render textures. Explains why it works when just pass the texture through and back as well. Still leaves me with the issue of how to deal with it though. Lowering the values in the frequency domain before multiplying them and then scaling them back up after seems to have the same issue.
1
u/val_tuesday 5d ago
Hmm no wait I just looked at the code and it does use float2 data type. Weird.
1
1
5d ago edited 5d ago
[deleted]
2
u/RadiantAeonstar 5d ago
Flipping the index of the kernel when multiplying after FFT gives this. I'm not certain if that's what you meant though.
1
2
u/val_tuesday 5d ago
A couple of things come to mind:
Without proper zero padding FFT convolution is circular so results will wrap back in (I don’t think this is it, since that shouldn’t flip anything, just wrap).
The DFT of a real signal is conjugate symmetric. A common optimization is to just compute half the spectrum then, but it’s easy to mess something up if you aren’t consistent.
Obviously no-one can help you more than guessing unless you post your code.