Search Unity

Change vertex colors with shader?

Discussion in 'Shaders' started by zombox, Mar 18, 2016.

  1. zombox

    zombox

    Joined:
    Aug 10, 2011
    Posts:
    119
    I have a large mesh that's a combination of hundreds of submeshes. Each of these submeshes have unique vertex colors assigned to them. In my shader, I would like to lerp all of the vertex colors of these submeshes to pure white, over a bunch of frames.

    One solution would be to do the lerping in C# and re-assign all of the vertex colors each frame, but that gives me a noticeable performance hit on mobile. Is there a way to do the lerping in a shader, so that each frame the shader itself changes the vertex colors? Or are vertex colors read-only when a shader accesses them?

    It should be noted that not all submeshes lerp their colors at the same time, so it's not as simple as doing a simple lerp-to-white over all the submeshes at once. That's why I have to rely on their vertex color data to keep them separated. In the game itself all vertex colors are set to black by default, then at various points in the game, a random submesh gets its vertices assigned a color. The idea is that once the shader detects an rgb value greater than 0, it starts lerping that submesh's verts to white. Is this possible?
     
  2. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    I'd put together a shader with 2 keywords (BLENDING and WHITE), and 3 materials with it assigned. One material with no keywords (i.e. shows vertex colour) one with BLENDING which lerps between white-->vcolor and one with WHITE which would just ignore vertex colour entirely.

    All objects get the first material to start with. When you want to blend a certain object to vertex colour, you assign it an instance of the BLENDING material, and blend that particular object the material parameter. Then, when it's fully blended out to white, set it's material back to the common material with the WHITE keyword.

    That way, you should be able to batch as much as possible at any given time, but don't have the overhead of having to alter the vertex colours of many items each frame.
     
  3. zombox

    zombox

    Joined:
    Aug 10, 2011
    Posts:
    119
    Thanks for the suggestion, but the effect I'm trying to achieve is part of a larger pipeline that requires the mesh has only one material and shader. So, it's gotta be figure-out-how-to-change-vertex-colors-in-shader, or bust.
     
  4. Michal_

    Michal_

    Joined:
    Jan 14, 2015
    Posts:
    365
    Vertex colors are definitely read-only (like every vertex attribute). You could use stream output stage on desktop but not on mobile.
    You could try to store absolute time when the lerp should begin in uv channel for every vertex. That way every vertex knows when the lerp started (uv channel) and its initial color (vertex color). You can now compare start time with current absolute time to get time delta. Use it to compute current color and pass it to pixel shader.
     
  5. zombox

    zombox

    Joined:
    Aug 10, 2011
    Posts:
    119
    Fantastic idea Michal, thanks for that!