Skip to content

renderer: rework tone mapper and SSAO enablement #1577

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/engine/renderer/glsl_source/cameraEffects_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ IN(smooth) vec2 var_TexCoords;

DECLARE_OUTPUT(vec4)

// Tone mapping is not available when high-precision float framebuffer isn't enabled or supported.
#if defined(r_highPrecisionRendering) && defined(HAVE_ARB_texture_float)
/* x: contrast
y: highlightsCompressionSpeed
z: shoulderClip
Expand All @@ -49,6 +51,7 @@ vec3 TonemapLottes( vec3 color ) {
return pow( color, vec3( u_TonemapParms[0] ) )
/ ( pow( color, vec3( u_TonemapParms[0] * u_TonemapParms[1] ) ) * u_TonemapParms[2] + u_TonemapParms[3] );
}
#endif

void main()
{
Expand All @@ -58,9 +61,10 @@ void main()
vec4 color = texture2D(u_CurrentMap, st);
color *= u_GlobalLightFactor;

if( u_Tonemap ) {
color.rgb = TonemapLottes( color.rgb * u_TonemapExposure );
}
#if defined(r_highPrecisionRendering) && defined(HAVE_ARB_texture_float)
color.rgb = TonemapLottes( color.rgb * u_TonemapExposure );
#endif

color.rgb = clamp( color.rgb, vec3( 0.0f ), vec3( 1.0f ) );

#if defined(r_colorGrading)
Expand Down
20 changes: 9 additions & 11 deletions src/engine/renderer/tr_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ void GL_BindNullProgram()

void GL_SelectTexture( int unit )
{

if ( glState.currenttmu == unit )
{
return;
Expand Down Expand Up @@ -3192,7 +3191,8 @@ void RB_RenderSSAO()
{
GLimp_LogComment( "--- RB_RenderSSAO ---\n" );

if ( !glConfig2.textureGatherAvailable ) {
if ( !glConfig2.ssao )
{
return;
}

Expand All @@ -3205,7 +3205,7 @@ void RB_RenderSSAO()
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO );
GL_Cull( cullType_t::CT_TWO_SIDED );

if ( r_ssao->integer < 0 ) {
if ( glConfig2.ssao && r_ssao.Get() == Util::ordinal( ssaoMode::SHOW ) ) {
// clear the screen to show only SSAO
GL_ClearColor( 1.0, 1.0, 1.0, 1.0 );
glClear( GL_COLOR_BUFFER_BIT );
Expand Down Expand Up @@ -3355,13 +3355,13 @@ void RB_CameraPostFX()

gl_cameraEffectsShader->SetUniform_InverseGamma( 1.0 / r_gamma->value );

const bool tonemap = r_tonemap.Get() && r_highPrecisionRendering.Get() && glConfig2.textureFloatAvailable;
const bool tonemap = r_toneMapping.Get() && r_highPrecisionRendering.Get() && glConfig2.textureFloatAvailable;
if ( tonemap ) {
vec4_t tonemapParms { r_tonemapContrast.Get(), r_tonemapHighlightsCompressionSpeed.Get() };
ComputeTonemapParams( tonemapParms[0], tonemapParms[1], r_tonemapHDRMax.Get(),
r_tonemapDarkAreaPointHDR.Get(), r_tonemapDarkAreaPointLDR.Get(), tonemapParms[2], tonemapParms[3] );
vec4_t tonemapParms { r_toneMappingContrast.Get(), r_toneMappingHighlightsCompressionSpeed.Get() };
ComputeTonemapParams( tonemapParms[0], tonemapParms[1], r_toneMappingHDRMax.Get(),
r_toneMappingDarkAreaPointHDR.Get(), r_toneMappingDarkAreaPointLDR.Get(), tonemapParms[2], tonemapParms[3] );
gl_cameraEffectsShader->SetUniform_TonemapParms( tonemapParms );
gl_cameraEffectsShader->SetUniform_TonemapExposure( r_tonemapExposure.Get() );
gl_cameraEffectsShader->SetUniform_TonemapExposure( r_toneMappingExposure.Get() );
}
gl_cameraEffectsShader->SetUniform_Tonemap( tonemap );

Expand Down Expand Up @@ -4726,9 +4726,7 @@ static void RB_RenderView( bool depthPass )
RB_RenderDrawSurfaces( shaderSort_t::SS_ENVIRONMENT_FOG, shaderSort_t::SS_OPAQUE, DRAWSURFACES_ALL );
}

if ( r_ssao->integer ) {
RB_RenderSSAO();
}
RB_RenderSSAO();

if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_SHADING_TIMES) )
{
Expand Down
34 changes: 22 additions & 12 deletions src/engine/renderer/tr_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,20 +209,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

cvar_t *r_gamma;

Cvar::Cvar<bool> r_tonemap( "r_tonemap", "Use HDR->LDR tonemapping", Cvar::NONE, true );
Cvar::Cvar<float> r_tonemapExposure( "r_tonemapExposure", "Tonemap exposure", Cvar::NONE, 1.0f );
Cvar::Range<Cvar::Cvar<float>> r_tonemapContrast( "r_tonemapContrast", "Makes dark areas light up faster",
Cvar::Cvar<bool> r_toneMapping(
"r_toneMapping", "Use HDR->LDR tonemapping", Cvar::NONE, true );
Cvar::Cvar<float> r_toneMappingExposure(
"r_toneMappingExposure", "Tonemap exposure", Cvar::NONE, 1.0f );
Cvar::Range<Cvar::Cvar<float>> r_toneMappingContrast(
"r_toneMappingContrast", "Makes dark areas light up faster",
Cvar::NONE, 1.6f, 1.0f, 10.0f );
Cvar::Range<Cvar::Cvar<float>> r_tonemapHighlightsCompressionSpeed( "r_tonemapHighlightsCompressionSpeed",
"Highlights saturation",
Cvar::Range<Cvar::Cvar<float>> r_toneMappingHighlightsCompressionSpeed(
"r_toneMappingHighlightsCompressionSpeed", "Highlights saturation",
Cvar::NONE, 0.977f, 0.0f, 10.0f );
Cvar::Range<Cvar::Cvar<float>> r_tonemapHDRMax( "r_tonemapHDRMax", "HDR white point",
Cvar::Range<Cvar::Cvar<float>> r_toneMappingHDRMax(
"r_toneMappingHDRMax", "HDR white point",
Cvar::NONE, 8.0f, 1.0f, 128.0f );
Cvar::Range<Cvar::Cvar<float>> r_tonemapDarkAreaPointHDR( "r_tonemapDarkAreaPointHDR",
"Cut-off for dark area light-up",
Cvar::Range<Cvar::Cvar<float>> r_toneMappingDarkAreaPointHDR(
"r_toneMappingDarkAreaPointHDR", "Cut-off for dark area light-up",
Cvar::NONE, 0.18f, 0.0f, 1.0f );
Cvar::Range<Cvar::Cvar<float>> r_tonemapDarkAreaPointLDR( "r_tonemapDarkAreaPointLDR",
"Convert to this brightness at dark area cut-off",
Cvar::Range<Cvar::Cvar<float>> r_toneMappingDarkAreaPointLDR(
"r_toneMappingDarkAreaPointLDR", "Convert to this brightness at dark area cut-off",
Cvar::NONE, 0.268f, 0.0f, 1.0f );

cvar_t *r_lockpvs;
Expand Down Expand Up @@ -316,7 +320,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Cvar::Cvar<float> r_bloomBlur( "r_bloomBlur", "Bloom strength", Cvar::NONE, 1.0 );
Cvar::Cvar<int> r_bloomPasses( "r_bloomPasses", "Amount of bloom passes in each direction", Cvar::NONE, 2 );
cvar_t *r_FXAA;
cvar_t *r_ssao;
Cvar::Range<Cvar::Cvar<int>> r_ssao( "r_ssao",
"Screen space ambient occlusion: "
"-1: show, 0: disabled, 1: enabled",
Cvar::NONE,
Util::ordinal( ssaoMode::DISABLED ),
Util::ordinal( ssaoMode::SHOW ),
Util::ordinal( ssaoMode::ENABLED ) );

cvar_t *r_evsmPostProcess;

Expand Down Expand Up @@ -1246,7 +1256,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p

Cvar::Latch( r_bloom );
r_FXAA = Cvar_Get( "r_FXAA", "0", CVAR_LATCH | CVAR_ARCHIVE );
r_ssao = Cvar_Get( "r_ssao", "0", CVAR_LATCH | CVAR_ARCHIVE );
Cvar::Latch( r_ssao );

// temporary variables that can change at any time
r_showImages = Cvar_Get( "r_showImages", "0", CVAR_TEMP );
Expand Down
22 changes: 14 additions & 8 deletions src/engine/renderer/tr_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,12 @@ enum class shaderProfilerRenderSubGroupsMode {
FS_ALL
};

enum class ssaoMode {
SHOW = -1,
DISABLED,
ENABLED,
};

enum class renderSpeeds_t
{
RSPEEDS_GENERAL = 1,
Expand Down Expand Up @@ -2964,13 +2970,13 @@ enum class shaderProfilerRenderSubGroupsMode {
extern cvar_t *r_mode; // video mode
extern cvar_t *r_gamma;

extern Cvar::Cvar<bool> r_tonemap;
extern Cvar::Cvar<float> r_tonemapExposure;
extern Cvar::Range<Cvar::Cvar<float>> r_tonemapContrast;
extern Cvar::Range<Cvar::Cvar<float>> r_tonemapHighlightsCompressionSpeed;
extern Cvar::Range<Cvar::Cvar<float>> r_tonemapHDRMax;
extern Cvar::Range<Cvar::Cvar<float>> r_tonemapDarkAreaPointHDR;
extern Cvar::Range<Cvar::Cvar<float>> r_tonemapDarkAreaPointLDR;
extern Cvar::Cvar<bool> r_toneMapping;
extern Cvar::Cvar<float> r_toneMappingExposure;
extern Cvar::Range<Cvar::Cvar<float>> r_toneMappingContrast;
extern Cvar::Range<Cvar::Cvar<float>> r_toneMappingHighlightsCompressionSpeed;
extern Cvar::Range<Cvar::Cvar<float>> r_toneMappingHDRMax;
extern Cvar::Range<Cvar::Cvar<float>> r_toneMappingDarkAreaPointHDR;
extern Cvar::Range<Cvar::Cvar<float>> r_toneMappingDarkAreaPointLDR;

extern cvar_t *r_nobind; // turns off binding to appropriate textures
extern cvar_t *r_singleShader; // make most world faces use default shader
Expand Down Expand Up @@ -3109,7 +3115,7 @@ enum class shaderProfilerRenderSubGroupsMode {
extern Cvar::Cvar<float> r_bloomBlur;
extern Cvar::Cvar<int> r_bloomPasses;
extern cvar_t *r_FXAA;
extern cvar_t *r_ssao;
extern Cvar::Range<Cvar::Cvar<int>> r_ssao;

extern cvar_t *r_evsmPostProcess;

Expand Down
1 change: 1 addition & 0 deletions src/engine/renderer/tr_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ struct glconfig2_t
bool reflectionMappingAvailable;
bool reflectionMapping;
bool bloom;
bool ssao;
bool motionBlur;
};

Expand Down
32 changes: 20 additions & 12 deletions src/engine/renderer/tr_shade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static void EnableAvailableFeatures()

if ( glConfig2.realtimeLightLayers > glConfig2.max3DTextureSize ) {
glConfig2.realtimeLightLayers = glConfig2.max3DTextureSize;
Log::Notice( "r_realtimeLightLayers exceeds maximum 3D texture size, using %i instead", glConfig2.max3DTextureSize );
Log::Notice( "r_realtimeLightLayers exceeds maximum 3D texture size, using %i instead.", glConfig2.max3DTextureSize );
}

Log::Notice( "Using %i dynamic light layers, %i dynamic lights available per tile", glConfig2.realtimeLightLayers,
Expand All @@ -98,7 +98,7 @@ static void EnableAvailableFeatures()
{
if ( !glConfig2.textureFloatAvailable )
{
Log::Warn( "Shadow mapping disabled because ARB_texture_float is not available" );
Log::Warn( "Shadow mapping disabled because ARB_texture_float is not available." );
glConfig2.shadowMapping = false;
}
}
Expand Down Expand Up @@ -136,14 +136,29 @@ static void EnableAvailableFeatures()
}
}


// Disable features that require deluxe mapping to be enabled.
glConfig2.normalMapping = glConfig2.deluxeMapping && glConfig2.normalMapping;
glConfig2.specularMapping = glConfig2.deluxeMapping && glConfig2.specularMapping;
glConfig2.physicalMapping = glConfig2.deluxeMapping && glConfig2.physicalMapping;

glConfig2.bloom = r_bloom.Get();

glConfig2.ssao = r_ssao.Get() != Util::ordinal( ssaoMode::DISABLED );

static const std::pair<bool*, std::string> ssaoRequiredExtensions[] = {
{ &glConfig2.textureGatherAvailable, "ARB_texture_gather" },
{ &glConfig2.gpuShader4Available, "EXT_gpu_shader4" },
};

for ( auto& e: ssaoRequiredExtensions )
{
if ( !*e.first )
{
Log::Warn( "SSAO disabled because %s is not available.", e.second );
glConfig2.ssao = false;
}
}

/* Motion blur is enabled by cg_motionblur which is a client cvar so we have to build it in all cases,
unless unsupported by the hardware which is the only condition when the engine knows it is not used. */
glConfig2.motionBlur = true;
Expand Down Expand Up @@ -369,16 +384,9 @@ static void GLSL_InitGPUShadersOrError()
gl_shaderManager.LoadShader( gl_motionblurShader );
}

if ( r_ssao->integer )
if ( glConfig2.ssao )
{
if ( glConfig2.textureGatherAvailable )
{
gl_shaderManager.LoadShader( gl_ssaoShader );
}
else
{
Log::Warn("SSAO not used because GL_ARB_texture_gather is not available.");
}
gl_shaderManager.LoadShader( gl_ssaoShader );
}

if ( r_FXAA->integer != 0 )
Expand Down