0

Reapeating the above: Can a GLSL fragment shader run without a framebuffer and any rasterization stage?

This perfect answer gives an insight about where to start with SSBO's. The answer has a link to OpenGL ARB extension that has a boilerplate code. The code works for me if made with some changes to work with OpenGL compute programs. But, I really does not get it, how to do with a fragment program? And without any other buffers than SSBO.

The code clearly has fragment source code without any pixel operations, only SSBO ones.

  in vec4 color;

  void main()
  {
    uint fragmentNumber = atomicCounterIncrement(fragmentCounter);
    if (fragmentNumber < maxFragmentCount) {
      fragments[fragmentNumber].position = ivec2(gl_FragCoord.xy);
      fragments[fragmentNumber].color    = color;
    }
  }

And later in the C program file:

  // Generate, bind, and specify the data store for the atomic counter.
  glGenBuffers(1, &counterBuffer);
  glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, counterBuffer);
  glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, 
               GL_DYNAMIC_DRAW);

  // Reset the atomic counter to zero, then draw stuff.  This will record
  // values into the shader storage buffer as fragments are generated.
  GLuint zero = 0;
  glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), &zero);
  glUseProgram(program);
  glDrawElements(GL_TRIANGLES, ...);

As per my setup, I do not have any output with the means of OpenGL pixels. I wish it to stay so. Is it possible, or am I missing something?

P.S The above setup gives me error invalid framebuffer operation after glDrawElements immediately followed by glFinish.

Update 21.03.2021

There is a Framebuffers with no attachments. The only thing you should set in its state is its width and height. And that is somewhat at the course that anyone's heading, if one wish to minimize setup.

The minus of the aformentioned, is that it is still requires some geometry to be fed to rasterization stage. To start the shader stages, you know. But, as a plus, one gets geometry rasterization, wish it or not.

If I have time, I leave some code as a reminder for miself.

user14063792468
  • 839
  • 12
  • 28
  • 3
    "*But, I really does not get it, how to do with a fragment program?*" Why would you want to? A fragment shader is for rendering. If you are not writing to a framebuffer, then you are not rendering. – Nicol Bolas Mar 16 '21 at 05:04
  • @NicolBolas I'm not rendering, but I want to do some manipulations on the buffer later. Fragment shaders seem to be easier in setup. – user14063792468 Mar 16 '21 at 09:10
  • 2
    @user14063792468: Unless you are rendering something (or at least rasterizing something), the fragment shader will never be called. Setup wise running a compute is basically the same code as with the fragment shader version, just without the VAO/VBO/Drawcall setup – BDL Mar 16 '21 at 10:59
  • @BDL But the workgroup, local group pain... Yes, I've profiled and fragment programs are definetly faster. – user14063792468 Mar 16 '21 at 13:14
  • 1
    @BDL If the today's OpenGL do not allow the above, could you post it as an answer? – user14063792468 Mar 16 '21 at 13:20
  • "Yes, I've profiled and fragment programs are definetly faster" This only means that you converted this to compute shaders in some sub-optimal way. Since your algotihm obviously does not need any of the advanced workgroup synchronization and communication features (because fragment shaders don't offer these), it should actually not be hard to port it to a compute shader in an efficient way. – derhass Mar 21 '21 at 22:41
  • @derhass I have a compute code, I'm not converting anything. The question states clear: I wish to get rid of rasterization stage(**in this particular case**). But the setup is somewhat complicated. So there is two options: have a dummy framebuffer with fragments and some quad, or, have a computes with who-knows-how setup of the workgroups, threads, and whatelse. – user14063792468 Mar 22 '21 at 05:14
  • 1
    "I wish to get rid of rasterization stage(in this particular case)" No, you do not. This particular example does record the **rersults of the rasterizer** into an SSBO (and it tracks the implementation-defined order your rasterizer works), it simply does not make the slightest sense without a rasterizer, and it is meant for _actual_, _arbitrary_ input geometry, not limited yo just some dummy full-screen quad. Now this is only an example without any real-world usage scenario. – derhass Mar 22 '21 at 15:10
  • @derhass Good point. Based on comments, I have toi remember that fragment shaders work with some geometry supplied. – user14063792468 Mar 22 '21 at 19:30
  • @user14063792468 Can you consider moving your edit about GL_ARB_framebuffer_no_attachments to an actual answer? On Stack Overflow you are encouraged to answer your own questions if you found a solution [1], and I skipped over your useful find since the question was displayed as "unanswered". [1] https://stackoverflow.com/help/self-answer – David Zhao Akeley Jun 27 '22 at 22:41
  • @DavidZhaoAkeley I had posted an answer. The explanation actually was given by commenters. – user14063792468 Jun 28 '22 at 01:33

1 Answers1

1

Can a GLSL fragment shader run without a framebuffer and similar inconveniences?

No. The fragment shaders need the step that invokes them. The stage that produce fragments called rasterization.

From the khronos wiki:

A Fragment Shader is the Shader stage that will process a Fragment generated by the Rasterization into a set of colors and a single depth value.

The fragment shader is the OpenGL pipeline stage after a primitive is rasterized.

And the rasterization needs a render step to produce fragments. The rendering is done to somewhere. In OpenGL, it is done to framebuffer. So without a framebuffer, you can not render, hence OpenGL can not produce fragments.

Setup of a framebuffer can be minimized by Framebuffers with no attachments. But one needs to supply geometry and render it, to invoke fragment shaders.

Fragment shaders can read and write to arbitrary SSBO. But the usage is not similar to compute shaders. Fragment shaders invoke on each produced fragment, and compute shaders can be invoked, as I may say, arbitrary.

Many thanks to all commenters who had pointed me to the obvious, by now, reason why the fragment shaders need a render operation.

user14063792468
  • 839
  • 12
  • 28