Only modulate down ambient pass with SSAO

This commit is contained in:
Robert Beckebans 2020-04-25 18:30:40 +02:00
parent 4e9e15e65a
commit c87e9e1711
5 changed files with 126 additions and 78 deletions

View file

@ -69,7 +69,7 @@ half3 Fresnel_SchlickRoughness( half3 specularColor, half vDotN, half roughness
// Sébastien Lagarde proposes an empirical approach to derive the specular occlusion term from the diffuse occlusion term in [Lagarde14].
// The result does not have any physical basis but produces visually pleasant results.
// See Sébastien Lagarde and Charles de Rousiers. 2014. Moving Frostbite to PBR.
float ComputeSpecularAO( float vDotN, float ao, float roughness)
float ComputeSpecularAO( float vDotN, float ao, float roughness )
{
return clamp( pow( vDotN + ao, exp2( -16.0 * roughness - 1.0) ) - 1.0 + ao, 0.0, 1.0 );
}

View file

@ -35,7 +35,7 @@ uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal m
uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map
uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map
uniform sampler2D samp3 : register(s3); // texture 4 is the BRDF LUT
uniform sampler2D samp4 : register(s4); // texture 5 is unused
uniform sampler2D samp4 : register(s4); // texture 5 is SSAO
uniform samplerCUBE samp7 : register(s7); // texture 6 is the irradiance cube map
uniform samplerCUBE samp8 : register(s8); // texture 7 is the radiance cube map
@ -156,12 +156,20 @@ void main( PS_IN fragment, out PS_OUT result )
#endif
float3 ao = float3( 1.0, 1.0, 1.0 );
//diffuseColor = half3( 1.0, 1.0, 1.0 );
//diffuseColor = half3( 0.0, 0.0, 0.0 );
// calculate the screen texcoord in the 0.0 to 1.0 range
//float2 screenTexCoord = vposToScreenPosTexCoord( fragment.position.xy );
float2 screenTexCoord = fragment.position.xy * rpScreenCorrectionFactor.xy;
float ao = tex2D( samp4, screenTexCoord ).r;
//diffuseColor.rgb *= ao;
// evaluate diffuse IBL
float3 irradiance = texCUBE( samp7, globalNormal ).rgb;
float3 diffuseLight = ( kD * irradiance * diffuseColor ) * ( rpDiffuseModifier.xyz * 3.0 );
float3 diffuseLight = ( kD * irradiance * diffuseColor ) * ao * ( rpDiffuseModifier.xyz * 3.0 );
// evaluate specular IBL
@ -170,9 +178,7 @@ void main( PS_IN fragment, out PS_OUT result )
float mip = clamp( ( roughness * MAX_REFLECTION_LOD ) + 0.0, 0.0, 10.0 );
float3 radiance = textureLod( samp8, reflectionVector, mip ).rgb;
// our LUT is upside down
float2 envBRDF = texture( samp3, float2( max( vDotN, 0.0 ), roughness ) ).rg;
//float2 envBRDF = texture( samp3, float2( max( vDotN, 0.0), 1.0 - roughness ) ).rg;
#if 0
result.color.rgb = float3( envBRDF.x, envBRDF.y, 0.0 );
@ -180,7 +186,8 @@ void main( PS_IN fragment, out PS_OUT result )
return;
#endif
float3 specularLight = radiance * ( kS * envBRDF.x + float3( envBRDF.y ) ) * ( rpSpecularModifier.xyz * 0.75 );
float specAO = ComputeSpecularAO( vDotN, ao, roughness );
float3 specularLight = radiance * ( kS * envBRDF.x + float3( envBRDF.y ) ) * specAO * ( rpSpecularModifier.xyz * 0.75 );
#if 0
// Marmoset Horizon Fade trick
@ -199,5 +206,6 @@ void main( PS_IN fragment, out PS_OUT result )
//result.color.rgb = localNormal.xyz * 0.5 + 0.5;
//result.color.xyz = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor ) * fragment.color.rgb;
//result.color = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor + rimColor ) * fragment.color.rgba;
//result.color.rgb = float3( ao );
result.color.w = fragment.color.a;
}

