Tweaked HDR tone mapping and linear RGB bugfixes

This commit is contained in:
Robert Beckebans 2016-01-17 12:49:04 +01:00
parent d50c93f26f
commit 8f1512dc5e
7 changed files with 52 additions and 19 deletions

View file

@ -71,5 +71,5 @@ void main( PS_IN fragment, out PS_OUT result ) {
float4 envMap = texCUBE( samp0, reflectionVector );
result.color = float4( envMap.xyz, 1.0f ) * fragment.color;
result.color = float4( sRGBToLinearRGB( envMap.xyz ), 1.0f ) * fragment.color;
}

View file

@ -52,5 +52,5 @@ void main( PS_IN fragment, out PS_OUT result ) {
float4 envMap = texCUBE( samp0, reflectionVector );
result.color = float4( envMap.xyz, 1.0f ) * fragment.color;
result.color = float4( sRGBToLinearRGB( envMap.xyz ), 1.0f ) * fragment.color;
}

View file

@ -52,5 +52,5 @@ void main( PS_IN fragment, out PS_OUT result ) {
float4 envMap = texCUBE( samp0, reflectionVector );
result.color = float4( envMap.xyz, 1.0f ) * fragment.color;
result.color = float4( sRGBToLinearRGB( envMap.xyz ), 1.0f ) * fragment.color;
}

View file

@ -137,6 +137,20 @@ void main( PS_IN fragment, out PS_OUT result )
#elif OPERATOR == 2
// can be in range [-4.0 .. 4.0]
//float exposureOffset = rpScreenCorrectionFactor.w;
float avgLuminance = max( hdrAverageLuminance, 0.001 );
float linearExposure = ( hdrKey / avgLuminance );
float exposure = log2( max( linearExposure, 0.0001 ) );
//exposure = -2.0;
float3 exposedColor = exp2( exposure ) * color.rgb;
color.rgb = ACESFilm( exposedColor );
#elif OPERATOR == 3
// can be in range [-4.0 .. 4.0]
float exposure = rpScreenCorrectionFactor.w;
@ -148,7 +162,8 @@ void main( PS_IN fragment, out PS_OUT result )
float3 whiteScale = 1.0 / ACESFilm( float3( Ymax ) );
color.rgb = curr * whiteScale;
#elif OPERATOR == 3
#elif OPERATOR == 4
// Uncharted 2 tone mapping based on Kodak film curve
//float exposure = ( hdrKey / hdrAverageLuminance ) * 0.2;

View file

@ -41,5 +41,5 @@ struct PS_OUT {
};
void main( PS_IN fragment, out PS_OUT result ) {
result.color = texCUBE( samp0, fragment.texcoord0 ) * fragment.color;
result.color = sRGBAToLinearRGBA( texCUBE( samp0, fragment.texcoord0 ) ) * fragment.color;
}

View file

