Search Unity

Position of a vertex from vertex-animated shader?

Discussion in 'Shaders' started by VLukianenko, Jun 25, 2018.

  1. VLukianenko

    VLukianenko

    Joined:
    Mar 27, 2017
    Posts:
    30
    Hello, everyone!

    I have a riddle I'd like to solve, hoping for the help of community.
    Is it possible to obtain exact world position of a vertex during it's rendering with a vertex-animated shader?

    I imagine it's impossible without some voodoo magic, since CPU knows nothing about GPU rendering a vertex.
    What should I look for?
    Or, maybe, I should use a different approach? To not to animate vertices in vertex-shader, but in a different, however somewhat random manner?

    Any ideas would be appreciated
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    Short version: No.

    Vertex shaders output data that gets interpolated and passed to the fragment shader that outputs a color on screen. No other data but that final color is retained from any of the shader stages and they're not designed to output data back to the CPU.


    Long version: Yes, but you really don't want to.

    You can use special shaders and render texture setups to output the vertex positions to a texture, or you can use a compute buffer to write out the vertex positions within the vertex stage itself. However to get that data back to the CPU from the GPU will likely take longer than doing all of the same calculations on the CPU to begin with, not to mention you have to render the object once to get this data prior to rendering the scene for real as once the scene is rendering it's too late to use that data for that frame, otherwise you're always a frame behind on the CPU.
     
  3. Kumo-Kairo

    Kumo-Kairo

    Joined:
    Sep 2, 2013
    Posts:
    343
  4. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
  5. VLukianenko

    VLukianenko

    Joined:
    Mar 27, 2017
    Posts:
    30
    Thanks for the replies!

    I looked up compute shaders and this indeed seems to be what I am looking for.
    So far I had success setting vertex buffer from a mesh, calculating positions in compute shader, altering them, and then using ComputeBuffer.GetData() and Mesh.SetVertices() to let the CPU know of their new positions. It doesn't lag for me, while animating mesh on CPU did lag. Though, I am working on relatively small amount of vertices right now (4-5k).

    Regarding of what I am trying to achieve: it's a procedural vertex animation, with particles spawned from vertices at a certain condition. While the animation worked with a usual cg shader, particle system didn't know about altered vertex positions when spawning. Now they know.

    As optimization, I could get and set vertices only when I need to spawn partciles, to avoid doing this every frame.

    Thanks for the help!
     
    mattstrangio likes this.
  6. Kumo-Kairo

    Kumo-Kairo

    Joined:
    Sep 2, 2013
    Posts:
    343
    For vertex - based particle emission you can take this thing as a starting point:
    upload_2018-6-28_13-29-41.png

    It uses a skinned mesh renderer, but the idea should work for procedural vertex animation too
    https://github.com/keijiro/Skinner
     
  7. VLukianenko

    VLukianenko

    Joined:
    Mar 27, 2017
    Posts:
    30
    Thanks a lot! Looks interesting!