Sign in to follow this  

IFFT compute shader

This topic is 827 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,
 
Have been trying to implement the tessendorf ocean without any success. So basically I have the h~(t) computed in a texture (image2D), and I need to transform that back from frequency domain. I have attached my h~(t) texture as spectrum.png.
 
The trouble I have been having is implementing FFT with compute shader. I understand that I have to perform a 2D FFT, essentially one FFT for horizontal direction and another FFT for vertical direction. For the butterfly algorithm, I would have to precompute a butterfly texture for storing the index and weights to perform the addition.
 
The butterfly algorithm also has multiple stages, and in my case I have 8 stages as I use a 256x256 image. And within each stage, the output becomes the input of the next stage. Similarly, the output from FFTX would be the input for FFTY. This is done using two ping pong textures, and we switch them before we dispatch compute shader.

for (int i = 0; i < m_iNumOfPasses; i++)
{
	m_pFFTXComputeShader->SetPass(i);
	m_pFFTXComputeShader->Compute();
}

for (int i = 0; i < m_iNumOfPasses; i++)
{
	m_pFFTYComputeShader->SetPass(i);
	m_pFFTYComputeShader->Compute();
}

And my compute shader looks like this:

#version 430

layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

layout(location = 0, rgba16f) uniform image2D inputTex;
layout(location = 1, rgba16f) uniform image2D butterflyTex;
layout(location = 2, rgba16f) uniform image2D destTex;

uniform int pass;

vec2 FFT(ivec2 pos, vec2 index, vec2 weight)
{
  //get the two inputs we perform butterfly operation on
  vec2 input1 = imageLoad(inputTex, ivec2(index.x, pos.y)).xy;
  vec2 input2 = imageLoad(inputTex, ivec2(index.y, pos.y)).xy;
	
  //get the weighted input2
  vec2 weighted2;
  weighted2.x = weight.x * input2.x - weight.y * input2.y;
  weighted2.y = weight.y * input2.x + weight.x * input2.y;

  //add everything together
  vec2 complex = input1 + weighted2;
  return complex;
}

void main()
{
  const ivec2 thread_xy = ivec2(gl_GlobalInvocationID);

  vec4 indexAndWeight = imageLoad(butterflyTex, ivec2(thread_xy.x, pass));
	
  vec2 index = indexAndWeight.xy;
  vec2 weight = indexAndWeight.zw;

  vec2 result = FFT(thread_xy, index, weight);
  imageStore(destTex, thread_xy, vec4(result, 0.0, 1.0));
}

My FFT for vertical looks very similar to this shader, but with different lookup coordinates for the images.

 

Is there anything anyone can see I have got conceptually mistaken? I'm getting a black texture for my displacement texture (see ifft.png). To be honest, I'm not quite sure what to expect the texture to look like at the stages of FFT, I think it does look partially right with the butterfly structure, similar to some images I've seen online.

 

Any help would be appreciated, thanks!

 

(Please pardon anything strange you see in the compute shader, I've only just begun playing with compute shaders and I have no idea why it's so slow at the moment! 9 ms for the FFT, must be the slowest GPU FFT anyone has written, but I am just trying to go for the correctness first).

Edited by Bendtner

Share this post


Link to post
Share on other sites

This topic is 827 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this