<?xml version="1.0" encoding="UTF-8" standalone="yes"?><oembed><version><![CDATA[1.0]]></version><provider_name><![CDATA[Krzysztof Narkowicz]]></provider_name><provider_url><![CDATA[https://knarkowicz.wordpress.com]]></provider_url><author_name><![CDATA[Krzysztof Narkowicz]]></author_name><author_url><![CDATA[https://knarkowicz.wordpress.com/author/knarkowicz/]]></author_url><title><![CDATA[Premultiplied alpha]]></title><type><![CDATA[link]]></type><html><![CDATA[<div>
<p>If You don&#8217;t know what&#8217;s premultiplied alpha and why it solves all the world&#8217;s problems, just read <a href="http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BPremultiplied%20alpha%5D%5D">Tom Forsyth on premultiplied alpha</a> or <a href="http://blogs.msdn.com/shawnhar/archive/2009/11/06/premultiplied-alpha.aspx">Shawn Hargreaves on premultiplied alpha</a>.</p>
</div>
<p>Pros:</p>
<ol>
<li>Better quality for textures with sharp alpha cutouts.</li>
<li>Removes some blending state changes (which can be important if You are coding for a PC).</li>
<li>Can mix additive blending with alpha blending without a state/shader/texture change.</li>
</ol>
<p>What are the hidden cons, which aren&#8217;t mentioned by Tom or Shawn?</p>
<ol>
<li>Fixed pipeline fog doesn&#8217;t work with it.</li>
<li>Worse quality for smooth alpha with DXT5 compression.</li>
</ol>
<p>Why premultiplied alpha doesn&#8217;t work very well with DXT5 for textures with smooth alpha gradients? In DXT5 texture is divided into the 4&#215;4 pixel blocks. For every block, colors (and alphas) are approximated with equidistant points on a line between two end points (using some index table). Color end points are quantized (5:6:5 bits) and alpha end points are saved with 8 bit precision. This means that for the most textures we get better precision for the alpha channel than for the color channel.</p>
<p>Furthermore compressing values of a broader range gives us better precision. For example if we have alpha filled with 1/255 and RGB values in range [0; 1] then premultiplied texture RGB channels will contain only two different numbers &#8211; 0 or 1/125. This means that by using standard alpha blending we get better precision in case we would like to multiply RGB by a factor greater than 1 or tonemap final results.</p>
<p>Standard alpha blending:</p>
<pre class="brush: cpp; title: ; notranslate" title="">srcAlpha = Compress_color( src.rgb ) * Compress_alpha( src.a )</pre>
<p>Premultiplied alpha blending:</p>
<pre class="brush: cpp; title: ; notranslate" title="">srcAlpha = Compress_color( src.rgb * src.a )</pre>
<p>Let&#8217;s see how does it look in practice. I created a sample texture with a &#8220;lighting&#8221; gradient in RGB channels and smoke puff in alpha (from left to right: RGB, alpha and premultiplied RGB by alpha):</p>
<p><a href="https://knarkowicz.files.wordpress.com/2009/11/srctile2.png"><img loading="lazy" data-attachment-id="153" data-permalink="https://knarkowicz.wordpress.com/2009/11/18/premultiplied-alpha/srctile/" data-orig-file="https://knarkowicz.files.wordpress.com/2009/11/srctile2.png" data-orig-size="384,128" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="srcTile" data-image-description="" data-image-caption="" data-medium-file="https://knarkowicz.files.wordpress.com/2009/11/srctile2.png?w=300" data-large-file="https://knarkowicz.files.wordpress.com/2009/11/srctile2.png?w=384" class="aligncenter size-full wp-image-153" src="https://knarkowicz.files.wordpress.com/2009/11/srctile2.png?w=384&#038;h=128" alt="srcTile" width="384" height="128" srcset="https://knarkowicz.files.wordpress.com/2009/11/srctile2.png 384w, https://knarkowicz.files.wordpress.com/2009/11/srctile2.png?w=150&amp;h=50 150w, https://knarkowicz.files.wordpress.com/2009/11/srctile2.png?w=300&amp;h=100 300w" sizes="(max-width: 384px) 100vw, 384px" /></a></p>
<p>Now let&#8217;s alpha blend two compressed textures (DXT5), zoom and compare results (left image &#8211; standard alpha blending, right &#8211; premultiplied alpha blending):</p>
<p><a href="https://knarkowicz.files.wordpress.com/2009/11/cmp21.png"><img loading="lazy" data-attachment-id="154" data-permalink="https://knarkowicz.wordpress.com/2009/11/18/premultiplied-alpha/cmp2/" data-orig-file="https://knarkowicz.files.wordpress.com/2009/11/cmp21.png" data-orig-size="512,256" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="cmp2" data-image-description="" data-image-caption="" data-medium-file="https://knarkowicz.files.wordpress.com/2009/11/cmp21.png?w=300" data-large-file="https://knarkowicz.files.wordpress.com/2009/11/cmp21.png?w=512" class="aligncenter size-full wp-image-154" src="https://knarkowicz.files.wordpress.com/2009/11/cmp21.png?w=512&#038;h=256" alt="cmp2" width="512" height="256" srcset="https://knarkowicz.files.wordpress.com/2009/11/cmp21.png 512w, https://knarkowicz.files.wordpress.com/2009/11/cmp21.png?w=150&amp;h=75 150w, https://knarkowicz.files.wordpress.com/2009/11/cmp21.png?w=300&amp;h=150 300w" sizes="(max-width: 512px) 100vw, 512px" /></a></p>
<div>
<p>This looks like a small difference, but can be quite visible in a real game &#8211; especially when smoke particles are big or their color is multiplied by a factor greater than 1 or when using some kind of tone-mapping.</p>
<p>BTW there is interesting feature/bug in NVIDIA Photoshop texture tools. You can&#8217;t save DXT5 with full black alpha (it just creates a DDS without alpha channel).</p>
</div>
]]></html><thumbnail_url><![CDATA[https://knarkowicz.files.wordpress.com/2009/11/cmp21.png?fit=440%2C330]]></thumbnail_url><thumbnail_width><![CDATA[440]]></thumbnail_width><thumbnail_height><![CDATA[220]]></thumbnail_height></oembed>