View file

@ -1198,14 +1198,14 @@ GENERAL INTERACTION RENDERING
const int INTERACTION_TEXUNIT_BUMP = 0;
const int INTERACTION_TEXUNIT_SPECULARMIX = 1;
const int INTERACTION_TEXUNIT_BASECOLOR = 2;
const int INTERACTION_TEXUNIT_FALLOFF = 3;
const int INTERACTION_TEXUNIT_PROJECTION = 4;
const int INTERACTION_TEXUNIT_FALLOFF = 3; // RB: also _brdfLut
const int INTERACTION_TEXUNIT_PROJECTION = 4; // RB: also SSAO render target
const int INTERACTION_TEXUNIT_SHADOWMAPS = 5;
const int INTERACTION_TEXUNIT_JITTER = 6;
#if defined( USE_VULKAN )
const int INTERACTION_TEXUNIT_AMBIENT_CUBE1 = 4;
const int INTERACTION_TEXUNIT_SPECULAR_CUBE1 = 5;
const int INTERACTION_TEXUNIT_AMBIENT_CUBE1 = 5;
const int INTERACTION_TEXUNIT_SPECULAR_CUBE1 = 6;
#else
const int INTERACTION_TEXUNIT_AMBIENT_CUBE1 = 7;
const int INTERACTION_TEXUNIT_SPECULAR_CUBE1 = 8;
@ -1358,6 +1358,17 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
GL_SelectTexture( INTERACTION_TEXUNIT_FALLOFF );
globalImages->brdfLutImage->Bind();
GL_SelectTexture( INTERACTION_TEXUNIT_PROJECTION );
if( !r_useSSAO.GetBool() )
{
globalImages->whiteImage->Bind();
//globalImages->brdfLutImage->Bind();
}
else
{
globalImages->ambientOcclusionImage[0]->Bind();
}
GL_SelectTexture( INTERACTION_TEXUNIT_AMBIENT_CUBE1 );
globalImages->defaultUACIrradianceCube->Bind();
@ -2186,9 +2197,10 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
//}
//else
{
#if 1
if( fillGbuffer )
{
// TODO support PBR textures and store roughness in the alpha channel
// fill geometry buffer with normal/roughness information
if( drawSurf->jointCache )
{
@ -2200,43 +2212,18 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
}
}
else
#endif
{
#if 0
if( useIBL )
// TODO support PBR textures
// draw Quake 4 style ambient
if( drawSurf->jointCache )
{
// draw Quake 4 style ambient
/*
if( drawSurf->jointCache )
{
renderProgManager.BindShader_ImageBasedLightingSkinned();
}
else
{
renderProgManager.BindShader_ImageBasedLighting();
}
*/
GL_SelectTexture( INTERACTION_TEXUNIT_AMBIENT_CUBE1 );
globalImages->defaultUACIrradianceCube->Bind();
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE1 );
globalImages->defaultUACRadianceCube->Bind();
renderProgManager.BindShader_AmbientLightingSkinned();
}
else
#endif
{
// TODO support PBR textures
// draw Quake 4 style ambient
if( drawSurf->jointCache )
{
renderProgManager.BindShader_AmbientLightingSkinned();
}
else
{
renderProgManager.BindShader_AmbientLighting();
}
renderProgManager.BindShader_AmbientLighting();
}
}
}
@ -4725,7 +4712,7 @@ void idRenderBackend::Bloom( const viewDef_t* _viewDef )
}
void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef )
void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef, bool downModulateScreen )
{
#if !defined(USE_VULKAN)
if( !_viewDef->viewEntitys || _viewDef->is2Dgui )
@ -4891,32 +4878,52 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS | GLS_CULL_TWOSIDED );
if( r_ssaoFiltering.GetBool() )
if( downModulateScreen )
{
if( r_ssaoFiltering.GetBool() )
{
globalFramebuffers.ambientOcclusionFBO[0]->Bind();
glClearColor( 0, 0, 0, 0 );
glClear( GL_COLOR_BUFFER_BIT );
renderProgManager.BindShader_AmbientOcclusion();
}
else
{
if( r_ssaoDebug.GetInteger() <= 0 )
{
GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_ALPHAMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
}
if( hdrIsActive )
{
globalFramebuffers.hdrFBO->Bind();
}
else
{
Framebuffer::Unbind();
}
renderProgManager.BindShader_AmbientOcclusionAndOutput();
}
}
else
{
globalFramebuffers.ambientOcclusionFBO[0]->Bind();
glClearColor( 0, 0, 0, 0 );
glClear( GL_COLOR_BUFFER_BIT );
renderProgManager.BindShader_AmbientOcclusion();
}
else
{
if( r_ssaoDebug.GetInteger() <= 0 )
if( r_ssaoFiltering.GetBool() )
{
GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_ALPHAMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
}
if( hdrIsActive )
{
globalFramebuffers.hdrFBO->Bind();
renderProgManager.BindShader_AmbientOcclusion();
}
else
{
Framebuffer::Unbind();
renderProgManager.BindShader_AmbientOcclusionAndOutput();
}
renderProgManager.BindShader_AmbientOcclusionAndOutput();
}
float screenCorrectionParm[4];
@ -4996,18 +5003,25 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef
#endif
// AO blur Y
if( hdrIsActive )
if( downModulateScreen )
{
globalFramebuffers.hdrFBO->Bind();
if( hdrIsActive )
{
globalFramebuffers.hdrFBO->Bind();
}
else
{
Framebuffer::Unbind();
}
if( r_ssaoDebug.GetInteger() <= 0 )
{
GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
}
}
else
{
Framebuffer::Unbind();
}
if( r_ssaoDebug.GetInteger() <= 0 )
{
GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
globalFramebuffers.ambientOcclusionFBO[0]->Bind();
}
renderProgManager.BindShader_AmbientOcclusionBlurAndOutput();
@ -5025,6 +5039,19 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef
DrawElementsWithCounters( &unitSquareSurface );
}
if( !downModulateScreen )
{
// go back to main scene render target
if( hdrIsActive )
{
globalFramebuffers.hdrFBO->Bind();
}
else
{
Framebuffer::Unbind();
}
}
renderProgManager.Unbind();
GL_State( GLS_DEFAULT );
@ -5520,7 +5547,12 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
AmbientPass( drawSurfs, numDrawSurfs, true );
//-------------------------------------------------
// fill the depth buffer and the color buffer with precomputed Q3A style lighting
// build hierarchical depth buffer and SSAO render target
//-------------------------------------------------
DrawScreenSpaceAmbientOcclusion( _viewDef, false );
//-------------------------------------------------
// render static lighting and consider SSAO results
//-------------------------------------------------
AmbientPass( drawSurfs, numDrawSurfs, false );
@ -5541,7 +5573,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
//-------------------------------------------------
// darken the scene using the screen space ambient occlusion
//-------------------------------------------------
DrawScreenSpaceAmbientOcclusion( _viewDef );
//DrawScreenSpaceAmbientOcclusion( _viewDef );
//RB_SSGI( _viewDef );
//-------------------------------------------------

