up close:
So here is a basic noise generator.
Code: Select all
// ALU noise in Next-gen post processing in COD:AW
float InterleavedGradientNoise( float2 uv )
{
float3 magic = { 0.06711056, 0.00583715, 52.9829189 };
return frac( magic.z * frac( dot( uv, magic.xy ) ) );
}
3 different alternatives here, linear, non-linear, energy-preserved
Code: Select all
float dither_amp = 1.0;
float noise = lerp(-0.5, 0.5, InterleavedGradientNoise( vPos )) * dither_amp; //or other noise method
//linear
color.xyz = color + noise / 255.0;
//non-linear
// color.xyz = pow( pow( color.xyz, 1.0 / 2.2) + noise / 255.0, 2.2);
//Energy-preserved
// color.xyz = pow(color.xyz, 1.0/2.2);
// color.xyz = color.xyz + noise * min(color.xyz + 0.5 * pow(1.0/255.0, 2.2), 0.75 * (pow(256.0/255.0, 2.2) - 1.0));
// color.xyz = pow(color.xyz, 2.2);
[gdc16] Advanced Techniques and Optimization of HDR Color Pipelines
Noted that the difference between these methods are less obvious on higher bit depth.
and a demo implementation on reference enbeffect.fx.