@ -247,11 +247,11 @@ idCVar r_shadowMapSunDepthBiasScale( "r_shadowMapSunDepthBiasScale", "0.999991",
// RB: HDR parameters
idCVar r_useHDR( "r_useHDR", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "use high dynamic range rendering" );
idCVar r_hdrAutoExposure( "r_hdrAutoExposure", "1", CVAR_RENDERER | CVAR_BOOL, "EXPENSIVE: enables adapative HDR tone mapping otherwise the exposure is derived by r_exposure" );
idCVar r_hdrMinLuminance( "r_hdrMinLuminance", "0.05", CVAR_RENDERER | CVAR_FLOAT, "" );
idCVar r_hdrMinLuminance( "r_hdrMinLuminance", "0.005", CVAR_RENDERER | CVAR_FLOAT, "" );
idCVar r_hdrMaxLuminance( "r_hdrMaxLuminance", "300", CVAR_RENDERER | CVAR_FLOAT, "" );
idCVar r_hdrKey( "r_hdrKey", "1.0", CVAR_RENDERER | CVAR_FLOAT, "mid-gray 0.5 in linear RGB space (without gamma curve applied)" );
idCVar r_hdrContrastDynamicThreshold( "r_hdrContrastDynamicThreshold", "33", CVAR_RENDERER | CVAR_FLOAT, "if dynamic tonemapping is on, all pixels brighter than this cause HDR bloom glares" );
idCVar r_hdrContrastStaticThreshold( "r_hdrContrastStaticThreshold", "0.5", CVAR_RENDERER | CVAR_FLOAT, "if dynamic tonemapping is off, all pixels brighter than this cause HDR bloom glares" );
idCVar r_hdrKey( "r_hdrKey", "0.015", CVAR_RENDERER | CVAR_FLOAT, "magic exposure key that works well with Doom 3 maps" );
idCVar r_hdrContrastDynamicThreshold( "r_hdrContrastDynamicThreshold", "2", CVAR_RENDERER | CVAR_FLOAT, "if auto exposure is on, all pixels brighter than this cause HDR bloom glares" );
idCVar r_hdrContrastStaticThreshold( "r_hdrContrastStaticThreshold", "3", CVAR_RENDERER | CVAR_FLOAT, "if auto exposure is off, all pixels brighter than this cause HDR bloom glares" );
idCVar r_hdrContrastOffset( "r_hdrContrastOffset", "100", CVAR_RENDERER | CVAR_FLOAT, "" );
idCVar r_hdrGlarePasses( "r_hdrGlarePasses", "8", CVAR_RENDERER | CVAR_INTEGER, "how many times the bloom blur is rendered offscreen. number should be even" );
idCVar r_hdrDebug( "r_hdrDebug", "0", CVAR_RENDERER | CVAR_FLOAT, "show scene luminance as heat map" );

View file

@ -1812,7 +1812,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs
idVec4 ambientColor;
float ambientBoost = 1.0f;
ambientBoost += r_useSSAO.GetBool() ? 0.5f : 0.0f;
ambientBoost += r_useSSAO.GetBool() ? 0.2f : 0.0f;
ambientBoost *= r_useHDR.GetBool() ? 1.1f : 1.0f;
ambientColor.x = r_forceAmbient.GetFloat() * ambientBoost;
ambientColor.y = r_forceAmbient.GetFloat() * ambientBoost;
@ -4242,7 +4242,7 @@ static void RB_CalculateAdaptation()
// no dynamic exposure
backEnd.hdrKey = r_hdrKey.GetFloat();
backEnd.hdrAverageLuminance = 1;
backEnd.hdrAverageLuminance = r_hdrMinLuminance.GetFloat();
backEnd.hdrMaxLuminance = 1;
}
else
@ -4392,21 +4392,39 @@ static void RB_Tonemap( const viewDef_t* viewDef )
float screenCorrectionParm[4];
if( viewDef->is2Dgui )
{
screenCorrectionParm[0] = 1.0f;
screenCorrectionParm[0] = 2.0f;
screenCorrectionParm[1] = 1.0f;
screenCorrectionParm[2] = 1.0f;
}
else
{
screenCorrectionParm[0] = backEnd.hdrKey;
screenCorrectionParm[1] = backEnd.hdrAverageLuminance;
screenCorrectionParm[2] = backEnd.hdrMaxLuminance;
if( r_hdrAutoExposure.GetBool() )
{
float exposureOffset = Lerp( -0.01f, 0.02f, idMath::ClampFloat( 0.0, 1.0, r_exposure.GetFloat() ) );
screenCorrectionParm[0] = backEnd.hdrKey + exposureOffset;
screenCorrectionParm[1] = backEnd.hdrAverageLuminance;
screenCorrectionParm[2] = backEnd.hdrMaxLuminance;
screenCorrectionParm[3] = exposureOffset;
//screenCorrectionParm[3] = Lerp( -1, 5, idMath::ClampFloat( 0.0, 1.0, r_exposure.GetFloat() ) );
}
else
{
//float exposureOffset = ( idMath::ClampFloat( 0.0, 1.0, r_exposure.GetFloat() ) * 2.0f - 1.0f ) * 0.01f;
float exposureOffset = Lerp( -0.01f, 0.01f, idMath::ClampFloat( 0.0, 1.0, r_exposure.GetFloat() ) );
screenCorrectionParm[0] = 0.015f + exposureOffset;
screenCorrectionParm[1] = 0.005f;
screenCorrectionParm[2] = 1;
// RB: this gives a nice exposure curve in Scilab when using
// log2( max( 3 + 0..10, 0.001 ) ) as input for exp2
//float exposureOffset = r_exposure.GetFloat() * 10.0f;
//screenCorrectionParm[3] = exposureOffset;
}
}
float exposure = ( r_exposure.GetFloat() * 2.0f - 1.0f ) * 4.0f;
//float exposure = r_exposure.GetFloat() * 2.0f;
screenCorrectionParm[3] = idMath::ClampFloat( -10.0f, 10.0f, exposure );
SetFragmentParm( RENDERPARM_SCREENCORRECTIONFACTOR, screenCorrectionParm ); // rpScreenCorrectionFactor
// Draw