Hi all,
Now that I've got my specular normalization working, I tried to play around with several tone mapping options (not doing any HDR so far), based on this article:
http://filmicworlds.com/blog/filmic-tonemapping-operators/
After trying out a number of them, I'm wondering if there's maybe something wrong with the approach in general.
The HLSL code is pasted below with some shots of the results. Any input is appreciated.
Also, which one would you say looks best? (knowing this is a preference/ taste thing perhaps).
A = linear exposure, so input color * 8
B = linear exposure / (1 + linear exposure) (Reinhard)
C = Jim Hejl and Richard Burgess-Dawson
D = Uncharted 2
In all cases I left out the linear to sRGB/ gamma conversion, because I let DX11 handle this through the proper RT/ texture buffer formats. Also good to know, the scene has relatively low ambient light (0.15, 0.15, 0.15), and the directional light (moon) has intensity 0.3 (color 1/1/1).
float3 ToneMapA(float3 pInputColor, uint pExposureMul)
{
float3 output = pInputColor * pExposureMul;
//output = pow(output, 1/2.2f);
return output;
}
float3 ToneMapB(float3 pInputColor, uint pExposureMul)
{
float3 output = pInputColor * pExposureMul;
output = output / (1.0f + output);
//output = pow(output, 1/2.2f);
return output;
}
float3 ToneMapC(float3 pInputColor, uint pExposureMul)
{
float3 output = pInputColor * pExposureMul;
float3 x = max(0, output-0.004);
float3 retColor = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06);
//retColor = pow(retColor, 1/2.2f);
return retColor;
}
float3 ToneMapD(float3 x) // used for uncharted
{
float A = 0.15;
float B = 0.50;
float C = 0.10;
float D = 0.20;
float E = 0.02;
float F = 0.30;
float W = 11.2;
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
}
float3 ToneMapUncharted(float3 pInputColor, uint pExposureMul)
{
float W = 11.2;
float3 output = pInputColor * pExposureMul;
float ExposureBias = 2.0f;
float3 curr = ToneMapD(ExposureBias * output);
float3 whiteScale = 1.0f/ToneMapD(W);
float3 color = curr * whiteScale;
//float3 retColor = pow(color,1/2.2);
return color;
}
// PIXEL SHADER (example, could be options A, B, C or Uncharted
if(gPerMaterial.Material.IsMetal)
final.rgb = d + sMetal;
else
final.rgb = d + sNonMetal;
final.rgb = ToneMapC(final.rgb, 8);
// or when I test with tone mapping the lighting part only
float3 diffuse = ToneMapA(lightSetup.DiffuseAcc, 8);
float3 specular = ToneMapA(lightSetup.SpecularAcc, 8);
float3 d = diffuse * texColor.rgb * gPerMaterial.Material.Diffuse.rgb;
float3 sMetal = specular * (texColor.rgb * 2.0f);
float3 sNonMetal = specular;
if(gPerMaterial.Material.IsMetal)
final.rgb = d + sMetal;
else
final.rgb = d + sNonMetal;
return final;
Off:
A - linear - exposure 8 (ALL):
A - linear - exposure 8 - only applied to lighting:
B - Reinhard - exposure 8 - ALL
B - Reinhard - exposure 8 - only applied to lighting
C - Jim Hejl and Richard Burgess-Dawson - exposure 8 = ALL
C - Jim Hejl and Richard Burgess-Dawson - exposure 8 - only applied to lighting
D - Uncharted 2 - exposure 8 - all
D - Uncharted 2 - exposure 8 - only applied to lighting