FXAA and sRGB

Started by
5 comments, last by TimothyLottes 12 years, 8 months ago
I recently added the FXAA 3.9 shader into my application. In the original paper it is mentioned that special care needs to be taken in case of sRGB targets.
So I use a sRGB view when tonemapping and a RGB view when passing that texture to the FXAA. The FXAA renders to a RGB view of the sRGB backbuffer. Comparing this with just using sRGB views all the time I can not really see any difference. What should I be expecting?

Generally it seems to work just fine. Performance is great, but on the other hand it is relatively easy to find edges where it completely fails, at least in the scenes I tried.
Advertisement
I think the newer versions have a define in the shader that you enable if you want to work in linear space (which means you use SRGB targets and textures).
Comparing this with just using sRGB views all the time I can not really see any difference. What should I be expecting?
The intensity/luminosity calculations will produce slightly different results in linear VS sRGB. Doing it in sRGB will either over or under-estimate the actual intensity differences between two values.

e.g. say you've got two greyscale pixels next to each other, one at 100% intensity and the other at 50% intensity"
In 8-bit sRGB, those values correspond to 255 and 186.
In 8-bit linear, those values correspond to 255 and 127.

So, if you do your edge-detection calculations in sRGB, you'll incorrectly calculate that there's only a 27% difference in intensity, instead of the correct 50% difference.

Likewise, if we have two pixels at 50% and 0%:
In 8-bit sRGB, those values correspond to 186 and 0.
In 8-bit linear, those values correspond to 127 and 0.
If you do your edge-detection calculations in sRGB, you'll incorrectly calculate that there's a 73% difference in intensity, instead of the correct 50% difference.

[edit]Although, I'm a bit confused by this, because I was reading the latest version of the FXAA source code today, and it explicitly asks you to feed gamma-space luminance values into the algorithm...

I was reading the latest version of the FXAA source code today, and it explicitly asks you to feed gamma-space luminance values into the algorithm...

My tone mapping ends like this:



//...
return float4(color, luminance(color));
}

static const float3 g_luminanceVector = float3(0.299f, 0.587f, 0.114f);

float luminance(float3 color)
{
return dot(color, g_luminanceVector) + 0.0001f;
}


I render this to an sRGB target, which is then fed to the FXAA shader. Is this what you are talking about, or am I doing it wrong. Your explanation of the difference between targets makes sense to me, yet I cannot see the difference in the actual results.

I recently added the FXAA 3.9 shader into my application. In the original paper it is mentioned that special care needs to be taken in case of sRGB targets.
So I use a sRGB view when tonemapping and a RGB view when passing that texture to the FXAA. The FXAA renders to a RGB view of the sRGB backbuffer. Comparing this with just using sRGB views all the time I can not really see any difference. What should I be expecting?


I've tried it both ways too and I confirm that there's no visible difference between sRGB and non-SRGB colors. Anyway, do it with sRGB just to be sure you get optimal quality all the time.


Generally it seems to work just fine. Performance is great, but on the other hand it is relatively easy to find edges where it completely fails, at least in the scenes I tried.


Actually, I think it works almost flawlessly. Yes, it fails some edges but its not that common and in general FXAA is a real image quality booster for a reduced performance impact.
I found out what was wrong. When storing the luminance in the alpha channel it should be

sqrt(luminance(color))

but I was only doing

luminance(color)

instead. Fixing this improved the quality in virtually all places where I saw problems before.
For longer edges and better quality I would suggest using the latest FXAA 3.11: http://timothylottes.blogspot.com/2011/07/fxaa-311-released.html

The 3.10 release increased the quality on long edges and added back presets so the quality and performance can be tuned.

Absolutely for luma packed in the alpha channel, FXAA requires a non-linear luma. This can be confusing. FXAA 3 finds end-of-edge condition by checking how much the average of 2 or 4 pixels changes from an edge threshold which was computed near to the source pixel getting processed. This average is done by a fractional texel offset when sampling. Since end-of-edge is a visual test, the average needs to be perceptual (gamma 2.0 works well and is fast). Linear encoding will not work correctly as the linear average does not account for the fact that humans see a larger difference between intensity in darker colors than in lighter colors.

This topic is closed to new replies.

Advertisement