Is there a way to compute something in a first shader program (eg. screen-space coordinates from word-space ones) and access those results in an another shader program?

Possible solutions

  1. Give up multiple-shader-programs architecture and create one combined shader program
  2. Save somehow results to a buffer objects (I couldn't find out if this is possible except computation shaders)
  3. Render to texture and read the texture

Is there a nicer solution?


Yes you can, this is how deferred rendering for example would work. For that you would render to a texture in one pass, in openGL this would be via an FBO, then feed that texture as the input to the next pass/shader.

  • $\begingroup$ Isn't it a bit restrictive? I mean, IMO, the texture is not the best-suited data storage for passing data in general (but I am new to computer graphics and maybe I have to get used to it). $\endgroup$ – BPiek Aug 2 '16 at 6:28
  • 2
    $\begingroup$ A texture is just a normal buffer, although in the fragment shader we use fancy sampler2D to read it with filtering/etc. You can use a compute shader to read it more in its raw form and skip the texture sampler stage. $\endgroup$ – PaulHK Aug 2 '16 at 6:30
  • $\begingroup$ There's a few options. Render-to-texture is probably the most straightforward but also kind of wasteful unless you need the results of your calculations in screen-space (like in deferred rendering), since you're rasterizing geometry before you can do any calculation. There's transform feedback, where you pull the output of a vertex or geometry shader before it hits the rasterizer and write it back to a buffer instead, might be good for the use case you mentioned but I haven't tried it myself. Otherwise compute shaders are the way to go, they're not that scary once you get used to them ;-) $\endgroup$ – russ Aug 5 '16 at 17:38

While the other answers are giving possible techniques to achieve what you're looking for, rendering your stuff into a texture is not always the best way if you need it as VBOs (i.e. vertex attributes) in the next render step (requiring either a read into a PBO and some index/coordinate/sizing magic or a vertex texture fetch).

An approach that would more accurately represent your 2nd point and be better when you need a transformation from a buffer into a buffer would be what's called Transform Feedback (or Stream Output in the DirectX world). However, this requires OpenGL 3/DirectX 10 hardware (however, not necessarily the GL4/DX11 needed for compute shaders). It's also a little less of a synchronization mess than compute shaders with arbitrary shader storage buffers when your use case is really just to transform a bunch of vertices/primitives into a nother bunch of vertices/primitives.

It basically lets you hook into the render pipeline after the vertex (or rather primitive) processing step and before the rasterization and write out whatever per-vertex values you computed directly into a buffer object (that you can then use as vertex attributes in the next step). It therefore doesn't draw anything into the framebuffer either. You just specify a bunch of varying/out variables and how to format them into the buffer and bind a buffer to the corresponding binding point. You can also use a query to gather information of how many primtives were written (since a geometry shader could change that dynamically) or, in later versions, just render the results directly without any need for synchronization. For more details, see the above Wiki article.

Together with the geometry shader (which TF hardware should have, too) and its abilities for changing the primtive type or removing/adding vertices, this makes a useful tool for transforming your geometry however you deem fit in preparation of further rendering stages. Of course, it has to be evaluated if that really buys you anything in the particular use-case, especially if you're really just doing a simple vertex transformation.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.