mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-24 18:50:20 +00:00
Added new PBR roughness estimation by Kennedith98
This commit is contained in:
parent
025627b155
commit
9ba5e92b42
4 changed files with 89 additions and 19 deletions
|
@ -1704,9 +1704,8 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
|
|||
|
||||
// apply the world-global overbright and the 2x factor for specular
|
||||
idVec4 diffuseColor = lightColor;
|
||||
idVec4 specularColor = lightColor * 2.0f; // RB: skip 2x factor for specular PBR formulars
|
||||
// jmarshall
|
||||
idVec4 specularColor = lightColor * 2.0f;
|
||||
|
||||
if( vLight->lightDef->parms.noSpecular )
|
||||
{
|
||||
specularColor.Zero();
|
||||
|
|
|
@ -102,7 +102,7 @@ float Visibility_SmithGGX( half vdotN, half ldotN, float alpha )
|
|||
return ( 1.0 / max( V1 * V2, 0.15 ) );
|
||||
}
|
||||
|
||||
// HACK calculate roughness from D3 gloss maps
|
||||
// RB: HACK calculate roughness from D3 gloss maps
|
||||
float EstimateLegacyRoughness( float3 specMapSRGB )
|
||||
{
|
||||
float Y = dot( LUMINANCE_SRGB.rgb, specMapSRGB );
|
||||
|
@ -115,6 +115,65 @@ float EstimateLegacyRoughness( float3 specMapSRGB )
|
|||
return roughness;
|
||||
}
|
||||
|
||||
// Kennedith98 begin
|
||||
// takes a gamma-space specular texture
|
||||
// outputs F0 color and roughness for PBR
|
||||
void PBRFromSpecmap( float3 specMap, out float3 F0, out float roughness )
|
||||
{
|
||||
// desaturate specular
|
||||
float specLum = max( specMap.r, max( specMap.g, specMap.b ) );
|
||||
|
||||
// fresnel base
|
||||
F0 = _float3( 0.04 );
|
||||
|
||||
// fresnel contrast (will tighten low spec and broaden high spec, stops specular looking too flat or shiny)
|
||||
float contrastMid = 0.214;
|
||||
float contrastAmount = 2.0;
|
||||
float contrast = saturate( ( specLum - contrastMid ) / ( 1 - contrastMid ) ); //high spec
|
||||
contrast += saturate( specLum / contrastMid ) - 1.0; //low spec
|
||||
contrast = exp2( contrastAmount * contrast );
|
||||
F0 *= contrast;
|
||||
|
||||
// reverse blinn BRDF to perfectly match vanilla specular brightness
|
||||
// fresnel is affected when specPow is 0, experimentation is desmos showed that happens at F0/4
|
||||
float linearBrightness = Linear1( 2.0 * specLum );
|
||||
float specPow = max( 0.0, ( ( 8 * linearBrightness ) / F0.y ) - 2.0 );
|
||||
F0 *= min( 1.0, linearBrightness / ( F0.y * 0.25 ) );
|
||||
|
||||
// specular power to roughness
|
||||
roughness = sqrt( 2.0 / ( specPow + 2.0 ) );
|
||||
|
||||
// RB: do another sqrt because PBR shader squares it
|
||||
roughness = sqrt( roughness );
|
||||
}
|
||||
|
||||
// takes roughness, unnormalized 0-1 normalmap texture and the distance to the camera
|
||||
// returns roughness
|
||||
float ApplySpecularAA( float roughness, float3 bumpMap, float camDist )
|
||||
{
|
||||
float normLen = saturate( length( bumpMap.xyz * 2.0 - 1.0 ) );
|
||||
|
||||
// roughness to specular power
|
||||
float specPow = ( 2.0 / ( roughness * roughness ) ) - 2.0;
|
||||
|
||||
// toksvig AA to prevent speckles from sharp normal edges
|
||||
float specAA = 1.0 / ( 1.0 + specPow * ( ( 1.0 / normLen ) - 1.0 ) );
|
||||
|
||||
// fade out AA close to the camera to prevent dull highlights close up
|
||||
float distMax = 100.0;
|
||||
float disMin = 1.0;
|
||||
specAA = lerp( specAA, 1.0, smoothstep( disMin, distMax, camDist ) );
|
||||
|
||||
//apply AA
|
||||
specPow *= specAA;
|
||||
|
||||
// specular power to roughness
|
||||
roughness = sqrt( 2.0 / ( specPow + 2.0 ) );
|
||||
|
||||
return roughness;
|
||||
}
|
||||
// Kennedith98 end
|
||||
|
||||
// Environment BRDF approximations
|
||||
// see s2013_pbs_black_ops_2_notes.pdf
|
||||
/*
|
||||
|
|
|
@ -131,6 +131,13 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
|
||||
float3 diffuseColor = baseColor * ( 1.0 - metallic );
|
||||
float3 specularColor = lerp( dielectricColor, baseColor, metallic );
|
||||
|
||||
#elif 1
|
||||
float3 diffuseColor = diffuseMap;
|
||||
float3 specularColor;
|
||||
float roughness;
|
||||
|
||||
PBRFromSpecmap( specMapSRGB.rgb, specularColor, roughness );
|
||||
#else
|
||||
const float roughness = EstimateLegacyRoughness( specMapSRGB.rgb );
|
||||
|
||||
|
@ -139,8 +146,10 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
#endif
|
||||
|
||||
|
||||
// RB: compensate r_lightScale 3 and the division of Pi
|
||||
// RB FIXME or not: compensate r_lightScale 3 and the division of Pi
|
||||
//lambert *= 1.3;
|
||||
// see http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
|
||||
//lambert /= PI;
|
||||
|
||||
// rpDiffuseModifier contains light color multiplier
|
||||
float3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );
|
||||
|
@ -149,8 +158,8 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
float vdotH = clamp( dot3( viewVector, halfAngleVector ), 0.0, 1.0 );
|
||||
float ldotH = clamp( dot3( lightVector, halfAngleVector ), 0.0, 1.0 );
|
||||
|
||||
// compensate r_lightScale 3 * 2
|
||||
float3 reflectColor = specularColor * rpSpecularModifier.rgb * 1.0;// * 0.5;
|
||||
// keep in mind this is r_lightScale 3 * 2
|
||||
float3 reflectColor = specularColor * rpSpecularModifier.rgb;
|
||||
|
||||
// cheap approximation by ARM with only one division
|
||||
// http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
|
||||
|
@ -162,17 +171,14 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
// disney GGX
|
||||
float D = ( hdotN * hdotN ) * ( rrrr - 1.0 ) + 1.0;
|
||||
float VFapprox = ( ldotH * ldotH ) * ( roughness + 0.5 );
|
||||
float3 specularLight = ( rrrr / ( 4.0 * PI * D * D * VFapprox ) ) * ldotN * reflectColor;
|
||||
//specularLight = float3( 0.0 );
|
||||
//float3 specularLight = ( rrrr / ( 4.0 * PI * D * D * VFapprox ) ) * ldotN * reflectColor;
|
||||
float3 specularLight = ( rrrr / ( 4.0 * D * D * VFapprox ) ) * ldotN * reflectColor;
|
||||
|
||||
#if 0
|
||||
result.color = float4( _float3( VFapprox ), 1.0 );
|
||||
return;
|
||||
#endif
|
||||
|
||||
// see http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
|
||||
//lambert /= PI;
|
||||
|
||||
//float3 diffuseColor = mix( diffuseMap, F0, metal ) * rpDiffuseModifier.xyz;
|
||||
float3 diffuseLight = diffuseColor * lambert * ( rpDiffuseModifier.xyz );
|
||||
|
||||
|
|
|
@ -489,6 +489,13 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
|
||||
float3 diffuseColor = baseColor * ( 1.0 - metallic );
|
||||
float3 specularColor = lerp( dielectricColor, baseColor, metallic );
|
||||
|
||||
#elif 1
|
||||
float3 diffuseColor = diffuseMap;
|
||||
float3 specularColor;
|
||||
float roughness;
|
||||
|
||||
PBRFromSpecmap( specMapSRGB.rgb, specularColor, roughness );
|
||||
#else
|
||||
const float roughness = EstimateLegacyRoughness( specMapSRGB.rgb );
|
||||
|
||||
|
@ -497,8 +504,10 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
#endif
|
||||
|
||||
|
||||
// RB: compensate r_lightScale 3 and the division of Pi
|
||||
// RB FIXME or not: compensate r_lightScale 3 and the division of Pi
|
||||
//lambert *= 1.3;
|
||||
// see http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
|
||||
//lambert /= PI;
|
||||
|
||||
// rpDiffuseModifier contains light color multiplier
|
||||
float3 lightColor = sRGBToLinearRGB( lightProj.xyz * lightFalloff.xyz );
|
||||
|
@ -507,8 +516,8 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
float vdotH = clamp( dot3( viewVector, halfAngleVector ), 0.0, 1.0 );
|
||||
float ldotH = clamp( dot3( lightVector, halfAngleVector ), 0.0, 1.0 );
|
||||
|
||||
// compensate r_lightScale 3 * 2
|
||||
float3 reflectColor = specularColor * rpSpecularModifier.rgb * 1.0;// * 0.5;
|
||||
// keep in mind this is r_lightScale 3 * 2
|
||||
float3 reflectColor = specularColor * rpSpecularModifier.rgb;
|
||||
|
||||
// cheap approximation by ARM with only one division
|
||||
// http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
|
||||
|
@ -520,17 +529,14 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
// disney GGX
|
||||
float D = ( hdotN * hdotN ) * ( rrrr - 1.0 ) + 1.0;
|
||||
float VFapprox = ( ldotH * ldotH ) * ( roughness + 0.5 );
|
||||
float3 specularLight = ( rrrr / ( 4.0 * PI * D * D * VFapprox ) ) * ldotN * reflectColor;
|
||||
//specularLight = float3( 0.0 );
|
||||
//float3 specularLight = ( rrrr / ( 4.0 * PI * D * D * VFapprox ) ) * ldotN * reflectColor;
|
||||
float3 specularLight = ( rrrr / ( 4.0 * D * D * VFapprox ) ) * ldotN * reflectColor;
|
||||
|
||||
#if 0
|
||||
result.color = float4( _float3( VFapprox ), 1.0 );
|
||||
return;
|
||||
#endif
|
||||
|
||||
// see http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
|
||||
//lambert /= PI;
|
||||
|
||||
//float3 diffuseColor = mix( diffuseMap, F0, metal ) * rpDiffuseModifier.xyz;
|
||||
float3 diffuseLight = diffuseColor * lambert * ( rpDiffuseModifier.xyz );
|
||||
|
||||
|
|
Loading…
Reference in a new issue