Improved linear RGB lighting and added ACES tonemap

This commit is contained in:
Robert Beckebans 2016-01-13 20:33:16 +01:00
parent a96eb702b5
commit f82b700598
12 changed files with 170 additions and 202 deletions

View file

@ -75,7 +75,7 @@ const float invRadius2 = 1.0 / radius2;
const float bias = 0.01 * METERS_TO_DOOM;
/** intensity / radius^6 */
const float intensity = 0.3;
const float intensity = 0.6;
const float intensityDivR6 = intensity / ( radius* radius* radius* radius* radius* radius );
/** The height in pixels of a 1m object if viewed from 1m away.

View file

@ -12,7 +12,7 @@
#define USE_OCT16 0
#define COMPUTE_PEELED_LAYER 0
#define USE_MIPMAPS 1
#define USE_TAP_NORMAL 0
#define USE_TAP_NORMAL 1
#define HIGH_QUALITY 0
@ -473,8 +473,8 @@ void sampleIndirectLight
numSamplesUsed += weight_Y;
#endif
//irradianceSum += E;
irradianceSum += pow( E, float3( 2.2 ) ); // RB: to linear RGB
irradianceSum += E;
//irradianceSum += pow( E, float3( 2.2 ) ); // RB: to linear RGB
}
@ -535,8 +535,8 @@ void main( PS_IN fragment, out PS_OUT result )
const float solidAngleHemisphere = 2 * PI;
float3 E_X = irradianceSum * solidAngleHemisphere / ( numSamplesUsed + 0.00001 );
//indirectColor = E_X;
indirectColor = pow( E_X, float3( 1.0 / 2.2 ) ); // RB: to sRGB
indirectColor = E_X;
//indirectColor = pow( E_X, float3( 1.0 / 2.2 ) ); // RB: to sRGB
// What is the ambient visibility of this location
visibility = 1 - numSamplesUsed / float( NUM_SAMPLES );

View file

@ -75,8 +75,8 @@ void main( PS_IN fragment, out PS_OUT result ) {
// RB: added abs
half3 specularContribution = _half3( pow( abs( hDotN ), specularPower ) );
half3 diffuseColor = diffuseMap * sRGBToLinearRGB( rpDiffuseModifier.xyz ) * 1.5f;
half3 specularColor = specMap.xyz * specularContribution * sRGBToLinearRGB( rpSpecularModifier.xyz );
half3 diffuseColor = diffuseMap * ( rpDiffuseModifier.xyz ) * 1.5f;
half3 specularColor = specMap.xyz * specularContribution * ( rpSpecularModifier.xyz );
// RB: http://developer.valvesoftware.com/wiki/Half_Lambert
float halfLdotN = dot3( localNormal, lightVector ) * 0.5 + 0.5;
@ -92,6 +92,7 @@ void main( PS_IN fragment, out PS_OUT result ) {
half3 rimColor = sRGBToLinearRGB( half3( 0.125 ) * 1.2 ) * lightColor * pow( rim, rimPower );
//result.color.rgb = localNormal.xyz * 0.5 + 0.5;
result.color.xyz = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor + rimColor ) * fragment.color.rgb;;
result.color.w = 1.0;
result.color.xyz = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor + rimColor ) * fragment.color.rgb;
//result.color = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor + rimColor ) * fragment.color.rgba;
result.color.w = fragment.color.a;
}

View file

@ -134,7 +134,7 @@ static float dot4( float2 a, float4 b ) { return dot( float4( a, 0, 1 ), b ); }
half3 sRGBToLinearRGB( half3 rgb )
{
#if defined(USE_SRGB)
return pow( rgb, half3( 2.2 ) );
return max( pow( rgb, half3( 2.2 ) ), half3( 0.0 ) );
#else
return rgb;
#endif
@ -143,7 +143,7 @@ half3 sRGBToLinearRGB( half3 rgb )
half4 sRGBAToLinearRGBA( half4 rgba )
{
#if defined(USE_SRGB)
return pow( rgba, half4( 2.2 ) );
return float4( max( pow( rgba.rgb, half3( 2.2 ) ), half3( 0.0 ) ), rgba.a );
#else
return rgba;
#endif
@ -243,7 +243,8 @@ static const half4 LUMINANCE_LINEAR = half4( 0.299, 0.587, 0.144, 0.0 );
static float4 idtex2Dproj( sampler2D samp, float4 texCoords ) { return tex2Dproj( samp, texCoords.xyw ); }
static float4 swizzleColor( float4 c )
{
return sRGBAToLinearRGBA( c );
return c;
//return sRGBAToLinearRGBA( c );
}
static float2 vposToScreenPosTexCoord( float2 vpos ) { return vpos.xy * rpWindowCoord.xy; }

View file

@ -60,12 +60,12 @@ void main( PS_IN fragment, out PS_OUT result )
half4 lightFalloff = ( idtex2Dproj( samp1, fragment.texcoord2 ) );
half4 lightProj = ( idtex2Dproj( samp2, fragment.texcoord3 ) );
half4 YCoCG = tex2D( samp3, fragment.texcoord4.xy );
half4 specMap = sRGBAToLinearRGBA( tex2D( samp4, fragment.texcoord5.xy ) );
half4 specMapSRGB = tex2D( samp4, fragment.texcoord5.xy );
half4 specMap = sRGBAToLinearRGBA( specMapSRGB );
half3 lightVector = normalize( fragment.texcoord0.xyz );
half3 viewVector = normalize( fragment.texcoord6.xyz );
half3 diffuseMap = sRGBToLinearRGB( ConvertYCoCgToRGB( YCoCG ) );
//diffuseMap.r = 1.0;
half3 localNormal;
// RB begin
@ -95,105 +95,76 @@ void main( PS_IN fragment, out PS_OUT result )
half3 halfAngleVector = normalize( lightVector + viewVector );
half hdotN = saturate( dot3( halfAngleVector, localNormal ) );
#if 1
/*
Physically based shading
#if 0 //defined(USE_PBR)
#if 0 //defined(USE_METALNESS)
const half metallic = specMapSRGB.g;
const half roughness = specMapSRGB.r;
const half glossiness = 1.0 - roughness;
// the vast majority of real-world materials (anything not metal or gems) have F(0°)
// values in a very narrow range (~0.02 - 0.08)
Lambert diffuse BRDF combined with Cook-Torrance microfacet specular BRDF
// approximate non-metals with linear RGB 0.04 which is 0.08 * 0.5 (default in UE4)
const half3 dielectricColor = half3( 0.04 );
D( h ) * F( v, h ) * G( l, v, h )
f( l, v ) = diffuse + ---------------------------------
4 * ( n * l ) ( n * v )
*/
// RB: compensate r_lightScale 3 and the division of Pi
lambert *= 1.3;
const half3 goldColor = half3( 1.00, 0.71, 0.29 );
//const half3 baseColor = goldColor;
// derive diffuse and specular from albedo(m) base color
const half3 baseColor = diffuseMap;
const half metallic = 0.0;
// rpDiffuseModifier contains light color
half3 lightColor = lightProj.xyz * lightFalloff.xyz * rpDiffuseModifier.xyz;
half vdotN = saturate( dot3( viewVector, localNormal ) );
half vdotH = saturate( dot3( viewVector, halfAngleVector ) );
// the vast majority of real-world materials (anything not metal or gems) have F(0°) values in a very narrow range (~0.02 - 0.06)
half3 diffuseColor = baseColor * ( 1.0 - metallic );
half3 specularColor = lerp( dielectricColor, baseColor, metallic );
#else
// HACK calculate roughness from D3 gloss maps
// converting from linear to sRGB space give pretty results
const half glossiness = clamp( pow( dot( LUMINANCE_VECTOR.rgb, specMap.rgb ) * 0.4, 1.0 / 2.2 ) * 1.0, 0.0, 0.98 );
float Y = dot( LUMINANCE_SRGB.rgb, specMapSRGB.rgb );
const half roughness = 1.0 - glossiness;
//const float glossiness = clamp( 1.0 - specMapSRGB.r, 0.0, 0.98 );
const float glossiness = clamp( pow( Y, 1.0 / 2.0 ), 0.0, 0.98 );
const float roughness = 1.0 - glossiness;
half3 diffuseColor = diffuseMap;
half3 specularColor = specMap.rgb;
#endif
// RB: compensate r_lightScale 3 and the division of Pi
//lambert *= 1.3;
// rpDiffuseModifier contains light color multiplier
half3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );// * rpDiffuseModifier.xyz;
half vdotN = clamp( dot3( viewVector, localNormal ), 0.0, 1.0 );
half vdotH = clamp( dot3( viewVector, halfAngleVector ), 0.0, 1.0 );
half ldotH = clamp( dot3( lightVector, halfAngleVector ), 0.0, 1.0 );
// compensate r_lightScale 3 * 2
half3 reflectColor = specMap.rgb * rpSpecularModifier.rgb * 0.5;
half3 reflectColor = specMap.rgb * rpSpecularModifier.rgb * 1.0;// * 0.5;
// alpha modifications by Disney - s2012_pbs_disney_brdf_notes_v2.pdf
const half alpha = roughness * roughness;
// cheap approximation by ARM with only one division
// http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
// page 26
// reduce roughness range from [0 .. 1] to [0.5 .. 1]
const half alphaG = pow( 0.5 + roughness * 0.5, 2.0 );
//half3 D = _half3( pow( abs( hdotN ), 10.0f ) );
half3 D = _half3( Distribution_GGX( hdotN, alpha ) );
//half3 D = _half3( Distribution_GGX_1886( hdotN, alpha ) );
half3 G = _half3( Visibility_Schlick( ldotN, vdotN, alpha ) );
//half3 G = _half3( Visibility_SmithGGX( ldotN, vdotN, alpha ) );
half3 F = Fresnel_Schlick( reflectColor, vdotH );
// horizon
float horizon = 1.0 - ldotN;
horizon *= horizon;
horizon *= horizon;
half3 specLightColor = lightColor.rgb - lightColor.rgb * horizon;
float3 specularColor = saturate( D * G * ( F * ( specLightColor.rgb * lambert ) ) );
//specularColor = EnvironmentBRDFApprox( roughness, vdotN, specularColor.rgb );// * 0.45;
float rr = roughness * roughness;
float rrrr = rr * rr;
// disney GGX
float D = ( hdotN * hdotN ) * ( rrrr - 1.0 ) + 1.0;
float VFapprox = ( ldotH * ldotH ) * ( roughness + 0.5 );
half3 specularBRDF = ( rrrr / ( 4.0 * PI * D * D * VFapprox ) ) * reflectColor;
//specularBRDF = half3( 0.0 );
#if 0
result.color = float4( _half3( F ), 1.0 );
result.color = float4( _half3( VFapprox ), 1.0 );
return;
#endif
// see http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
lambert /= PI;
//lambert /= PI;
//half3 diffuseColor = mix( diffuseMap, F0, metal ) * rpDiffuseModifier.xyz;
half3 diffuseColor = baseColor * rpDiffuseModifier.xyz;
diffuseColor *= lightColor * lambert;
/*
maintain energy conservation
Energy conservation is a restriction on the reflection model
that requires that the total amount of reflected light
cannot be more than the incoming light.
half3 diffuseBRDF = diffuseColor * lambert * sRGBToLinearRGB( rpDiffuseModifier.xyz );
http://www.rorydriscoll.com/2009/01/25/energy-conservation-in-games/
Cdiff + Cspec <= 1
*/
//diffuseColor.rgb *= ( half3( 1.0 ) - specularColor.rgb );
#if 0 //defined(USE_METALNESS)
//specularColor *= ( 0.96 * metallic ) * diffuseColor + half( 0.04 );
diffuseColor.rgb *= ( 1.0 - metallic );
//diffuseColor.rgb = mix( diffuseColor, specularColor, metallic );
#endif
// apply r_lightScale overbright for both diffuse and specular
result.color.xyz = ( diffuseColor + specularColor ) * fragment.color.rgb;// + rimColor;
result.color.xyz = ( diffuseBRDF + specularBRDF ) * lightColor * fragment.color.rgb * shadow;
result.color.w = 1.0;
#else
@ -205,11 +176,11 @@ void main( PS_IN fragment, out PS_OUT result )
const half specularPower = 10.0f;
// RB: added abs
half3 specularContribution = _half3( pow( abs( hdotN ), specularPower ) );
half3 specularContribution = _half3( pow( hdotN, specularPower ) );
half3 diffuseColor = diffuseMap * sRGBToLinearRGB( rpDiffuseModifier.xyz );
half3 specularColor = specMap.xyz * specularContribution * sRGBToLinearRGB( rpSpecularModifier.xyz * 1.0 );
half3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );
half3 specularColor = specMap.xyz * specularContribution * sRGBToLinearRGB( rpSpecularModifier.xyz );
half3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );
/*
half rim = 1.0f - saturate( hdotN );

View file

@ -67,7 +67,8 @@ void main( PS_IN fragment, out PS_OUT result )
half4 lightFalloff = ( idtex2Dproj( samp1, fragment.texcoord2 ) );
half4 lightProj = ( idtex2Dproj( samp2, fragment.texcoord3 ) );
half4 YCoCG = tex2D( samp3, fragment.texcoord4.xy );
half4 specMap = sRGBAToLinearRGBA( tex2D( samp4, fragment.texcoord5.xy ) );
half4 specMapSRGB = tex2D( samp4, fragment.texcoord5.xy );
half4 specMap = sRGBAToLinearRGBA( specMapSRGB );
half3 lightVector = normalize( fragment.texcoord0.xyz );
half3 viewVector = normalize( fragment.texcoord6.xyz );
@ -272,107 +273,78 @@ void main( PS_IN fragment, out PS_OUT result )
half3 halfAngleVector = normalize( lightVector + viewVector );
half hdotN = saturate( dot3( halfAngleVector, localNormal ) );
half hdotN = clamp( dot3( halfAngleVector, localNormal ), 0.0, 1.0 );
#if 1
/*
Physically based shading
#if 0 //defined(USE_PBR)
#if 0 //defined(USE_METALNESS)
const half metallic = specMapSRGB.g;
const half roughness = specMapSRGB.r;
const half glossiness = 1.0 - roughness;
// the vast majority of real-world materials (anything not metal or gems) have F(0°)
// values in a very narrow range (~0.02 - 0.08)
Lambert diffuse BRDF combined with Cook-Torrance microfacet specular BRDF
// approximate non-metals with linear RGB 0.04 which is 0.08 * 0.5 (default in UE4)
const half3 dielectricColor = half3( 0.04 );
D( h ) * F( v, h ) * G( l, v, h )
f( l, v ) = diffuse + ---------------------------------
4 * ( n * l ) ( n * v )
*/
// RB: compensate r_lightScale 3 and the division of Pi
lambert *= 1.3;
const half3 goldColor = half3( 1.00, 0.71, 0.29 );
//const half3 baseColor = goldColor;
// derive diffuse and specular from albedo(m) base color
const half3 baseColor = diffuseMap;
const half metallic = 0.0;
// rpDiffuseModifier contains light color
half3 lightColor = lightProj.xyz * lightFalloff.xyz * rpDiffuseModifier.xyz;
half vdotN = saturate( dot3( viewVector, localNormal ) );
half vdotH = saturate( dot3( viewVector, halfAngleVector ) );
// the vast majority of real-world materials (anything not metal or gems) have F(0°) values in a very narrow range (~0.02 - 0.06)
half3 diffuseColor = baseColor * ( 1.0 - metallic );
half3 specularColor = lerp( dielectricColor, baseColor, metallic );
#else
// HACK calculate roughness from D3 gloss maps
// converting from linear to sRGB space give pretty results
const half glossiness = clamp( pow( dot( LUMINANCE_VECTOR.rgb, specMap.rgb ) * 0.4, 1.0 / 2.2 ) * 1.0, 0.0, 0.98 );
float Y = dot( LUMINANCE_SRGB.rgb, specMapSRGB.rgb );
const half roughness = 1.0 - glossiness;
//const float glossiness = clamp( 1.0 - specMapSRGB.r, 0.0, 0.98 );
const float glossiness = clamp( pow( Y, 1.0 / 2.0 ), 0.0, 0.98 );
const float roughness = 1.0 - glossiness;
half3 diffuseColor = diffuseMap;
half3 specularColor = specMap.rgb;
#endif
// RB: compensate r_lightScale 3 and the division of Pi
//lambert *= 1.3;
// rpDiffuseModifier contains light color multiplier
half3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );// * rpDiffuseModifier.xyz;
half vdotN = clamp( dot3( viewVector, localNormal ), 0.0, 1.0 );
half vdotH = clamp( dot3( viewVector, halfAngleVector ), 0.0, 1.0 );
half ldotH = clamp( dot3( lightVector, halfAngleVector ), 0.0, 1.0 );
// compensate r_lightScale 3 * 2
half3 reflectColor = specMap.rgb * rpSpecularModifier.rgb * 0.5;
half3 reflectColor = specMap.rgb * rpSpecularModifier.rgb * 1.0;// * 0.5;
// alpha modifications by Disney - s2012_pbs_disney_brdf_notes_v2.pdf
const half alpha = roughness * roughness;
// cheap approximation by ARM with only one division
// http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
// page 26
// reduce roughness range from [0 .. 1] to [0.5 .. 1]
const half alphaG = pow( 0.5 + roughness * 0.5, 2.0 );
//half3 D = _half3( pow( abs( hdotN ), 10.0f ) );
half3 D = _half3( Distribution_GGX( hdotN, alpha ) );
//half3 D = _half3( Distribution_GGX_1886( hdotN, alpha ) );
half3 G = _half3( Visibility_Schlick( ldotN, vdotN, alpha ) );
//half3 G = _half3( Visibility_SmithGGX( ldotN, vdotN, alpha ) );
half3 F = Fresnel_Schlick( reflectColor, vdotH );
// horizon
float horizon = 1.0 - ldotN;
horizon *= horizon;
horizon *= horizon;
half3 specLightColor = lightColor.rgb - lightColor.rgb * horizon;
float3 specularColor = saturate( D * G * ( F * ( specLightColor.rgb * lambert ) ) );
//specularColor = EnvironmentBRDFApprox( roughness, vdotN, specularColor.rgb );// * 0.45;
float rr = roughness * roughness;
float rrrr = rr * rr;
// disney GGX
float D = ( hdotN * hdotN ) * ( rrrr - 1.0 ) + 1.0;
float VFapprox = ( ldotH * ldotH ) * ( roughness + 0.5 );
half3 specularBRDF = ( rrrr / ( 4.0 * PI * D * D * VFapprox ) ) * reflectColor;
//specularBRDF = half3( 0.0 );
#if 0
result.color = float4( _half3( F ), 1.0 );
result.color = float4( _half3( VFapprox ), 1.0 );
return;
#endif
// see http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
lambert /= PI;
//lambert /= PI;
//half3 diffuseColor = mix( diffuseMap, F0, metal ) * rpDiffuseModifier.xyz;
half3 diffuseColor = baseColor * rpDiffuseModifier.xyz;
diffuseColor *= lightColor * lambert;
/*
maintain energy conservation
Energy conservation is a restriction on the reflection model
that requires that the total amount of reflected light
cannot be more than the incoming light.
half3 diffuseBRDF = diffuseColor * lambert * sRGBToLinearRGB( rpDiffuseModifier.xyz );
http://www.rorydriscoll.com/2009/01/25/energy-conservation-in-games/
Cdiff + Cspec <= 1
*/
//diffuseColor.rgb *= ( half3( 1.0 ) - specularColor.rgb );
#if 0 //defined(USE_METALNESS)
//specularColor *= ( 0.96 * metallic ) * diffuseColor + half( 0.04 );
diffuseColor.rgb *= ( 1.0 - metallic );
//diffuseColor.rgb = mix( diffuseColor, specularColor, metallic );
#endif
// apply r_lightScale overbright for both diffuse and specular
result.color.xyz = ( diffuseColor + specularColor ) * fragment.color.rgb * shadow;// + rimColor;
result.color.xyz = ( diffuseBRDF + specularBRDF ) * lightColor * fragment.color.rgb * shadow;
result.color.w = 1.0;
#else
@ -384,11 +356,11 @@ void main( PS_IN fragment, out PS_OUT result )
const half specularPower = 10.0f;
// RB: added abs
half3 specularContribution = _half3( pow( abs( hdotN ), specularPower ) );
half3 specularContribution = _half3( pow( hdotN, specularPower ) );
half3 diffuseColor = diffuseMap * rpDiffuseModifier.xyz;
half3 specularColor = specMap.xyz * specularContribution * rpSpecularModifier.xyz;
half3 lightColor = lightProj.xyz * lightFalloff.xyz;
half3 diffuseColor = diffuseMap * sRGBToLinearRGB( rpDiffuseModifier.xyz );
half3 specularColor = specMap.xyz * specularContribution * sRGBToLinearRGB( rpSpecularModifier.xyz );
half3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );
/*
half rim = 1.0f - saturate( hdotN );

View file

@ -43,5 +43,5 @@ struct PS_OUT {
void main( PS_IN fragment, out PS_OUT result ) {
float4 color = tex2D( samp0, fragment.texcoord0 ) * fragment.color;
clip( color.a - rpAlphaTest.x );
result.color = color;
result.color = sRGBAToLinearRGBA( color );
}

View file

@ -43,5 +43,5 @@ struct PS_OUT {
void main( PS_IN fragment, out PS_OUT result ) {
float4 color = tex2D( samp0, fragment.texcoord0 ) * fragment.color;
clip( color.a - rpAlphaTest.x );
result.color = color;
result.color = sRGBAToLinearRGBA( color );
}

View file

@ -48,5 +48,5 @@ void main( PS_IN fragment, out PS_OUT result ) {
// gets called.
float4 texSample = idtex2Dproj( samp0, fragment.texcoord0 );
result.color = texSample * fragment.color;
result.color = sRGBAToLinearRGBA( texSample ) * fragment.color;
}

View file

@ -43,19 +43,32 @@ struct PS_OUT
float4 color : COLOR;
};
float A = 0.22; // shoulder strength
float B = 0.3; // linear strength
float C = 0.10; // linear angle
float D = 0.20; // toe strength
float E = 0.01; // toe numerator
float F = 0.30; // toe denominator
float W = 11.2; // linear white point
float3 Uncharted2Tonemap( float3 x )
{
float A = 0.22; // shoulder strength
float B = 0.3; // linear strength
float C = 0.10; // linear angle
float D = 0.20; // toe strength
float E = 0.01; // toe numerator
float F = 0.30; // toe denominator
float W = 11.2; // linear white point
return ( ( x * ( A * x + C * B ) + D * E ) / ( x * ( A * x + B ) + D * F ) ) - E / F;
}
// https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
float3 ACESFilm( float3 x )
{
float a = 2.51;
float b = 0.03;
float c = 2.43;
float d = 0.59;
float e = 0.14;
return saturate( ( x * ( a * x + b ) ) / ( x * ( c * x + d ) + e ) );
}
void main( PS_IN fragment, out PS_OUT result )
{
float2 tCoords = fragment.texcoord0;
@ -98,18 +111,20 @@ void main( PS_IN fragment, out PS_OUT result )
float Ymax = hdrMaxLuminance;
#define OPERATOR 2
#if 0
#if OPERATOR == 0
// advanced Reinhard operator, artistically desirable to burn out bright areas
float L = Yr * ( 1.0 + Yr / ( Ymax * Ymax ) ) / ( 1.0 + Yr );
color.rgb *= L;
#elif OPERATOR == 1
// http://freespace.virgin.net/hugo.elias/graphics/x_posure.htm
// exponential tone mapper that is very similar to the Uncharted one
// very good in keeping the colors natural
//float exposure = 1.0;
//float L = ( 1.0 - exp( -Yr * exposure ) );
//color.rgb *= L;
float exposure = 1.0;
float L = ( 1.0 - exp( -Yr * exposure ) );
color.rgb *= L;
// Kodak filmic tone mappping, includes gamma correction
//float3 rgb = max( float3( 0 ), color.rgb - float3( 0.004 ) );
@ -120,7 +135,15 @@ void main( PS_IN fragment, out PS_OUT result )
//color.rgb += ( cutoff * 2.0 - color.rgb ) * saturate( cutoff * 2 - color.rgb ) * ( 0.25 / cutoff ) - cutoff;
//color.rgb = color.rgb * ( float3( 0.5 ) + 6.2 * color.rgb ) / ( float3( 0.06 ) + color.rgb * ( float3( 1.7 ) + 6.2 * color.rgb ) );
#else
#elif OPERATOR == 2
float exposure = 1.0;
float3 exposedColor = exposure * color.rgb;
float3 curr = ACESFilm( exposedColor );
float3 whiteScale = 1.0 / ACESFilm( float3( Ymax ) );
color.rgb = curr * whiteScale;
#elif OPERATOR == 3
// Uncharted 2 tone mapping based on Kodak film curve
//float exposure = ( hdrKey / hdrAverageLuminance ) * 0.2;

View file

@ -248,8 +248,8 @@ idCVar r_shadowMapSunDepthBiasScale( "r_shadowMapSunDepthBiasScale", "0.999991",
idCVar r_useHDR( "r_useHDR", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "use high dynamic range rendering" );
idCVar r_hdrMinLuminance( "r_hdrMinLuminance", "0.05", CVAR_RENDERER | CVAR_FLOAT, "" );
idCVar r_hdrMaxLuminance( "r_hdrMaxLuminance", "300", CVAR_RENDERER | CVAR_FLOAT, "" );
idCVar r_hdrKey( "r_hdrKey", "0.5", CVAR_RENDERER | CVAR_FLOAT, "mid-gray 0.5 in linear RGB space (without gamma curve applied)" );
idCVar r_hdrContrastThreshold( "r_hdrContrastThreshold", "13", CVAR_RENDERER | CVAR_FLOAT, "all pixels brighter than this cause HDR bloom glares" );
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_hdrContrastThreshold( "r_hdrContrastThreshold", "33", CVAR_RENDERER | CVAR_FLOAT, "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

@ -5244,7 +5244,7 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye )
//-------------------------------------------------
// darken the scene using the screen space ambient occlusion result
//-------------------------------------------------
//RB_SSAO( viewDef );
RB_SSAO( viewDef );
//RB_SSGI( viewDef );
//-------------------------------------------------
@ -5271,7 +5271,7 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye )
//-------------------------------------------------
// use direct light and emissive light contributions to add indirect screen space light
//-------------------------------------------------
RB_SSGI( viewDef );
//RB_SSGI( viewDef );
//-------------------------------------------------
// fog and blend lights, drawn after emissive surfaces