# Math function equivalence for deferred transparency blending

if one consider the following blending operation:

color1*src_alpha blended with color2*(1-src_alpha)

Where color1 and color2 are RGB1*dot(L.N1) and RGB2*dot(L.N2)

Is it possible to find any math function equivalent where (RGB1 blend RGB2) can be blended to dot(L, function(N1,N2))?

The idea is to store a correct value of N1 blended with N2 in a normal map for later lighting. And with more than 2 normals if needed.

## 1 Answer

No, this is obviously not possible.

A normal map has only 3 degrees of freedom in its RGB channels 4 if you extend into using alpha too. The shading problem you're describing has (3 n) - 1 degrees of freedom, where n is the number of distinct normals you want to shade. (A single normal has two degrees of freedom, and every subsequent transparent layer adds two more degrees of freedom and a blend weight). You quickly end up with far more information than you have the bits to store.

And that's not even counting that the shading of each pixel depends not only on the normals of all the surfaces being lit, but also their locations. If the back surface is outside the range of the light, its normal should not contribute to the lighting and only the front one counts. And the reverse if the front surface is out of range. So now you either need to know the locations of all lights when doing your blend (in which case you might as well just do forward rendering), or also encode multiple depths per pixel and somehow be able to isolate the normal contribution at each depth.

This is why deferred shading is typically used only with opaque objects, and a follow-up forward pass to layer the transparency on top. Or tricks like alpha to coverage, dithering, and temporal anti-aliasing to render "transparent" blending as separate opaque samples and blur them together later.

You can also look into the technique of "depth peeling" for order-independent transparency, but it's quite heavyweight and not typically used in games.