Draw Material To Render Target node has inverted alpha

I was trying the new Draw Material To Render Target node in 4.13 Preview 1 and it seems that its default behaviour produces inverted alpha in the render target.

Here is my test setup using a blank C++ project:

Import a PNG with alpha as a texture

Right click the texture asset and make a material. Set the material to Translucent Unlit. Wire it up with emissive/opacity:

101626-basic_mat.png

Make a pass through material to draw your Render texture to a static mesh. Again make it Translucent Unlit.

101627-passthrough.png

Create the following BP. Add a static mesh (I used starter cube) and assign its material to the passthrough mat. Next the BP creates a canvas RT and draws the alpha texture material to it. Set the RT to the texture param of the passthrough mat.

Place the actor in the world and I get the following result.

If I add a 1-x node from the InTex texture parameter to the material opacity output for the passthrough material I get the expected results:

1 Like

Hey astonish,

I was able to reproduce this issue on my end and have gone ahead and entered a bug report for this issue, UE-34314. You can track this report on our new Known Issues tracker here.

Let me know if you have further questions or need additional assistance.

Cheers,

You may want to add to the issue that this isn’t limited to the new DrawMaterial function - the alpha is also inverted now on translucent objects being rendered by a SceneCapture2D actor (but I’m guessing it’s the same cause).

In the below screenshot I am using a SceneCapture2D off-screen to capture some falling leaves (so that I can use the rendered falling leaves texture in UMG to “wipe away” my loading screen). Note the inverted alpha (it works as expected in 4.11):

(Hoping this can be fixed for the full 4.13 release)

Yep, I do some custom rendering of a material to UCanvasRenderTarget2D’s in C++ for our project. In 4.11 transparency was straight up broken and I had to render the alpha to a separate RT, in 4.12 I can do it to a single target, but the alpha is inverted as it is in 4.13. If you invert the alpha in the source material the color channels come out black in 4.12

tldr: this is a limitation of alpha blending hardware

In order to accumulate a bunch of translucent layers and composite them onto a background later, you have to accumulate two values:

NewColor = Color0 * Opacity0 + Color1 * Opacity1 + ...
BackgroundAmount = (1 - Opacity0) * (1 - Opacity1) * ...

BackgroundAmount is what we’re storing in the alpha channel when you do DrawMaterialToRenderTarget or a SceneCapture. To get ForegroundAmount from that (what’s typically called Opacity), you do 1 - BackgroundAmount. With the way fixed function alpha blending hardware works, we can only accumulate BackgroundAmount, not ForegroundAmount.

Thanks for the explanation DanielW. I haven’t had any trouble working with the feature as is, but having code to loop through a TArray to val.A = 255 - val.A; made me shiver a bit on large buffers so I was hoping to gain a bit of perf.

I’ve un-one-minused my material so it’s fixed on PC - but on mobile ES2 now it is backwards (so it’s inverted on one platform and not the other) - I can get around this with a platform switch, but they should probably be brought to parity?

In 4.17 my workaround is:

  • Set draw material to AlphaComposite blend mode;
  • Use standard Alpha (not inverted) on draw material;
  • Set the passthrough material to use inverted alpha output from RenderTexture (OneMinus node);
  • Clear RenderTexture to (0, 0, 0, 1) before drawing.
3 Likes