Search Unity

Use the GPU per vertex shading for non graphical purposes

Discussion in 'Shaders' started by dr0r, Jun 18, 2017.

  1. dr0r

    dr0r

    Joined:
    Jun 18, 2017
    Posts:
    11
    Excuse my complete lack of knowledge.

    Is it possible to use shader programs to signal sometimes and fast back to the CPU instead of doing graphical changes?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    It's it possible to get data from a GPU vertex shader back to the CPU?
    Technically yes.

    Is it possible to use the GPU to speed up calculations?
    Also technically yes.

    Is it useful in practice for real time graphics to get data back to the CPU from the GPU for immediate use? Nope, never.

    Getting data back from the GPU to the CPU takes several milliseconds, generally significantly more time than it would have taken to have just done the calculations you wanted on the CPU to begin with. When people do use GPUs to speed up calculations that need to come back to the CPU it's when those calculations take so long that the several ms it takes to get data back isn't very long compared to the computation time (like doing a calculation that takes multiple seconds or longer), or if it's okay to wait a frame or two before the data is used. To make it more difficult Unity doesn't have any built in way to asynchronously get data from the GPU, that is request data but not use it immediately, so any time you try to read data back to the CPU you'll stall the entire game.

    When ever I see someone asking about getting data back from the GPU, or how to make it faster, my response is "you're doing it wrong, find a different way to solve the problem".
     
    dr0r likes this.
  3. dr0r

    dr0r

    Joined:
    Jun 18, 2017
    Posts:
    11
    This is not the only path I am pursuing :cool:.

    I believe you 100%. :)

    It is not entirely about the number crunching. Also about flagging vertices with values and have the ability to communicate what I choose back to the CPU and not just to the screen.

    I still want to know how to do it.

    How is it done? :(
     
    Last edited: Jun 18, 2017
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    There are two ways I can think of to do this. The first is to render your mesh to a render texture that's 1 pixel high and n vertices wide, then use SV_VertexID to determine the screen position to render out to rather than using the vertex position and projection matrices as one would normally. You can then read back the render texture into a Texture2D and parse each pixel on the CPU.

    The other way would be using a compute bufffer which you can set on the material write to from the vertex shader, then use GetData() to read on the CPU. This requires DX11 level hardware though.

    I'm not really sure what you're trying to accomplish though.
     
  5. dr0r

    dr0r

    Joined:
    Jun 18, 2017
    Posts:
    11
    I love you