Skip to content
Draft
2 changes: 2 additions & 0 deletions src.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ set(GLSL_EMBED_LIST
lighttile_fp.glsl
computeLight_fp.glsl
reliefMapping_fp.glsl
luminanceReduction_cp.glsl
clearFrameData_cp.glsl

# Common vertex shader libraries
deformVertexes_vp.glsl
Expand Down
4 changes: 4 additions & 0 deletions src/engine/renderer/BufferBind.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ namespace BufferBind {
TEX_DATA_STORAGE = 11,
STAGING = 12,

// Adaptative exposure
LUMINANCE = 3,
LUMINANCE_STORAGE = 8,

DEBUG = 10,

// Atomic
Expand Down
1 change: 1 addition & 0 deletions src/engine/renderer/GLUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ struct GLConfig
bool gpuShader4Available;
bool gpuShader5Available;
bool textureGatherAvailable;
bool adaptiveExposureAvailable;
int maxDrawBuffers;

float maxTextureAnisotropy;
Expand Down
76 changes: 67 additions & 9 deletions src/engine/renderer/gl_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ GLShader_fxaa *gl_fxaaShader = nullptr;
GLShader_motionblur *gl_motionblurShader = nullptr;
GLShader_ssao *gl_ssaoShader = nullptr;

GLShader_depthtile1 *gl_depthtile1Shader = nullptr;
GLShader_depthtile2 *gl_depthtile2Shader = nullptr;
GLShader_lighttile *gl_lighttileShader = nullptr;
GLShader_depthtile1* gl_depthtile1Shader = nullptr;
GLShader_depthtile2* gl_depthtile2Shader = nullptr;
GLShader_lighttile* gl_lighttileShader = nullptr;
GLShader_luminanceReduction* gl_luminanceReductionShader = nullptr;
GLShader_clearFrameData* gl_clearFrameDataShader = nullptr;

GLShader_generic *gl_genericShader = nullptr;
GLShader_genericMaterial *gl_genericShaderMaterial = nullptr;
Expand All @@ -81,6 +83,7 @@ GLShader_skybox *gl_skyboxShader = nullptr;
GLShader_skyboxMaterial *gl_skyboxShaderMaterial = nullptr;
GlobalUBOProxy *globalUBOProxy = nullptr;
GLShaderManager gl_shaderManager;
GLBuffer luminanceBuffer( "luminance", Util::ordinal( BufferBind::LUMINANCE ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT );

namespace // Implementation details
{
Expand Down Expand Up @@ -419,6 +422,9 @@ static const std::vector<addedExtension_t> fragmentVertexAddedExtensions = {
where the core variables have different names. */
{ glConfig.shaderDrawParametersAvailable, -1, "ARB_shader_draw_parameters" },
{ glConfig.SSBOAvailable, 430, "ARB_shader_storage_buffer_object" },
{ glConfig.shadingLanguage420PackAvailable, 420, "ARB_shading_language_420pack" },
{ glConfig.explicitUniformLocationAvailable, 430, "ARB_explicit_uniform_location" },
{ glConfig.shaderAtomicCountersAvailable, 420, "ARB_shader_atomic_counters" },
/* Even though these are part of the GL_KHR_shader_subgroup extension, we need to enable
the individual extensions for each feature.
GL_KHR_shader_subgroup itself can't be used in the shader. */
Expand Down Expand Up @@ -490,10 +496,14 @@ static void AddConst( std::string& str, const std::string& name, float v1, float

static std::string GenVersionDeclaration( const std::vector<addedExtension_t> &addedExtensions ) {
// Declare version.
std::string str = Str::Format( "#version %d %s\n\n",
std::string str = Str::Format( "#version %d %s\n",
glConfig.shadingLanguageVersion,
glConfig.shadingLanguageVersion >= 150 ? ( glConfig.glCoreProfile ? "core" : "compatibility" ) : "" );

str += "#line 1000000000\n";

str += "\n";

// Add supported GLSL extensions.
for ( const auto& addedExtension : addedExtensions ) {
addExtension( str, addedExtension.available, addedExtension.minGlslVersion, addedExtension.name );
Expand Down Expand Up @@ -580,6 +590,10 @@ static std::string GenVertexHeader() {
AddDefine( str, "BIND_LIGHTMAP_DATA", BufferBind::LIGHTMAP_DATA );
}

if ( glConfig.adaptiveExposureAvailable ) {
AddDefine( str, "BIND_LUMINANCE", Util::ordinal( BufferBind::LUMINANCE ) );
}

return str;
}

Expand Down Expand Up @@ -629,6 +643,11 @@ static std::string GenFragmentHeader() {
AddDefine( str, "USE_PUSH_BUFFER", 1 );
}

if ( glConfig.adaptiveExposureAvailable ) {
AddDefine( str, "BIND_LUMINANCE", Util::ordinal( BufferBind::LUMINANCE ) );
AddDefine( str, "ADAPTIVE_EXPOSURE_AVAILABLE", 1 );
}

return str;
}

Expand All @@ -654,6 +673,11 @@ static std::string GenComputeHeader() {
AddDefine( str, "BIND_DEBUG", BufferBind::DEBUG );
}

if ( glConfig.adaptiveExposureAvailable ) {
AddDefine( str, "BIND_LUMINANCE", Util::ordinal( BufferBind::LUMINANCE ) );
AddDefine( str, "BIND_LUMINANCE_STORAGE", Util::ordinal( BufferBind::LUMINANCE_STORAGE ) );
}

if ( glConfig.pushBufferAvailable ) {
AddDefine( str, "USE_PUSH_BUFFER", 1 );
}
Expand Down Expand Up @@ -838,7 +862,10 @@ std::string GLShaderManager::GetDeformShaderName( const int index ) {
std::string GLShaderManager::BuildDeformShaderText( const std::string& steps ) {
std::string shaderText;

shaderText = steps + "\n";
shaderText = "\n" + steps + "\n";

shaderText += "#line 2000000000\n";

shaderText += GetShaderText( "deformVertexes_vp.glsl" );

return shaderText;
Expand Down Expand Up @@ -1194,6 +1221,13 @@ std::string GLShaderManager::ProcessInserts( const std::string& shaderText ) con

while ( std::getline( shaderTextStream, line, '\n' ) ) {
++lineCount;

/* The deform vertex header is prepended to the mainText and is part
of the shaderText, so we should reset line numbering after it. */
if ( line == "#line 0" ) {
lineCount = 0;
}

const std::string::size_type position = line.find( "#insert" );
if ( position == std::string::npos || line.find_first_not_of( " \t" ) != position ) {
out += line + "\n";
Expand Down Expand Up @@ -1324,7 +1358,9 @@ void GLShaderManager::InitShader( GLShader* shader ) {
if ( shaderType.enabled ) {
Com_sprintf( filename, sizeof( filename ), "%s%s.glsl", shaderType.path.c_str(), shaderType.postfix );

shaderType.mainText = GetShaderText( filename );
/* The deform vertex header is prepended to the mainText,
so we should reset line numbering after it. */
shaderType.mainText = "#line 0\n" + GetShaderText( filename );
}
}

Expand Down Expand Up @@ -2607,6 +2643,23 @@ GLShader_lightMappingMaterial::GLShader_lightMappingMaterial() :
GLCompileMacro_USE_PHYSICAL_MAPPING( this ) {
}

GLShader_luminanceReduction::GLShader_luminanceReduction() :
GLShader( "luminanceReduction",
false, "luminanceReduction" ),
u_ViewWidth( this ),
u_ViewHeight( this ),
u_TonemapParms2( this ) {
}

void GLShader_luminanceReduction::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) {
glUniform1i( glGetUniformLocation( shaderProgram->id, "initialRenderImage" ), 0 );
}

GLShader_clearFrameData::GLShader_clearFrameData() :
GLShader( "clearFrameData",
false, "clearFrameData" ) {
}

GLShader_reflection::GLShader_reflection():
GLShader( "reflection", ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT,
false, "reflection_CB", "reflection_CB" ),
Expand Down Expand Up @@ -2802,11 +2855,14 @@ GLShader_cameraEffects::GLShader_cameraEffects() :
u_GlobalLightFactor( this ),
u_ColorModulate( this ),
u_SRGB( this ),
u_ViewWidth( this ),
u_ViewHeight( this ),
u_Tonemap( this ),
u_TonemapParms( this ),
u_TonemapAdaptiveExposure( this ),
u_TonemapParms2( this ),
u_Exposure( this ),
u_InverseGamma( this )
{
u_InverseGamma( this ) {
}

void GLShader_cameraEffects::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram )
Expand Down Expand Up @@ -3065,5 +3121,7 @@ GlobalUBOProxy::GlobalUBOProxy() :
u_InverseGamma( this ),
u_Tonemap( this ),
u_TonemapParms( this ),
u_TonemapAdaptiveExposure( this ),
u_TonemapParms2( this ),
u_Exposure( this ) {
}
}
55 changes: 52 additions & 3 deletions src/engine/renderer/gl_shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -2804,6 +2804,18 @@ class u_Tonemap :
}
};

class u_TonemapAdaptiveExposure :
GLUniform1Bool {
public:
u_TonemapAdaptiveExposure( GLShader* shader ) :
GLUniform1Bool( shader, "u_TonemapAdaptiveExposure", FRAME ) {
}

void SetUniform_TonemapAdaptiveExposure( bool tonemapAdaptiveExposure ) {
this->SetValue( tonemapAdaptiveExposure );
}
};

class u_TonemapParms :
GLUniform4f {
public:
Expand All @@ -2816,6 +2828,18 @@ class u_TonemapParms :
}
};

class u_TonemapParms2 :
GLUniform4f {
public:
u_TonemapParms2( GLShader* shader ) :
GLUniform4f( shader, "u_TonemapParms2", FRAME ) {
}

void SetUniform_TonemapParms2( vec4_t tonemapParms2 ) {
this->SetValue( tonemapParms2 );
}
};

class u_Exposure :
GLUniform1f {
public:
Expand Down Expand Up @@ -3084,6 +3108,22 @@ class GLShader_lightMappingMaterial :
GLShader_lightMappingMaterial();
};

class GLShader_luminanceReduction :
public GLShader,
public u_ViewWidth,
public u_ViewHeight,
public u_TonemapParms2 {
public:
GLShader_luminanceReduction();
void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override;
};

class GLShader_clearFrameData :
public GLShader {
public:
GLShader_clearFrameData();
};

class GLShader_reflection :
public GLShader,
public u_ColorMapCube,
Expand Down Expand Up @@ -3257,8 +3297,12 @@ class GLShader_cameraEffects :
public u_GlobalLightFactor,
public u_ColorModulate,
public u_SRGB,
public u_ViewWidth,
public u_ViewHeight,
public u_Tonemap,
public u_TonemapParms,
public u_TonemapAdaptiveExposure,
public u_TonemapParms2,
public u_Exposure,
public u_InverseGamma
{
Expand Down Expand Up @@ -3489,6 +3533,8 @@ class GlobalUBOProxy :
public u_InverseGamma,
public u_Tonemap,
public u_TonemapParms,
public u_TonemapAdaptiveExposure,
public u_TonemapParms2,
public u_Exposure {

public:
Expand All @@ -3513,9 +3559,11 @@ extern GLShader_fxaa *gl_fxaaShader;
extern GLShader_motionblur *gl_motionblurShader;
extern GLShader_ssao *gl_ssaoShader;

extern GLShader_depthtile1 *gl_depthtile1Shader;
extern GLShader_depthtile2 *gl_depthtile2Shader;
extern GLShader_lighttile *gl_lighttileShader;
extern GLShader_depthtile1* gl_depthtile1Shader;
extern GLShader_depthtile2* gl_depthtile2Shader;
extern GLShader_lighttile* gl_lighttileShader;
extern GLShader_luminanceReduction* gl_luminanceReductionShader;
extern GLShader_clearFrameData* gl_clearFrameDataShader;

extern GLShader_generic *gl_genericShader;
extern GLShader_genericMaterial *gl_genericShaderMaterial;
Expand All @@ -3534,5 +3582,6 @@ extern GLShader_skybox *gl_skyboxShader;
extern GLShader_skyboxMaterial *gl_skyboxShaderMaterial;
extern GlobalUBOProxy *globalUBOProxy;
extern GLShaderManager gl_shaderManager;
extern GLBuffer luminanceBuffer;

#endif // GL_SHADER_H
48 changes: 39 additions & 9 deletions src/engine/renderer/glsl_source/cameraEffects_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
uniform sampler2D u_CurrentMap;

#if defined(r_colorGrading)
uniform sampler3D u_ColorMap3D;
uniform sampler3D u_ColorMap3D;
#endif

uniform vec4 u_ColorModulate;
uniform float u_GlobalLightFactor; // 1 / tr.identityLight
uniform float u_InverseGamma;
uniform vec4 u_ColorModulate;
uniform float u_GlobalLightFactor; // 1 / tr.identityLight
uniform float u_InverseGamma;
uniform bool u_SRGB;

void convertToSRGB(inout vec3 color) {
Expand All @@ -58,24 +58,43 @@ uniform float u_Exposure;

// Tone mapping is not available when high-precision float framebuffer isn't enabled or supported.
#if defined(r_highPrecisionRendering) && defined(HAVE_ARB_texture_float)
uniform uint u_ViewWidth;
uniform uint u_ViewHeight;

uniform bool u_Tonemap;
#if defined(ADAPTIVE_EXPOSURE_AVAILABLE)
uniform bool u_TonemapAdaptiveExposure;
#endif
/* x: contrast
y: highlightsCompressionSpeed
z: shoulderClip
w: highlightsCompression */
uniform bool u_Tonemap;
uniform vec4 u_TonemapParms;
#if defined(ADAPTIVE_EXPOSURE_AVAILABLE)
uniform vec4 u_TonemapParms2;
#endif

vec3 TonemapLottes( vec3 color ) {
// Lottes 2016, "Advanced Techniques and Optimization of HDR Color Pipelines"
return pow( color, vec3( u_TonemapParms[0] ) )
/ ( pow( color, vec3( u_TonemapParms[0] * u_TonemapParms[1] ) ) * u_TonemapParms[2] + u_TonemapParms[3] );
}

#if defined(ADAPTIVE_EXPOSURE_AVAILABLE)
layout(std140, binding = BIND_LUMINANCE) uniform ub_LuminanceUBO {
uint luminanceU;
};

float GetAverageLuminance( const in uint luminance ) {
return float( luminanceU ) / ( u_TonemapParms2[1] * u_ViewWidth * u_ViewHeight );
}
#endif

#endif

DECLARE_OUTPUT(vec4)

void main()
{
void main() {
#insert material_fp

// calculate the screen texcoord in the 0.0 to 1.0 range
Expand All @@ -84,13 +103,24 @@ void main()
vec4 color = texture2D(u_CurrentMap, st);
color *= u_GlobalLightFactor;

color.rgb *= u_Exposure;

#if defined(r_highPrecisionRendering) && defined(HAVE_ARB_texture_float)
if( u_Tonemap ) {
#if defined(ADAPTIVE_EXPOSURE_AVAILABLE)
if ( u_TonemapAdaptiveExposure ) {
const float l = GetAverageLuminance( luminanceU ) - 8;
color.rgb *= clamp( 0.18f / exp2( l * 0.8f + 0.1f ), 0.0f, 2.0f );
}
#endif

color.rgb *= u_Exposure;

color.rgb = TonemapLottes( color.rgb );
}
else
#endif
{
color.rgb *= u_Exposure;
}

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

Expand Down
Loading
Loading