Transparency does unexpected things in Render Textures

Avatar
  • updated
  • Fixed

I have 2 game objects, each with a "Disc" component, they're next to each other in a venn diagram sort of shape. Left circle is an opaque red, the right circle is a translucent green (any opacity value not zero or one should repro)


In the scene view this looks like this:

Image 162

So far so good, the translucent green circle is blending with the red! This is the desired effect.

Now we point a (orthographic) camera at these two game objects, and render the result to a render texture, and attach that Render Texture to a Raw Image component. In the preview pane we see the first hint that something is amiss:

Image 163

The checkerboard pattern is showing through behind the middle section of the venn diagram. The left circle is opaque so it should be opaque.


It shows up this way in game as well.

Image 164

I also found that this repro'd regardless of whether the green circle was in front of or behind the red one. It seems to always pick the lowest possible opacity for that pixel.


Not the end of the world (I can imagine lots of possible workarounds), just thought I'd call it out.

Thanks for all the great work!

Reporting a bug? please specify Unity version:
2019.4.0f1
Reporting a bug? please specify Shapes version:
2.3.1
Reporting a bug? please specify Render Pipeline:
Pinned replies
Avatar
Freya Holmér creator
  • Answer
  • Fixed

I've now added Transparent Premultiplied as a blend mode in Shapes! If all shapes you render are using premultiplied alpha blending, they will correctly composite into the RT in a premultiplied state


note that this requires you to render the final RT correctly too, either by rendering the RT itself using premultiplied alpha, or by unpacking it from premul to straight alpha before rendering, which does require some extra code:

// premul alpha to straight alpha
if( c.a == 0 )
c = float4(0,0,0,0); else
c.rgb /= c.a;
Avatar
Freya Holmér creator
  • Not a bug

this is (unfortunately) how alpha blending in games work, because games generally don't use the correct math for it, which means it ignores the destination alpha channel and doesn't write the correct net alpha

more info on this here: https://twitter.com/FreyaHolmer/status/1293163103035817985

this is also something I can't really add either, as it's more complicated than just having another blending mode available :( It requires you to pass in the current state of the render texture into all of these shaders

Avatar
Wyatt Chapman

Ah, bummer! Well thanks for the reply anyway.

Avatar
Freya Holmér creator

a little update - this might actually be possible if I add premultiplied alpha blending as an option, in which case all blending should work as expected if you premultiply the RT before rendering all shapes, and then un-premultiplying afterwards (or change the way you render it to parse it as a premul), so I might add that soon!

Avatar
Freya Holmér creator
  • Answer
  • Fixed

I've now added Transparent Premultiplied as a blend mode in Shapes! If all shapes you render are using premultiplied alpha blending, they will correctly composite into the RT in a premultiplied state


note that this requires you to render the final RT correctly too, either by rendering the RT itself using premultiplied alpha, or by unpacking it from premul to straight alpha before rendering, which does require some extra code:

// premul alpha to straight alpha
if( c.a == 0 )
c = float4(0,0,0,0); else
c.rgb /= c.a;
Avatar
Wyatt Chapman

Awesome! Thanks Freya!

Avatar
Freya Holmér creator

also, a little update - this will now be the default behavior of the regular transparent blending mode, so you don't even need to use a separate premultiplied blend :)