20161101 - Linear Dithering Before Transfer Function

Source Material
Fine Art of Film Grain
Grain and Fine Details
Advanced Techniques and Optimization of VDR Color Pipelines - Link to GDC presentation on this page

Extra Notes
The point of Fine Art of Film Grain was to show how to take an artist generated grain texture, specifically something which isn't a perfect repeating blue noise texture, and make it energy conserving so it can serve double usage as video grain and dithering. Bart Wronski's Dithering Part Two - Golden Ratio Sequence, Blue Noise and Highpass and Remap qualifies the frequency domain output of repeated highpass with remap used to reshape a poor quality noise. The technique I use to generate an artistic grain texture is a little different, I would do many repeated highpass passes, and only at the end do one remap step.

Linear Dither Before Non-Linear Quantization
My VDR GDC presentation talked about this, but the slides don't go into enough detail on why. This as an alternative method of quantization to the traditional quantization in the non-linear output space. Both have various cost/quality trade-offs.

In order for a dither to be energy conserving, meaning not introduce any bias into the signal temporally, on a still image, the average of the output values over time should be the non-dithered input. Best way to test this is to try to dither to 2-bits/channel on a color photograph with a temporal dither. If the photo's contrast or saturation changes, then a bias had been introduced in the signal.

Near black, bias can also be a large problem. To avoid any bias, over time, any amount of positive dithering must be matched with a linearly equal amount of negative dithering temporally. However the display and signal cannot reproduce negative luma. So dithering must be adjusted as image luma approaches zero (talked about around slide 95-96 in my GDC presentation).

In a 2-bit/channel dithering ground truth test, a similar adjustment must be done to the whites. However in practice I don't do the correction for whites with typical 8-bit output, because I don't feel it is perceptually important. It is perceptually important in the darks, and note be very careful here, because some displays like WRGB OLED TVs clamp a large range of darks to zero by default. Evaluation of darks need to be done in a theater black ambient level room with a very low APL scene on a calibrated display which is actually capable of correct black output close to zero.

Hardware ROP rounds to nearest in the non-linear output space. Linearly speaking, this rounding is biased where the bias changes based on the slope of the transfer function for the non-linear output space. Likewise if a dither is added after the linear to non-linear transform, then equal positive and negative dither contribution to that non-linear signal before quantization will also have bias (which changes based on the slope of the transfer function).

While it is possible to correct for bias with dithering in the non-linear output space, I find it excessively expensive to do so in real-time. The solution I use instead is to introduce dither linearly with enough dither so that there are no bands of unchanging values, and so that the final non-linear quantized value is temporally switching between at least 2-3 values. Given the linear dithered value, it is possible to do linear nearest quantization in the shader instead of letting the hardware do non-linear nearest in say a 10:10:10:2 non-linear output.

Lastly, when adding grain/dither linearly with output PQ2048 transfer functions, an energy conserving asymmetrical grain distribution must be used (covered around slide 99 in my GDC presentation).