View file

@ -307,7 +307,7 @@ private:
void Tonemap( const viewDef_t* viewDef );
void Bloom( const viewDef_t* viewDef );
void DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef );
void DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef, bool downModulateScreen );
void DrawScreenSpaceGlobalIllumination( const viewDef_t* _viewDef );
// Experimental feature

View file

@ -1809,7 +1809,7 @@ static const cgShaderDef_t cg_renderprogs[] =
"// Sébastien Lagarde proposes an empirical approach to derive the specular occlusion term from the diffuse occlusion term in [Lagarde14].\n"
"// The result does not have any physical basis but produces visually pleasant results.\n"
"// See Sébastien Lagarde and Charles de Rousiers. 2014. Moving Frostbite to PBR.\n"
"float ComputeSpecularAO( float vDotN, float ao, float roughness)\n"
"float ComputeSpecularAO( float vDotN, float ao, float roughness )\n"
"{\n"
" return clamp( pow( vDotN + ao, exp2( -16.0 * roughness - 1.0) ) - 1.0 + ao, 0.0, 1.0 );\n"
"}\n"
@ -2238,7 +2238,7 @@ static const cgShaderDef_t cg_renderprogs[] =
"uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map\n"
"uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map \n"
"uniform sampler2D samp3 : register(s3); // texture 4 is the BRDF LUT\n"
"uniform sampler2D samp4 : register(s4); // texture 5 is unused\n"
"uniform sampler2D samp4 : register(s4); // texture 5 is SSAO\n"
"\n"
"uniform samplerCUBE samp7 : register(s7); // texture 6 is the irradiance cube map\n"
"uniform samplerCUBE samp8 : register(s8); // texture 7 is the radiance cube map\n"
@ -2359,12 +2359,20 @@ static const cgShaderDef_t cg_renderprogs[] =
"\n"
"#endif\n"
"\n"
" float3 ao = float3( 1.0, 1.0, 1.0 );\n"
" //diffuseColor = half3( 1.0, 1.0, 1.0 );\n"
" //diffuseColor = half3( 0.0, 0.0, 0.0 );\n"
" \n"
" // calculate the screen texcoord in the 0.0 to 1.0 range\n"
" //float2 screenTexCoord = vposToScreenPosTexCoord( fragment.position.xy );\n"
" float2 screenTexCoord = fragment.position.xy * rpScreenCorrectionFactor.xy;\n"
" \n"
" float ao = tex2D( samp4, screenTexCoord ).r;\n"
" //diffuseColor.rgb *= ao;\n"
"\n"
" // evaluate diffuse IBL\n"
"\n"
" float3 irradiance = texCUBE( samp7, globalNormal ).rgb;\n"
" float3 diffuseLight = ( kD * irradiance * diffuseColor ) * ( rpDiffuseModifier.xyz * 3.0 );\n"
" float3 diffuseLight = ( kD * irradiance * diffuseColor ) * ao * ( rpDiffuseModifier.xyz * 3.0 );\n"
"\n"
" // evaluate specular IBL\n"
"\n"
@ -2373,9 +2381,7 @@ static const cgShaderDef_t cg_renderprogs[] =
" float mip = clamp( ( roughness * MAX_REFLECTION_LOD ) + 0.0, 0.0, 10.0 );\n"
" float3 radiance = textureLod( samp8, reflectionVector, mip ).rgb;\n"
"\n"
" // our LUT is upside down\n"
" float2 envBRDF = texture( samp3, float2( max( vDotN, 0.0 ), roughness ) ).rg;\n"
" //float2 envBRDF = texture( samp3, float2( max( vDotN, 0.0), 1.0 - roughness ) ).rg;\n"
"\n"
"#if 0\n"
" result.color.rgb = float3( envBRDF.x, envBRDF.y, 0.0 );\n"
@ -2383,7 +2389,8 @@ static const cgShaderDef_t cg_renderprogs[] =
" return;\n"
"#endif\n"
"\n"
" float3 specularLight = radiance * ( kS * envBRDF.x + float3( envBRDF.y ) ) * ( rpSpecularModifier.xyz * 0.75 );\n"
" float specAO = ComputeSpecularAO( vDotN, ao, roughness );\n"
" float3 specularLight = radiance * ( kS * envBRDF.x + float3( envBRDF.y ) ) * specAO * ( rpSpecularModifier.xyz * 0.75 );\n"
"\n"
"#if 0\n"
" // Marmoset Horizon Fade trick\n"
@ -2402,6 +2409,7 @@ static const cgShaderDef_t cg_renderprogs[] =
" //result.color.rgb = localNormal.xyz * 0.5 + 0.5;\n"
" //result.color.xyz = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor ) * fragment.color.rgb;\n"
" //result.color = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor + rimColor ) * fragment.color.rgba;\n"
" //result.color.rgb = float3( ao );\n"
" result.color.w = fragment.color.a;\n"
"}\n"
"\n"