mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 22:50:45 +00:00
Added Contrast Adaptive Sharpening (AMD) by Justin Marshal (IcedTech)
This commit is contained in:
parent
5dedbc70a6
commit
558afdd093
6 changed files with 390 additions and 30 deletions
|
@ -77,6 +77,8 @@ The main goal is that the new content looks the same in RBDOOM-3-BFG as in Blend
|
|||
|
||||
* Added Blue Noise based Filmic Dithering by Timothy Lottes and Chromatic Aberration
|
||||
|
||||
* Added Contrast Adaptive Sharpening (AMD) from Just Marshal (IcedTech)
|
||||
|
||||
* Improved Shadow Mapping quality with Vogel Disk Sampling by Panos Karabelas and using dithering the result with Blue Noise magic by Alan Wolfe
|
||||
|
||||
* Improved Screen Space Ambient Occlusion performance by enhancing the quality with Blue Noise and skipping the expensive extra bilateral filtering pass
|
||||
|
|
|
@ -335,32 +335,39 @@ float3 Hash33( float3 p3 )
|
|||
return fract( ( p3.xxy + p3.yxx ) * p3.zyx );
|
||||
}
|
||||
|
||||
static float3 ditherRGB( float3 c, float2 uvSeed )
|
||||
static float3 ditherRGB( float3 color, float2 uvSeed, float quantSteps )
|
||||
{
|
||||
// uniform noise
|
||||
//float3 whiteNoise = Hash33( float3( uvSeed, rpJitterTexOffset.w ) );
|
||||
//float3 noise = Hash33( float3( uvSeed, rpJitterTexOffset.w ) );
|
||||
|
||||
//float3 whiteNoise = float3( InterleavedGradientNoise( uvSeed ) );
|
||||
float3 whiteNoise = float3( InterleavedGradientNoiseAnim( uvSeed, rpJitterTexOffset.w ) );
|
||||
//float3 noise = float3( InterleavedGradientNoise( uvSeed ) );
|
||||
float3 noise = float3( InterleavedGradientNoiseAnim( uvSeed, rpJitterTexOffset.w ) );
|
||||
|
||||
|
||||
// triangular noise [-0.5;1.5[
|
||||
|
||||
#if 1
|
||||
whiteNoise.x = RemapNoiseTriErp( whiteNoise.x );
|
||||
whiteNoise = whiteNoise * 2.0 - 0.5;
|
||||
noise.x = RemapNoiseTriErp( noise.x );
|
||||
noise = noise * 2.0 - 0.5;
|
||||
#endif
|
||||
|
||||
whiteNoise = float3( whiteNoise.x );
|
||||
noise = float3( noise.x );
|
||||
|
||||
|
||||
// quantize/truncate color and dither the result
|
||||
//float scale = exp2( float( TARGET_BITS ) ) - 1.0;
|
||||
|
||||
// lets assume 2^3 bits = 8
|
||||
float scale = 255.0;
|
||||
//float scale = 7.0;
|
||||
//const float quantSteps = 8.0;
|
||||
float scale = quantSteps - 1.0;
|
||||
|
||||
float3 color = floor( c * scale + whiteNoise ) / scale;
|
||||
// apply dither
|
||||
color += noise / ( quantSteps );
|
||||
|
||||
color = floor( color * scale ) / scale;
|
||||
|
||||
//float3 color = c + whiteNoise / 255.0;
|
||||
|
||||
#if defined( USE_LINEAR_RGB )
|
||||
|
||||
|
@ -368,3 +375,37 @@ static float3 ditherRGB( float3 c, float2 uvSeed )
|
|||
|
||||
return color;
|
||||
}
|
||||
|
||||
static float3 ditherChromaticBlueNoise( float3 color, float2 n, sampler2D blueTex )
|
||||
{
|
||||
// uniform noise
|
||||
//float3 noise = Hash33( float3( n, rpJitterTexOffset.w ) );
|
||||
|
||||
//float3 noise = float3( InterleavedGradientNoise( n ) );
|
||||
//float3 noise = float3( InterleavedGradientNoiseAnim( n, rpJitterTexOffset.w ) );
|
||||
|
||||
// uv is screen position / sizeof blue noise image
|
||||
float2 uv = n.xy * rpJitterTexOffset.xy;
|
||||
float3 noise = tex2D( blueTex, uv ).rgb;
|
||||
|
||||
// rpJitterTexOffset.w is frameTime % 64
|
||||
noise = fract( noise + c_goldenRatioConjugate * rpJitterTexOffset.w );
|
||||
|
||||
// triangular noise [-0.5;1.5[
|
||||
noise.x = RemapNoiseTriErp( noise.x );
|
||||
noise = noise * 2.0 - 0.5;
|
||||
|
||||
//noise = float3( noise.x );
|
||||
|
||||
// quantize/truncate color and dither the result
|
||||
//float scale = exp2( float( TARGET_BITS ) ) - 1.0;
|
||||
|
||||
// lets assume 2^3 bits = 8
|
||||
float quantSteps = 255.0;
|
||||
|
||||
//float3 color = floor( c * scale + noise ) / scale;
|
||||
|
||||
color = floor( 0.5 + color * quantSteps - 0.5 + noise ) * ( 1.0 / ( quantSteps - 1.0 ) );
|
||||
|
||||
return color;
|
||||
}
|
||||
|
|
|
@ -424,9 +424,15 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
|
||||
// rpDiffuseModifier contains light color multiplier
|
||||
half3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );
|
||||
//lightColor = ditherRGB( lightColor, fragment.position.xy );
|
||||
//lightColor *= sRGBToLinearRGB( lightFalloff.xyz );// * rpDiffuseModifier.xyz;
|
||||
|
||||
//lightFalloff.xyz = ditherRGB( lightFalloff.xyz, fragment.texcoord2.xy );
|
||||
//lightProj.xyz = ditherRGB( lightProj.xyz, fragment.texcoord3.xy );
|
||||
|
||||
//half3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );
|
||||
|
||||
//lightColor = ditherChromaticBlueNoise( lightColor, fragment.position.xy, samp6 );
|
||||
|
||||
//lightColor *= sRGBToLinearRGB( lightFalloff.xyz );// * rpDiffuseModifier.xyz;
|
||||
//lightColor = ditherRGB( lightColor, fragment.position.xy );
|
||||
|
||||
|
||||
|
@ -463,6 +469,10 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
//half3 diffuseColor = mix( diffuseMap, F0, metal ) * rpDiffuseModifier.xyz;
|
||||
half3 diffuseBRDF = diffuseColor * lambert * ( rpDiffuseModifier.xyz );
|
||||
|
||||
result.color.xyz = ( diffuseBRDF + specularBRDF ) * lightColor * fragment.color.rgb * shadow;
|
||||
result.color.w = 1.0;
|
||||
float3 color = ( diffuseBRDF + specularBRDF ) * lightColor * fragment.color.rgb * shadow;
|
||||
|
||||
//color = ditherChromaticBlueNoise( color, fragment.position.xy, samp6 );
|
||||
|
||||
result.color.rgb = color;
|
||||
result.color.a = 1.0;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ Doom 3 BFG Edition GPL Source Code
|
|||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2015-2020 Robert Beckebans
|
||||
Copyright (C) 2014 Timothy Lottes (AMD)
|
||||
Copyright (C) 2019 Justin Marshal (IcedTech)
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -61,7 +62,9 @@ struct PS_OUT
|
|||
#define Vibrance 0.5 // [-1.00 to 1.00]
|
||||
#define Vibrance_RGB_Balance float3( 1.0, 1.0, 1.0 )
|
||||
|
||||
#define USE_DITHERING 1
|
||||
#define USE_CAS 1
|
||||
|
||||
#define USE_DITHERING 0
|
||||
#define Dithering_QuantizationSteps 8.0 // 8.0 = 2 ^ 3 quantization bits
|
||||
#define Dithering_NoiseBoost 1.0
|
||||
#define Dithering_Wide 1.0
|
||||
|
@ -460,6 +463,107 @@ void DitheringPass( inout float4 fragColor )
|
|||
}
|
||||
|
||||
|
||||
float Min3( float x, float y, float z )
|
||||
{
|
||||
return min( x, min( y, z ) );
|
||||
}
|
||||
|
||||
float Max3( float x, float y, float z )
|
||||
{
|
||||
return max( x, max( y, z ) );
|
||||
}
|
||||
|
||||
|
||||
float rcp( float v )
|
||||
{
|
||||
return 1.0 / v;
|
||||
}
|
||||
|
||||
void ContrastAdaptiveSharpeningPass( inout float4 fragColor )
|
||||
{
|
||||
float2 texcoord = fragment.texcoord0;
|
||||
float Sharpness = 1;
|
||||
|
||||
// fetch a 3x3 neighborhood around the pixel 'e',
|
||||
// a b c
|
||||
// d(e)f
|
||||
// g h i
|
||||
int2 bufferSize = textureSize( samp0, 0 );
|
||||
float pixelX = ( 1.0 / bufferSize.x );
|
||||
float pixelY = ( 1.0 / bufferSize.y );
|
||||
|
||||
float3 a = tex2D( samp0, texcoord + float2( -pixelX, -pixelY ) ).rgb;
|
||||
float3 b = tex2D( samp0, texcoord + float2( 0.0, -pixelY ) ).rgb;
|
||||
float3 c = tex2D( samp0, texcoord + float2( pixelX, -pixelY ) ).rgb;
|
||||
float3 d = tex2D( samp0, texcoord + float2( -pixelX, 0.0 ) ).rgb;
|
||||
float3 e = tex2D( samp0, texcoord ).rgb;
|
||||
float3 f = tex2D( samp0, texcoord + float2( pixelX, 0.0 ) ).rgb;
|
||||
float3 g = tex2D( samp0, texcoord + float2( -pixelX, pixelY ) ).rgb;
|
||||
float3 h = tex2D( samp0, texcoord + float2( 0.0, pixelY ) ).rgb;
|
||||
float3 i = tex2D( samp0, texcoord + float2( pixelX, pixelY ) ).rgb;
|
||||
|
||||
// Soft min and max.
|
||||
// a b c b
|
||||
// d e f * 0.5 + d e f * 0.5
|
||||
// g h i h
|
||||
// These are 2.0x bigger (factored out the extra multiply).
|
||||
float mnR = Min3( Min3( d.r, e.r, f.r ), b.r, h.r );
|
||||
float mnG = Min3( Min3( d.g, e.g, f.g ), b.g, h.g );
|
||||
float mnB = Min3( Min3( d.b, e.b, f.b ), b.b, h.b );
|
||||
|
||||
float mnR2 = Min3( Min3( mnR, a.r, c.r ), g.r, i.r );
|
||||
float mnG2 = Min3( Min3( mnG, a.g, c.g ), g.g, i.g );
|
||||
float mnB2 = Min3( Min3( mnB, a.b, c.b ), g.b, i.b );
|
||||
mnR = mnR + mnR2;
|
||||
mnG = mnG + mnG2;
|
||||
mnB = mnB + mnB2;
|
||||
|
||||
float mxR = Max3( Max3( d.r, e.r, f.r ), b.r, h.r );
|
||||
float mxG = Max3( Max3( d.g, e.g, f.g ), b.g, h.g );
|
||||
float mxB = Max3( Max3( d.b, e.b, f.b ), b.b, h.b );
|
||||
|
||||
float mxR2 = Max3( Max3( mxR, a.r, c.r ), g.r, i.r );
|
||||
float mxG2 = Max3( Max3( mxG, a.g, c.g ), g.g, i.g );
|
||||
float mxB2 = Max3( Max3( mxB, a.b, c.b ), g.b, i.b );
|
||||
mxR = mxR + mxR2;
|
||||
mxG = mxG + mxG2;
|
||||
mxB = mxB + mxB2;
|
||||
|
||||
// Smooth minimum distance to signal limit divided by smooth max.
|
||||
float rcpMR = rcp( mxR );
|
||||
float rcpMG = rcp( mxG );
|
||||
float rcpMB = rcp( mxB );
|
||||
|
||||
float ampR = saturate( min( mnR, 2.0 - mxR ) * rcpMR );
|
||||
float ampG = saturate( min( mnG, 2.0 - mxG ) * rcpMG );
|
||||
float ampB = saturate( min( mnB, 2.0 - mxB ) * rcpMB );
|
||||
|
||||
// Shaping amount of sharpening.
|
||||
ampR = sqrt( ampR );
|
||||
ampG = sqrt( ampG );
|
||||
ampB = sqrt( ampB );
|
||||
|
||||
// Filter shape.
|
||||
// 0 w 0
|
||||
// w 1 w
|
||||
// 0 w 0
|
||||
float peak = -rcp( lerp( 8.0, 5.0, saturate( Sharpness ) ) );
|
||||
|
||||
float wR = ampR * peak;
|
||||
float wG = ampG * peak;
|
||||
float wB = ampB * peak;
|
||||
|
||||
float rcpWeightR = rcp( 1.0 + 4.0 * wR );
|
||||
float rcpWeightG = rcp( 1.0 + 4.0 * wG );
|
||||
float rcpWeightB = rcp( 1.0 + 4.0 * wB );
|
||||
|
||||
float3 outColor = float3( saturate( ( b.r * wR + d.r * wR + f.r * wR + h.r * wR + e.r ) * rcpWeightR ),
|
||||
saturate( ( b.g * wG + d.g * wG + f.g * wG + h.g * wG + e.g ) * rcpWeightG ),
|
||||
saturate( ( b.b * wB + d.b * wB + f.b * wB + h.b * wB + e.b ) * rcpWeightB ) );
|
||||
|
||||
fragColor.rgb = outColor;
|
||||
}
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
float2 tCoords = fragment.texcoord0;
|
||||
|
@ -479,6 +583,10 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
VibrancePass( color );
|
||||
#endif
|
||||
|
||||
#if USE_CAS
|
||||
ContrastAdaptiveSharpeningPass( color );
|
||||
#endif
|
||||
|
||||
#if USE_DITHERING
|
||||
DitheringPass( color );
|
||||
#endif
|
||||
|
|
|
@ -69,6 +69,8 @@ float3 ACESFilm( float3 x )
|
|||
return saturate( ( x * ( a * x + b ) ) / ( x * ( c * x + d ) + e ) );
|
||||
}
|
||||
|
||||
#define USE_DITHERING 0
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
float2 tCoords = fragment.texcoord0;
|
||||
|
@ -93,6 +95,14 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
color.b = pow( color.b, gamma );
|
||||
#endif
|
||||
|
||||
#if USE_DITHERING
|
||||
|
||||
const float quantSteps = 256.0;
|
||||
|
||||
// dither
|
||||
color.rgb = ditherRGB( color.rgb, fragment.position.xy, quantSteps );
|
||||
#endif
|
||||
|
||||
#if defined(BRIGHTPASS)
|
||||
if( Y < 0.1 )
|
||||
{
|
||||
|
@ -197,7 +207,16 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
color.rgb *= clamp( B, 0.0, 1.0 );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#if USE_DITHERING
|
||||
// The following represents hardware linear->sRGB xform
|
||||
// which happens on sRGB formatted render targets,
|
||||
// except using a lot less bits/pixel.
|
||||
color.rgb = max( float3( 0.0 ), color.rgb );
|
||||
color.rgb = Srgb3( color.rgb );
|
||||
color.rgb = floor( color.rgb * quantSteps ) * ( 1.0 / ( quantSteps - 1.0 ) );
|
||||
|
||||
#else
|
||||
|
||||
// convert from linear RGB to sRGB
|
||||
|
||||
//float hdrGamma = 2.2;
|
||||
|
@ -205,6 +224,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
color.r = pow( color.r, gamma );
|
||||
color.g = pow( color.g, gamma );
|
||||
color.b = pow( color.b, gamma );
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HDR_DEBUG)
|
||||
|
|
|
@ -349,32 +349,39 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" return fract( ( p3.xxy + p3.yxx ) * p3.zyx );\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"static float3 ditherRGB( float3 c, float2 uvSeed )\n"
|
||||
"static float3 ditherRGB( float3 color, float2 uvSeed, float quantSteps )\n"
|
||||
"{\n"
|
||||
" // uniform noise\n"
|
||||
" //float3 whiteNoise = Hash33( float3( uvSeed, rpJitterTexOffset.w ) );\n"
|
||||
" //float3 noise = Hash33( float3( uvSeed, rpJitterTexOffset.w ) );\n"
|
||||
"\n"
|
||||
" //float3 whiteNoise = float3( InterleavedGradientNoise( uvSeed ) );\n"
|
||||
" float3 whiteNoise = float3( InterleavedGradientNoiseAnim( uvSeed, rpJitterTexOffset.w ) );\n"
|
||||
" //float3 noise = float3( InterleavedGradientNoise( uvSeed ) );\n"
|
||||
" float3 noise = float3( InterleavedGradientNoiseAnim( uvSeed, rpJitterTexOffset.w ) );\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" // triangular noise [-0.5;1.5[\n"
|
||||
"\n"
|
||||
"#if 1\n"
|
||||
" whiteNoise.x = RemapNoiseTriErp( whiteNoise.x );\n"
|
||||
" whiteNoise = whiteNoise * 2.0 - 0.5;\n"
|
||||
" noise.x = RemapNoiseTriErp( noise.x );\n"
|
||||
" noise = noise * 2.0 - 0.5;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" whiteNoise = float3( whiteNoise.x );\n"
|
||||
" noise = float3( noise.x );\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" // quantize/truncate color and dither the result\n"
|
||||
" //float scale = exp2( float( TARGET_BITS ) ) - 1.0;\n"
|
||||
"\n"
|
||||
" // lets assume 2^3 bits = 8\n"
|
||||
" float scale = 255.0;\n"
|
||||
" //float scale = 7.0;\n"
|
||||
" //const float quantSteps = 8.0;\n"
|
||||
" float scale = quantSteps - 1.0;\n"
|
||||
"\n"
|
||||
" float3 color = floor( c * scale + whiteNoise ) / scale;\n"
|
||||
" // apply dither\n"
|
||||
" color += noise / ( quantSteps );\n"
|
||||
"\n"
|
||||
" color = floor( color * scale ) / scale;\n"
|
||||
"\n"
|
||||
" //float3 color = c + whiteNoise / 255.0;\n"
|
||||
"\n"
|
||||
"#if defined( USE_LINEAR_RGB )\n"
|
||||
"\n"
|
||||
|
@ -383,6 +390,40 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" return color;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"static float3 ditherChromaticBlueNoise( float3 color, float2 n, sampler2D blueTex )\n"
|
||||
"{\n"
|
||||
" // uniform noise\n"
|
||||
" //float3 noise = Hash33( float3( n, rpJitterTexOffset.w ) );\n"
|
||||
"\n"
|
||||
" //float3 noise = float3( InterleavedGradientNoise( n ) );\n"
|
||||
" //float3 noise = float3( InterleavedGradientNoiseAnim( n, rpJitterTexOffset.w ) );\n"
|
||||
"\n"
|
||||
" // uv is screen position / sizeof blue noise image\n"
|
||||
" float2 uv = n.xy * rpJitterTexOffset.xy;\n"
|
||||
" float3 noise = tex2D( blueTex, uv ).rgb;\n"
|
||||
"\n"
|
||||
" // rpJitterTexOffset.w is frameTime % 64\n"
|
||||
" noise = fract( noise + c_goldenRatioConjugate * rpJitterTexOffset.w );\n"
|
||||
"\n"
|
||||
" // triangular noise [-0.5;1.5[\n"
|
||||
" noise.x = RemapNoiseTriErp( noise.x );\n"
|
||||
" noise = noise * 2.0 - 0.5;\n"
|
||||
"\n"
|
||||
" //noise = float3( noise.x );\n"
|
||||
"\n"
|
||||
" // quantize/truncate color and dither the result\n"
|
||||
" //float scale = exp2( float( TARGET_BITS ) ) - 1.0;\n"
|
||||
"\n"
|
||||
" // lets assume 2^3 bits = 8\n"
|
||||
" float quantSteps = 255.0;\n"
|
||||
"\n"
|
||||
" //float3 color = floor( c * scale + noise ) / scale;\n"
|
||||
"\n"
|
||||
" color = floor( 0.5 + color * quantSteps - 0.5 + noise ) * ( 1.0 / ( quantSteps - 1.0 ) );\n"
|
||||
"\n"
|
||||
" return color;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
|
||||
},
|
||||
|
||||
|
@ -10294,9 +10335,15 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"\n"
|
||||
" // rpDiffuseModifier contains light color multiplier\n"
|
||||
" half3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );\n"
|
||||
" //lightColor = ditherRGB( lightColor, fragment.position.xy );\n"
|
||||
" //lightColor *= sRGBToLinearRGB( lightFalloff.xyz );// * rpDiffuseModifier.xyz;\n"
|
||||
"\n"
|
||||
" //lightFalloff.xyz = ditherRGB( lightFalloff.xyz, fragment.texcoord2.xy );\n"
|
||||
" //lightProj.xyz = ditherRGB( lightProj.xyz, fragment.texcoord3.xy );\n"
|
||||
"\n"
|
||||
" //half3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );\n"
|
||||
"\n"
|
||||
" //lightColor = ditherChromaticBlueNoise( lightColor, fragment.position.xy, samp6 );\n"
|
||||
"\n"
|
||||
" //lightColor *= sRGBToLinearRGB( lightFalloff.xyz );// * rpDiffuseModifier.xyz;\n"
|
||||
" //lightColor = ditherRGB( lightColor, fragment.position.xy );\n"
|
||||
"\n"
|
||||
"\n"
|
||||
|
@ -10333,8 +10380,12 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" //half3 diffuseColor = mix( diffuseMap, F0, metal ) * rpDiffuseModifier.xyz;\n"
|
||||
" half3 diffuseBRDF = diffuseColor * lambert * ( rpDiffuseModifier.xyz );\n"
|
||||
"\n"
|
||||
" result.color.xyz = ( diffuseBRDF + specularBRDF ) * lightColor * fragment.color.rgb * shadow;\n"
|
||||
" result.color.w = 1.0;\n"
|
||||
" float3 color = ( diffuseBRDF + specularBRDF ) * lightColor * fragment.color.rgb * shadow;\n"
|
||||
"\n"
|
||||
" //color = ditherChromaticBlueNoise( color, fragment.position.xy, samp6 );\n"
|
||||
"\n"
|
||||
" result.color.rgb = color;\n"
|
||||
" result.color.a = 1.0;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
|
||||
|
@ -10732,6 +10783,7 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.\n"
|
||||
"Copyright (C) 2015-2020 Robert Beckebans\n"
|
||||
"Copyright (C) 2014 Timothy Lottes (AMD)\n"
|
||||
"Copyright (C) 2019 Justin Marshal (IcedTech)\n"
|
||||
"\n"
|
||||
"This file is part of the Doom 3 BFG Edition GPL Source Code (\"Doom 3 BFG Edition Source Code\").\n"
|
||||
"\n"
|
||||
|
@ -10788,7 +10840,9 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"#define Vibrance 0.5 // [-1.00 to 1.00]\n"
|
||||
"#define Vibrance_RGB_Balance float3( 1.0, 1.0, 1.0 )\n"
|
||||
"\n"
|
||||
"#define USE_DITHERING 1\n"
|
||||
"#define USE_CAS 1\n"
|
||||
"\n"
|
||||
"#define USE_DITHERING 0\n"
|
||||
"#define Dithering_QuantizationSteps 8.0 // 8.0 = 2 ^ 3 quantization bits\n"
|
||||
"#define Dithering_NoiseBoost 1.0\n"
|
||||
"#define Dithering_Wide 1.0\n"
|
||||
|
@ -11187,6 +11241,107 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"}\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"float Min3( float x, float y, float z )\n"
|
||||
"{\n"
|
||||
" return min( x, min( y, z ) );\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"float Max3( float x, float y, float z )\n"
|
||||
"{\n"
|
||||
" return max( x, max( y, z ) );\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"float rcp( float v )\n"
|
||||
"{\n"
|
||||
" return 1.0 / v;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void ContrastAdaptiveSharpeningPass( inout float4 fragColor )\n"
|
||||
"{\n"
|
||||
" float2 texcoord = fragment.texcoord0;\n"
|
||||
" float Sharpness = 1;\n"
|
||||
"\n"
|
||||
" // fetch a 3x3 neighborhood around the pixel 'e',\n"
|
||||
" // a b c\n"
|
||||
" // d(e)f\n"
|
||||
" // g h i\n"
|
||||
" int2 bufferSize = textureSize( samp0, 0 );\n"
|
||||
" float pixelX = ( 1.0 / bufferSize.x );\n"
|
||||
" float pixelY = ( 1.0 / bufferSize.y );\n"
|
||||
"\n"
|
||||
" float3 a = tex2D( samp0, texcoord + float2( -pixelX, -pixelY ) ).rgb;\n"
|
||||
" float3 b = tex2D( samp0, texcoord + float2( 0.0, -pixelY ) ).rgb;\n"
|
||||
" float3 c = tex2D( samp0, texcoord + float2( pixelX, -pixelY ) ).rgb;\n"
|
||||
" float3 d = tex2D( samp0, texcoord + float2( -pixelX, 0.0 ) ).rgb;\n"
|
||||
" float3 e = tex2D( samp0, texcoord ).rgb;\n"
|
||||
" float3 f = tex2D( samp0, texcoord + float2( pixelX, 0.0 ) ).rgb;\n"
|
||||
" float3 g = tex2D( samp0, texcoord + float2( -pixelX, pixelY ) ).rgb;\n"
|
||||
" float3 h = tex2D( samp0, texcoord + float2( 0.0, pixelY ) ).rgb;\n"
|
||||
" float3 i = tex2D( samp0, texcoord + float2( pixelX, pixelY ) ).rgb;\n"
|
||||
"\n"
|
||||
" // Soft min and max.\n"
|
||||
" // a b c b\n"
|
||||
" // d e f * 0.5 + d e f * 0.5\n"
|
||||
" // g h i h\n"
|
||||
" // These are 2.0x bigger (factored out the extra multiply).\n"
|
||||
" float mnR = Min3( Min3( d.r, e.r, f.r ), b.r, h.r );\n"
|
||||
" float mnG = Min3( Min3( d.g, e.g, f.g ), b.g, h.g );\n"
|
||||
" float mnB = Min3( Min3( d.b, e.b, f.b ), b.b, h.b );\n"
|
||||
"\n"
|
||||
" float mnR2 = Min3( Min3( mnR, a.r, c.r ), g.r, i.r );\n"
|
||||
" float mnG2 = Min3( Min3( mnG, a.g, c.g ), g.g, i.g );\n"
|
||||
" float mnB2 = Min3( Min3( mnB, a.b, c.b ), g.b, i.b );\n"
|
||||
" mnR = mnR + mnR2;\n"
|
||||
" mnG = mnG + mnG2;\n"
|
||||
" mnB = mnB + mnB2;\n"
|
||||
"\n"
|
||||
" float mxR = Max3( Max3( d.r, e.r, f.r ), b.r, h.r );\n"
|
||||
" float mxG = Max3( Max3( d.g, e.g, f.g ), b.g, h.g );\n"
|
||||
" float mxB = Max3( Max3( d.b, e.b, f.b ), b.b, h.b );\n"
|
||||
"\n"
|
||||
" float mxR2 = Max3( Max3( mxR, a.r, c.r ), g.r, i.r );\n"
|
||||
" float mxG2 = Max3( Max3( mxG, a.g, c.g ), g.g, i.g );\n"
|
||||
" float mxB2 = Max3( Max3( mxB, a.b, c.b ), g.b, i.b );\n"
|
||||
" mxR = mxR + mxR2;\n"
|
||||
" mxG = mxG + mxG2;\n"
|
||||
" mxB = mxB + mxB2;\n"
|
||||
"\n"
|
||||
" // Smooth minimum distance to signal limit divided by smooth max.\n"
|
||||
" float rcpMR = rcp( mxR );\n"
|
||||
" float rcpMG = rcp( mxG );\n"
|
||||
" float rcpMB = rcp( mxB );\n"
|
||||
"\n"
|
||||
" float ampR = saturate( min( mnR, 2.0 - mxR ) * rcpMR );\n"
|
||||
" float ampG = saturate( min( mnG, 2.0 - mxG ) * rcpMG );\n"
|
||||
" float ampB = saturate( min( mnB, 2.0 - mxB ) * rcpMB );\n"
|
||||
"\n"
|
||||
" // Shaping amount of sharpening.\n"
|
||||
" ampR = sqrt( ampR );\n"
|
||||
" ampG = sqrt( ampG );\n"
|
||||
" ampB = sqrt( ampB );\n"
|
||||
"\n"
|
||||
" // Filter shape.\n"
|
||||
" // 0 w 0\n"
|
||||
" // w 1 w\n"
|
||||
" // 0 w 0\n"
|
||||
" float peak = -rcp( lerp( 8.0, 5.0, saturate( Sharpness ) ) );\n"
|
||||
"\n"
|
||||
" float wR = ampR * peak;\n"
|
||||
" float wG = ampG * peak;\n"
|
||||
" float wB = ampB * peak;\n"
|
||||
"\n"
|
||||
" float rcpWeightR = rcp( 1.0 + 4.0 * wR );\n"
|
||||
" float rcpWeightG = rcp( 1.0 + 4.0 * wG );\n"
|
||||
" float rcpWeightB = rcp( 1.0 + 4.0 * wB );\n"
|
||||
"\n"
|
||||
" float3 outColor = float3( saturate( ( b.r * wR + d.r * wR + f.r * wR + h.r * wR + e.r ) * rcpWeightR ),\n"
|
||||
" saturate( ( b.g * wG + d.g * wG + f.g * wG + h.g * wG + e.g ) * rcpWeightG ),\n"
|
||||
" saturate( ( b.b * wB + d.b * wB + f.b * wB + h.b * wB + e.b ) * rcpWeightB ) );\n"
|
||||
"\n"
|
||||
" fragColor.rgb = outColor;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main( PS_IN fragment, out PS_OUT result )\n"
|
||||
"{\n"
|
||||
" float2 tCoords = fragment.texcoord0;\n"
|
||||
|
@ -11206,6 +11361,10 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" VibrancePass( color );\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#if USE_CAS\n"
|
||||
" ContrastAdaptiveSharpeningPass( color );\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#if USE_DITHERING\n"
|
||||
" DitheringPass( color );\n"
|
||||
"#endif\n"
|
||||
|
@ -13599,6 +13758,8 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" return saturate( ( x * ( a * x + b ) ) / ( x * ( c * x + d ) + e ) );\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"#define USE_DITHERING 0\n"
|
||||
"\n"
|
||||
"void main( PS_IN fragment, out PS_OUT result )\n"
|
||||
"{\n"
|
||||
" float2 tCoords = fragment.texcoord0;\n"
|
||||
|
@ -13623,6 +13784,14 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" color.b = pow( color.b, gamma );\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#if USE_DITHERING\n"
|
||||
"\n"
|
||||
" const float quantSteps = 256.0;\n"
|
||||
"\n"
|
||||
" // dither\n"
|
||||
" color.rgb = ditherRGB( color.rgb, fragment.position.xy, quantSteps );\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#if defined(BRIGHTPASS)\n"
|
||||
" if( Y < 0.1 )\n"
|
||||
" {\n"
|
||||
|
@ -13727,7 +13896,16 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" color.rgb *= clamp( B, 0.0, 1.0 );\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#if 1\n"
|
||||
"#if USE_DITHERING\n"
|
||||
" // The following represents hardware linear->sRGB xform\n"
|
||||
" // which happens on sRGB formatted render targets,\n"
|
||||
" // except using a lot less bits/pixel.\n"
|
||||
" color.rgb = max( float3( 0.0 ), color.rgb );\n"
|
||||
" color.rgb = Srgb3( color.rgb );\n"
|
||||
" color.rgb = floor( color.rgb * quantSteps ) * ( 1.0 / ( quantSteps - 1.0 ) );\n"
|
||||
"\n"
|
||||
"#else\n"
|
||||
"\n"
|
||||
" // convert from linear RGB to sRGB\n"
|
||||
"\n"
|
||||
" //float hdrGamma = 2.2;\n"
|
||||
|
@ -13735,6 +13913,7 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" color.r = pow( color.r, gamma );\n"
|
||||
" color.g = pow( color.g, gamma );\n"
|
||||
" color.b = pow( color.b, gamma );\n"
|
||||
"\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#if defined(HDR_DEBUG)\n"
|
||||
|
|
Loading…
Reference in a new issue