Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
Dismiss Notice
Join us now in the Performance Profiling Dev Blitz Day 2023 - Q&A forum where you can connect with our teams behind the Memory and CPU Profilers and the Frame Debugger.

How to properly Alpha Blend a RenderTexture with objects behind it?

Discussion in 'Shaders' started by jthomCMM, May 30, 2014.

  1. jthomCMM

    jthomCMM

    Joined:
    May 28, 2014
    Posts:
    5
    I've seen some similar posts but I'm not sure they were the same issue. I apologize if it is. I'm just hoping I can get some insight into this. Basically, I'm trying to make a little paint program where a user can select a background and paint over the top of it (not into it). So far I have been able to successfully write to a render texture and apply that to a quad over the top of my background quad. The painting works ok but I can't seem to figure out the alpha blending. I apologize if this isn't clear. I'm quite new to shader programming but I'll try to explain anything that isn't clear.

    So a quick rundown of the process I'm using:

    1) Using Graphics.Blit() I blit a fully transparent texture into the RenderTexture once at the start of the app.

    2) When paint is applied with the mouse I set my RenderTexture as active.

    3) Then I draw the brush textures into RenderTexture using Graphics.DrawTexture() and reset the active render texture to null.

    4) Finally I apply an Unlit shader to blend the RenderTexture with the background image.


    I'm using an unlit shader with alpha blending using:

    Blend SrcAlpha OneMinusSrcAlpha

    I can post the full shader if needed but it's basically Unity's standard Transparent Unlit Shader. The problem seems to be that when I blend the RenderTexture I'm getting very low alpha values and the paint appears much more transparent than it should be.

    I also tried using AlphaTest:

    AlphaTest Greater 0

    This has a slightly better result but it seems to produce black outlines around the paint textures which I'm guessing also has to do with the low alpha values.

    The thing that puzzles me is that the RenderTexture preview in Unity looks correct. Here is an image of my results and one of the brush I'm using.

    Blending

    $AlphaBlendingRenderTexture.jpg

    Brush

    $Brush.png

    If anyone can provide some insight on how to properly blend a RenderTexture I would greatly appreciate it, thanks!
     
    Last edited: May 30, 2014
  2. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    I don't think you are doing anything wrong with the shader, i believe Blend SrcAlpha OneMinusSrcAlpha is what you want for your case

    the problem seems to be the way you paint, you are replacing the 4 channels rgba at each brush stroke but in my perspective you should only be replacing the rgb channels while the alpha channel should be additive
     
  3. jthomCMM

    jthomCMM

    Joined:
    May 28, 2014
    Posts:
    5
    Thanks for the reply. That does make sense that the alpha channel is getting reset each time. Would you happen to know if it's possible to write only to RGB and Alpha separately using Graphics.DrawTexture() or should I be approaching this from some other way?
     
  4. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    I'm not sure but

    since DrawTexture uses a texture, can't you change the texture before painting it? might be too heavy but you could read the renderTexture below and then mix the alpha as you want in the texture before drawing it

    I'm not sure if this is the ideal way though, i'm just trying to adjust your way of doing it
     
  5. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Premultiplied alpha blending is the way to do this. Use it both for rendering into your texture and rendering your texture into the scene.
     
  6. jthomCMM

    jthomCMM

    Joined:
    May 28, 2014
    Posts:
    5
    Thanks for the link! That blog looks like a wealth of knowledge. I've added premultiplied alpha blending to my shader for the scene but I'm still a little unclear on how to do this while rendering into the texture. I know Graphics.DrawTexture() does have a Material parameter but when I apply a material (using the same premultiplied shader) nothing seems to render into the texture. I think I might be missing a step. Any ideas?
     
  7. sameer-mirza

    sameer-mirza

    Joined:
    Nov 14, 2011
    Posts:
    36
    Hi, I'm doing something similar,

    I get borders around my paint strokes (much like the AlphaTest image posted above), even after changing the blend mode to use One OneMinusSrcAlpha, I'm getting a black border. I'm using a Projector to paint with colors and output to a rendertexture which is then used to show the painting in the scene.
    This is what is returned at the end of the Projection shader:

    float4 output = float4(paintValue, alpha);​

    where paintValue is the color value of the paint and alpha is taken from reading the tex2Dproj's alpha value.

    Any help getting rid of the borders is much appreciated!!

    Capture.PNG RT_A.PNG RT_RGB.PNG
     
    Last edited: Oct 8, 2015
  8. NotSuspiciousLLC

    NotSuspiciousLLC

    Joined:
    Nov 26, 2019
    Posts:
    3
    For any future people who stumble onto this:

    The reason the borders look black is because they had the cleared (black) original pixels mixed in when the brush was applied. The brush should be setting the pixels to a premultiplied green rgb, with appropriate alpha, instead of inheriting any background information.
     
    kmedved likes this.