Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Looking For Shader Advice

Discussion in 'Shaders' started by Phedg1, Sep 6, 2018.

  1. Phedg1

    Phedg1

    Joined:
    Mar 3, 2015
    Posts:
    113
    I'm just beginning to wrap my head around shaders and I'm looking for some advice. I render my camera to a RenderTexture that I draw back on the screen with a RawImage component and I am trying to get the colours and transparency to match the camera's view as closely as possible. I also need the image to be effected by CanvasGroup.alpha so I can fade it in and off the screen seamlessly. To that end, I'm trying to create a shader that has some nice transparent/semitransparent blending. The unity manual recommends Blend SrcAlpha OneMinusSrcAlpha, but I have noticed that, whether it's the colour or alpha, the end result is that the colours are noticeably off. After some Googling I found that Blend One OneMinusSrcAlpha is recommended for a truer transparency blend. However, using this new blend mode I have found that the transparency has an abrubt cutoff when approaching zero, using the CanvasGroup.alpha property. When approaching opaque the shader transitions really smoothly. When approaching 0, setting the alpha at 0.002 is still significantly opaque and when it hits zero it's quite noticeable that it was not a smooth transition. Is there anything I can do to address this? Can I have some advice as to where to start Googling to tackle this? Thanks.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    This is proper alpha blending. As the alpha goes lower, the object will get more transparent.

    This is premultiplied alpha blending. As the alpha goes lower, the object will get more additive. You need to simultaneously multiply the color value by the alpha in the shader for it to get more transparent, but the results will be identical to the above. It's called "premultiplied" in reference to the color values being already multiplied by the alpha prior to the blend. This can be useful for doing compositing if your render texture has a range of alpha values, but less so if you're simply fading the entire image in and out.

    Likely because at zero alpha, the canvas group knows to just not draw at all, so you're going from nearly fully additive, to not being rendered when you're using the premultiplied alpha blend.

    Here's the rub. You should be using the Blend SrcAlpha OneMinusSrcAlpha, but if you're using gamma color space rendering you may see a color shift when fading out that's unavoidable. The solution is to use linear color space.
    https://docs.unity3d.com/Manual/LinearRendering-LinearOrGammaWorkflow.html

    Alternatively you can do the blend in the shader if you can get a copy of the screen contents. Using grab pass for example. Then you would convert both the grab pass texture and your render texture to linear using the built in GammaToLinearSpace() function, lerp between them based on the alpha, then convert back using LinearToGammaSpace().
     
  3. Phedg1

    Phedg1

    Joined:
    Mar 3, 2015
    Posts:
    113
    Ok, so I've found that, regardless of the shader used, there is some funny business going on when rendering a Camera to a RenderTexture. It seem that the RenderTexture has, regardless of the shader used, has an incorrect alpha channel. This is especially apparent where there are semitransparent images on top of opaque ones, causing what otherwise should be an opaque section to become transparent. Do you know of a way around this?

    Desired/How the camera renders the image normally on screen.
    https://postimg.cc/image/g49jlf3c7/



    Actual/What the RenderTexture actually is.
    https://postimg.cc/image/42e5r9mdz/
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    If the render texture has alpha you don't want, you can either make sure everything you're rendering to the render texture is properly outputting the wanted alpha value (especially opaque objects which often don't pay attention to their alpha value), or you can change your shader to simply ignore the render texture's alpha.
     
  5. Phedg1

    Phedg1

    Joined:
    Mar 3, 2015
    Posts:
    113
    Can you give an example of the first part of this? Or an idea as to where to look? Because I don't understand how to do what you mean.

    It's almost like when generating the RenderTexture the alpha is being overwritten instead of blended.
     
    Last edited: Sep 7, 2018
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    When you render any object, the shader is going to output an RGBA value. For opaque objects, the alpha doesn't "do" anything, at least nothing that is obvious as far as the RGB color is concerned, but it is still being written into the target buffer! I've seen (and written) plenty of opaque shaders that do something like this:

    return tex2D(_Tex, UV);

    If the texture has any alpha, I've now written those to the alpha value of the render target.

    One solution is to use ColorMask RGB which will tell the shader to not render to the alpha, but the better option is to force the alpha to be 1 like this.

    fixed4 col = tex2D(_Tex, UV);
    return fixed4(col.rgb, 1.0);
     
  7. Phedg1

    Phedg1

    Joined:
    Mar 3, 2015
    Posts:
    113
    The issue is that I still need the alpha's of my RenderTexture, I can't just have everything as opaque, I'm trying to replicate as closely as possible the original image including its alpha. The issue is that when the RenderTexture is generated from the Camera the alphas are incorrect.
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Ah, in that case you do need to use premultiplied alpha, as the color values in your render texture have already been multipled by their alpha. It also means you need to make sure all of the objects you're rendering in that render texture are properly handling their alpha output as mentioned above.

    I go into detail on the topic here:
    https://forum.unity.com/threads/dar...awn-into-a-rendertexture.516545/#post-3385666
     
  9. Phedg1

    Phedg1

    Joined:
    Mar 3, 2015
    Posts:
    113
    Thanks!