Search Unity

Question Custom alpha blending with GPU instancing.

Discussion in 'Shaders' started by izzynab, Jan 23, 2023.

  1. izzynab

    izzynab

    Joined:
    May 7, 2021
    Posts:
    56
    I am working on my trails system. I have been struggling with this for quite some time and I am not able to find any solution to this.
    I use GPU instancing to spawn meshes with instanced property _Alpha.

    When using alpha blending it looks like this:
    upload_2023-1-23_21-55-53.png

    I would like to perform some kind of operation on that it wouldn't have this values that are added to each other.

    The best option would be to use some blend function like this:

    Code (CSharp):
    1. fixed4 BlendMaxAlpha(fixed4 newColor, fixed4 oldColor) {
    2.     fixed maxAlpha = max(newColor.a, oldColor.a);
    3.     fixed4 blendedColor;
    4.     blendedColor.rgb = lerp(oldColor.rgb, newColor.rgb, maxAlpha);
    5.     blendedColor.a = maxAlpha;
    6.     return blendedColor;
    7. }
    But this isn't possible since I am using GPU instancing.
    Is there any way to take the max value of alpha from the previous object and based on that blend these objects into the camera texture?
    I tried using render textures to custom blend alpha values and pass it to another blit shader but there is still the same problem there. I cannot access alpha values of other objects since there are GPU instanced.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    This isn't because of GPU instancing. The above statement is true in all cases because that's how GPU rasterization works. Each triangle, nay, each fragment is rendered with no knowledge of any other rendered before or after it. And you only have access to the blend options exposed by the blending hardware of that GPU, of which doing a max of the current and previous alpha before doing a blend is not one of those options.

    Even on platforms that support programmatic blends (doing the blend in the shader) this wouldn't be possible, as you only get the value that's in the current render target. And that's not the previous object, that's at best the result of the previous blend(s).

    If you want to have a trail that has a constant color value, then you want to use a trail rather than discrete particles.

    The other "hack" would be to use a grab pass / opaque texture to sample the background and use opaque particles that look transparent by lerping to in the background color in the shader.
     
    AshwinMods likes this.