<?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[ACES Filmic Tone Mapping&nbsp;Curve]]></title><type><![CDATA[link]]></type><html><![CDATA[<p><span style="font-weight:400;">Careful mapping of HDR values to LDR is an important part of a modern game rendering pipeline. One of the goals of our new renderer was to replace Reinhard‘s tone mapping curve with some kind of <a href="http://www.slideshare.net/ozlael/hable-john-uncharted2-hdr-lighting/53">a filmic tone mapping curve</a></span><span style="font-weight:400;">. We tried <a href="http://filmicgames.com/archives/75">one from Ucharted 2</a></span><span style="font-weight:400;"> and tried rolling our own, but weren’t happy with either of this solutions. Finally, we settled on the one from <a href="https://github.com/ampas/aces-dev">ACES</a>, which is </span><span style="font-weight:400;">currently a <a href="https://docs.unrealengine.com/latest/INT/Support/Builds/ReleaseNotes/2015/4_8/">default tone mapping curve in Unreal Engine 4</a>.</span></p>
<p><span style="font-weight:400;">ACES color encoding system was designed for seamless working with color images regardless of input or output color space. It also features a carefully crafted filmic curve for displaying HDR images on LDR output devices. Full ACES integration is a bit of overkill for games, but we can just sample ODT( RRT( x ) ) transform and fit a simple curve to this data. We don’t even need to run any ACES code at all, as ACES provides <a href="https://github.com/ampas/aces-dev/tree/master/images">reference images for all transforms</a>. Although there is no linear RGB D65 ODT transform, but we can just use REC709 D65 and remove 2.4 gamma from it.</span></p>
<p><span style="font-weight:400;">Curve was manually fitted (max fit error: 0.0138) to be more precise in the blacks &#8211; after all we will be applying some kind gamma afterwards. Additionally, data was pre-exposed, so 1 on input maps to ~0.8 on output and resulting image’s brightness is more consistent with the one without any tone mapping curve at all. For the original ACES curve just multiply input (x) by 0.6.</span></p>
<p>Fitted curve&#8217;s HLSL source code (free to use under public domain CC0 or MIT license):</p>
<pre class="brush: cpp; title: ; notranslate" title="">
float3 ACESFilm(float3 x)
{
    float a = 2.51f;
    float b = 0.03f;
    float c = 2.43f;
    float d = 0.59f;
    float e = 0.14f;
    return saturate((x*(a*x+b))/(x*(c*x+d)+e));
}
</pre>
<p>Fitted curve plotted against source data&#8217;s sample points:</p>
<p><img loading="lazy" data-attachment-id="362" data-permalink="https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/aces_film_curve/" data-orig-file="https://knarkowicz.files.wordpress.com/2016/01/aces_film_curve.png" data-orig-size="576,366" 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="ACES_film_curve" data-image-description="" data-image-caption="" data-medium-file="https://knarkowicz.files.wordpress.com/2016/01/aces_film_curve.png?w=300" data-large-file="https://knarkowicz.files.wordpress.com/2016/01/aces_film_curve.png?w=576" class="aligncenter size-full wp-image-362" src="https://knarkowicz.files.wordpress.com/2016/01/aces_film_curve.png?w=576&#038;h=366" alt="ACES_film_curve" width="576" height="366" srcset="https://knarkowicz.files.wordpress.com/2016/01/aces_film_curve.png 576w, https://knarkowicz.files.wordpress.com/2016/01/aces_film_curve.png?w=150&amp;h=95 150w, https://knarkowicz.files.wordpress.com/2016/01/aces_film_curve.png?w=300&amp;h=191 300w" sizes="(max-width: 576px) 100vw, 576px" /></p>
<p><strong>UPDATE:</strong> This is a very simple luminance only fit, which over saturates brights. This was actually something consistent with our art direction, but for a more realistic rendering you may want a more complex fit like <a href="https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl">this one</a> from Stephen Hill.</p>
]]></html><thumbnail_url><![CDATA[https://knarkowicz.files.wordpress.com/2016/01/aces_film_curve.png?fit=440%2C330]]></thumbnail_url><thumbnail_width><![CDATA[440]]></thumbnail_width><thumbnail_height><![CDATA[280]]></thumbnail_height></oembed>