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

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

Brush

27107-brush.png

If anyone can provide some insight on how to properly blend a RenderTexture I would greatly appreciate it, thanks!

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

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?

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

Premultiplied alpha blending is the way to do this. Use it both for rendering into your texture and rendering your texture into the scene.

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?

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!!

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.

1 Like