Skip to content

Commit a26cfed

Browse files
committed
renderer: implement GLSL sRGB lightmapping
1 parent aedc03f commit a26cfed

15 files changed

+350
-11
lines changed

src.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ set(GLSLSOURCELIST
153153
${ENGINE_DIR}/renderer/glsl_source/blurY_vp.glsl
154154
${ENGINE_DIR}/renderer/glsl_source/cameraEffects_fp.glsl
155155
${ENGINE_DIR}/renderer/glsl_source/cameraEffects_vp.glsl
156+
${ENGINE_DIR}/renderer/glsl_source/colorSpace_fp.glsl
156157
${ENGINE_DIR}/renderer/glsl_source/computeLight_fp.glsl
157158
${ENGINE_DIR}/renderer/glsl_source/contrast_fp.glsl
158159
${ENGINE_DIR}/renderer/glsl_source/contrast_vp.glsl

src/common/Color.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3838
#include "Compiler.h"
3939
#include "Math.h"
4040

41+
#define convertFromSRGB( v ) v <= 0.04045f ? v * (1.0f / 12.92f) : pow((v + 0.055f) * (1.0f / 1.055f), 2.4f)
42+
4143
namespace Color {
4244

4345
/*
@@ -80,6 +82,7 @@ template<>
8082
* component_type Alpha() const; // Alpha component
8183
*
8284
*/
85+
8386
template<class T>
8487
class ColorAdaptor;
8588

@@ -256,6 +259,18 @@ class BasicColor
256259
alpha = v;
257260
}
258261

262+
CONSTEXPR_FUNCTION_RELAXED component_type ConvertFromSRGB( component_type v ) NOEXCEPT
263+
{
264+
return convertFromSRGB( v );
265+
}
266+
267+
CONSTEXPR_FUNCTION_RELAXED void ConvertFromSRGB() NOEXCEPT
268+
{
269+
red = ConvertFromSRGB( red );
270+
green = ConvertFromSRGB( green );
271+
blue = ConvertFromSRGB( blue );
272+
}
273+
259274
CONSTEXPR_FUNCTION_RELAXED BasicColor& operator*=( float factor ) NOEXCEPT
260275
{
261276
*this = *this * factor;

src/engine/renderer/gl_shader.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,7 @@ GLShader_generic::GLShader_generic( GLShaderManager *manager ) :
15851585
u_Bones( this ),
15861586
u_VertexInterpolation( this ),
15871587
u_DepthScale( this ),
1588+
u_LinearizeTexture( this ),
15881589
GLDeformStage( this ),
15891590
GLCompileMacro_USE_VERTEX_SKINNING( this ),
15901591
GLCompileMacro_USE_VERTEX_ANIMATION( this ),
@@ -1596,6 +1597,11 @@ GLShader_generic::GLShader_generic( GLShaderManager *manager ) :
15961597
{
15971598
}
15981599

1600+
void GLShader_generic::BuildShaderFragmentLibNames( std::string& fragmentInlines )
1601+
{
1602+
fragmentInlines += "colorSpace";
1603+
}
1604+
15991605
void GLShader_generic::BuildShaderVertexLibNames( std::string& vertexInlines )
16001606
{
16011607
vertexInlines += "vertexSimple vertexSkinning vertexAnimation vertexSprite ";
@@ -1628,6 +1634,8 @@ GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) :
16281634
u_LightGridScale( this ),
16291635
u_numLights( this ),
16301636
u_Lights( this ),
1637+
u_LinearizeTexture( this ),
1638+
u_LinearizeLightMap( this ),
16311639
GLDeformStage( this ),
16321640
GLCompileMacro_USE_BSP_SURFACE( this ),
16331641
GLCompileMacro_USE_VERTEX_SKINNING( this ),
@@ -1649,7 +1657,7 @@ void GLShader_lightMapping::BuildShaderVertexLibNames( std::string& vertexInline
16491657

16501658
void GLShader_lightMapping::BuildShaderFragmentLibNames( std::string& fragmentInlines )
16511659
{
1652-
fragmentInlines += "computeLight reliefMapping";
1660+
fragmentInlines += "colorSpace computeLight reliefMapping";
16531661
}
16541662

16551663
void GLShader_lightMapping::BuildShaderCompileMacros( std::string& /*compileMacros*/ )
@@ -1695,6 +1703,8 @@ GLShader_forwardLighting_omniXYZ::GLShader_forwardLighting_omniXYZ( GLShaderMana
16951703
u_ReliefDepthScale( this ),
16961704
u_ReliefOffsetBias( this ),
16971705
u_NormalScale( this ),
1706+
u_LinearizeTexture( this ),
1707+
u_LinearizeLightMap( this ),
16981708
GLDeformStage( this ),
16991709
GLCompileMacro_USE_VERTEX_SKINNING( this ),
17001710
GLCompileMacro_USE_VERTEX_ANIMATION( this ),
@@ -1711,7 +1721,7 @@ void GLShader_forwardLighting_omniXYZ::BuildShaderVertexLibNames( std::string& v
17111721

17121722
void GLShader_forwardLighting_omniXYZ::BuildShaderFragmentLibNames( std::string& fragmentInlines )
17131723
{
1714-
fragmentInlines += "computeLight reliefMapping";
1724+
fragmentInlines += "colorSpace computeLight reliefMapping";
17151725
}
17161726

17171727
void GLShader_forwardLighting_omniXYZ::BuildShaderCompileMacros( std::string& /*compileMacros*/ )
@@ -1754,6 +1764,8 @@ GLShader_forwardLighting_projXYZ::GLShader_forwardLighting_projXYZ( GLShaderMana
17541764
u_ReliefDepthScale( this ),
17551765
u_ReliefOffsetBias( this ),
17561766
u_NormalScale( this ),
1767+
u_LinearizeTexture( this ),
1768+
u_LinearizeLightMap( this ),
17571769
GLDeformStage( this ),
17581770
GLCompileMacro_USE_VERTEX_SKINNING( this ),
17591771
GLCompileMacro_USE_VERTEX_ANIMATION( this ),
@@ -1770,7 +1782,7 @@ void GLShader_forwardLighting_projXYZ::BuildShaderVertexLibNames( std::string& v
17701782

17711783
void GLShader_forwardLighting_projXYZ::BuildShaderFragmentLibNames( std::string& fragmentInlines )
17721784
{
1773-
fragmentInlines += "computeLight reliefMapping";
1785+
fragmentInlines += "colorSpace computeLight reliefMapping";
17741786
}
17751787

17761788
void GLShader_forwardLighting_projXYZ::BuildShaderCompileMacros( std::string& compileMacros )
@@ -1816,6 +1828,8 @@ GLShader_forwardLighting_directionalSun::GLShader_forwardLighting_directionalSun
18161828
u_ReliefDepthScale( this ),
18171829
u_ReliefOffsetBias( this ),
18181830
u_NormalScale( this ),
1831+
u_LinearizeTexture( this ),
1832+
u_LinearizeLightMap( this ),
18191833
GLDeformStage( this ),
18201834
GLCompileMacro_USE_VERTEX_SKINNING( this ),
18211835
GLCompileMacro_USE_VERTEX_ANIMATION( this ),
@@ -1832,7 +1846,7 @@ void GLShader_forwardLighting_directionalSun::BuildShaderVertexLibNames( std::st
18321846

18331847
void GLShader_forwardLighting_directionalSun::BuildShaderFragmentLibNames( std::string& fragmentInlines )
18341848
{
1835-
fragmentInlines += "computeLight reliefMapping";
1849+
fragmentInlines += "colorSpace computeLight reliefMapping";
18361850
}
18371851

18381852
void GLShader_forwardLighting_directionalSun::BuildShaderCompileMacros( std::string& compileMacros )
@@ -2069,8 +2083,14 @@ GLShader_cameraEffects::GLShader_cameraEffects( GLShaderManager *manager ) :
20692083
u_TextureMatrix( this ),
20702084
u_ModelViewProjectionMatrix( this ),
20712085
u_DeformMagnitude( this ),
2072-
u_InverseGamma( this )
2086+
u_InverseGamma( this ),
2087+
u_DelinearizeScreen( this )
2088+
{
2089+
}
2090+
2091+
void GLShader_cameraEffects::BuildShaderFragmentLibNames( std::string& fragmentInlines )
20732092
{
2093+
fragmentInlines += "colorSpace";
20742094
}
20752095

20762096
void GLShader_cameraEffects::SetShaderProgramUniforms( shaderProgram_t *shaderProgram )
@@ -2142,7 +2162,7 @@ GLShader_liquid::GLShader_liquid( GLShaderManager *manager ) :
21422162

21432163
void GLShader_liquid::BuildShaderFragmentLibNames( std::string& fragmentInlines )
21442164
{
2145-
fragmentInlines += "computeLight reliefMapping";
2165+
fragmentInlines += "colorSpace computeLight reliefMapping";
21462166
}
21472167

21482168
void GLShader_liquid::SetShaderProgramUniforms( shaderProgram_t *shaderProgram )

src/engine/renderer/gl_shader.h

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,51 @@ class u_ShadowTexelSize :
15271527
}
15281528
};
15291529

1530+
class u_LinearizeTexture :
1531+
GLUniform1i
1532+
{
1533+
public:
1534+
u_LinearizeTexture( GLShader *shader ) :
1535+
GLUniform1i( shader, "u_LinearizeTexture" )
1536+
{
1537+
}
1538+
1539+
void SetUniform_LinearizeTexture( bool value )
1540+
{
1541+
this->SetValue( (int) value );
1542+
}
1543+
};
1544+
1545+
class u_LinearizeLightMap :
1546+
GLUniform1i
1547+
{
1548+
public:
1549+
u_LinearizeLightMap( GLShader *shader ) :
1550+
GLUniform1i( shader, "u_LinearizeLightMap" )
1551+
{
1552+
}
1553+
1554+
void SetUniform_LinearizeLightMap( bool value )
1555+
{
1556+
this->SetValue( (int) value );
1557+
}
1558+
};
1559+
1560+
class u_DelinearizeScreen :
1561+
GLUniform1i
1562+
{
1563+
public:
1564+
u_DelinearizeScreen( GLShader *shader ) :
1565+
GLUniform1i( shader, "u_DelinearizeScreen" )
1566+
{
1567+
}
1568+
1569+
void SetUniform_DelinearizeScreen( bool value )
1570+
{
1571+
this->SetValue( (int) value );
1572+
}
1573+
};
1574+
15301575
class u_ShadowBlur :
15311576
GLUniform1f
15321577
{
@@ -2250,6 +2295,7 @@ class GLShader_generic :
22502295
public u_Bones,
22512296
public u_VertexInterpolation,
22522297
public u_DepthScale,
2298+
public u_LinearizeTexture,
22532299
public GLDeformStage,
22542300
public GLCompileMacro_USE_VERTEX_SKINNING,
22552301
public GLCompileMacro_USE_VERTEX_ANIMATION,
@@ -2262,6 +2308,7 @@ class GLShader_generic :
22622308
public:
22632309
GLShader_generic( GLShaderManager *manager );
22642310
void BuildShaderVertexLibNames( std::string& vertexInlines ) override;
2311+
void BuildShaderFragmentLibNames( std::string& vertexInlines ) override;
22652312
void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override;
22662313
};
22672314

@@ -2285,6 +2332,8 @@ class GLShader_lightMapping :
22852332
public u_LightGridScale,
22862333
public u_numLights,
22872334
public u_Lights,
2335+
public u_LinearizeTexture,
2336+
public u_LinearizeLightMap,
22882337
public GLDeformStage,
22892338
public GLCompileMacro_USE_BSP_SURFACE,
22902339
public GLCompileMacro_USE_VERTEX_SKINNING,
@@ -2327,6 +2376,8 @@ class GLShader_forwardLighting_omniXYZ :
23272376
public u_ReliefDepthScale,
23282377
public u_ReliefOffsetBias,
23292378
public u_NormalScale,
2379+
public u_LinearizeTexture,
2380+
public u_LinearizeLightMap,
23302381
public GLDeformStage,
23312382
public GLCompileMacro_USE_VERTEX_SKINNING,
23322383
public GLCompileMacro_USE_VERTEX_ANIMATION,
@@ -2365,6 +2416,8 @@ class GLShader_forwardLighting_projXYZ :
23652416
public u_ReliefDepthScale,
23662417
public u_ReliefOffsetBias,
23672418
public u_NormalScale,
2419+
public u_LinearizeTexture,
2420+
public u_LinearizeLightMap,
23682421
public GLDeformStage,
23692422
public GLCompileMacro_USE_VERTEX_SKINNING,
23702423
public GLCompileMacro_USE_VERTEX_ANIMATION,
@@ -2405,6 +2458,8 @@ class GLShader_forwardLighting_directionalSun :
24052458
public u_ReliefDepthScale,
24062459
public u_ReliefOffsetBias,
24072460
public u_NormalScale,
2461+
public u_LinearizeTexture,
2462+
public u_LinearizeLightMap,
24082463
public GLDeformStage,
24092464
public GLCompileMacro_USE_VERTEX_SKINNING,
24102465
public GLCompileMacro_USE_VERTEX_ANIMATION,
@@ -2579,11 +2634,13 @@ class GLShader_cameraEffects :
25792634
public u_TextureMatrix,
25802635
public u_ModelViewProjectionMatrix,
25812636
public u_DeformMagnitude,
2582-
public u_InverseGamma
2637+
public u_InverseGamma,
2638+
public u_DelinearizeScreen
25832639
{
25842640
public:
25852641
GLShader_cameraEffects( GLShaderManager *manager );
25862642
void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override;
2643+
void BuildShaderFragmentLibNames( std::string& vertexInlines ) override;
25872644
};
25882645

25892646
class GLShader_blurX :

src/engine/renderer/glsl_source/cameraEffects_fp.glsl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ uniform sampler2D u_CurrentMap;
2626
uniform sampler3D u_ColorMap;
2727
uniform vec4 u_ColorModulate;
2828
uniform float u_InverseGamma;
29+
uniform int u_DelinearizeScreen;
2930

3031
IN(smooth) vec2 var_TexCoords;
3132

@@ -36,9 +37,14 @@ void main()
3637
// calculate the screen texcoord in the 0.0 to 1.0 range
3738
vec2 st = gl_FragCoord.st / r_FBufSize;
3839

39-
vec4 original = clamp(texture2D(u_CurrentMap, st), 0.0, 1.0);
40+
vec4 original = texture2D(u_CurrentMap, st);
4041

41-
vec4 color = original;
42+
if (u_DelinearizeScreen == 1)
43+
{
44+
convertToSRGB(original.rgb);
45+
}
46+
47+
vec4 color = clamp(original, 0.0, 1.0);
4248

4349
// apply color grading
4450
vec3 colCoord = color.rgb * 15.0 / 16.0 + 0.5 / 16.0;
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#define SRGB_CHEAP
2+
3+
void convertFromSRGB(inout vec3 color) {
4+
#if defined(SRGB_CHEAP)
5+
float gamma = 2.2;
6+
color = pow(color, vec3(gamma));
7+
8+
#elif defined(SRGB_NAIVE)
9+
// (((c) <= 0.04045f) ? (c) * (1.0f / 12.92f) : (float)pow(((c) + 0.055f)*(1.0f/1.055f), 2.4f))
10+
11+
float threshold = 0.0031308f;
12+
13+
color.r = color.r <= threshold ? color.r * (1.0f / 12.92f) : pow((color.r + 0.055f) * (1.0f / 1.055f), 2.4f);
14+
color.g = color.g <= threshold ? color.g * (1.0f / 12.92f) : pow((color.g + 0.055f) * (1.0f / 1.055f), 2.4f);
15+
color.b = color.b <= threshold ? color.b * (1.0f / 12.92f) : pow((color.b + 0.055f) * (1.0f / 1.055f), 2.4f);
16+
#elif defined(SRGB_FBOOL)
17+
float threshold = 0.0031308f;
18+
19+
vec3 yes = vec3(float(color.r <= threshold), float(color.g <= threshold), float(color.b <= threshold));
20+
vec3 no = yes * -1.0f + 1.0f;
21+
22+
vec3 low = color * (1.0f / 12.92f);
23+
vec3 high = pow((color + 0.055f) * (1.0f / 1.055f), vec3(2.4f));
24+
25+
color = (yes * low) + (no * high);
26+
#elif defined(SRGB_BOOL)
27+
float threshold = 0.0031308f;
28+
29+
bvec3 yes = bvec3(color.r <= threshold, color.g <= threshold, color.b <= threshold);
30+
bvec3 no = bvec3(!yes.x, !yes.y, !yes.z);
31+
32+
vec3 low = color * (1.0f / 12.92f);
33+
vec3 high = pow((color + 0.055f) * (1.0f / 1.055f), vec3(2.4f));
34+
35+
color = (float(yes) * low) + (float(no) * high);
36+
#elif defined(SRGB_MIX)
37+
float threshold = 0.0031308f;
38+
39+
bvec3 cutoff = lessThan(color, vec3(threshold));
40+
vec3 low = color / vec3(12.92f);
41+
vec3 high = pow((color + vec3(0.055f)) / vec3(1.055f), vec3(2.4f));
42+
43+
color = mix(high, low, cutoff);
44+
#else
45+
#error undefined SRGB computation
46+
#endif
47+
}
48+
49+
void convertToSRGB(inout vec3 color) {
50+
#if defined(SRGB_CHEAP)
51+
float gamma = 2.2;
52+
color = pow(color, vec3(1/gamma));
53+
#elif defined(SRGB_NAIVE)
54+
// (((c) < 0.0031308f) ? (c) * 12.92f : 1.055f * (float)pow((c), 1.0f/2.4f) - 0.055f)
55+
float threshold = 0.0031308f;
56+
57+
color.r = color.r < threshold ? color.r * 12.92f : 1.055f * pow(color.r, 1.0f / 2.4f) - 0.055f;
58+
color.g = color.g < threshold ? color.g * 12.92f : 1.055f * pow(color.g, 1.0f / 2.4f) - 0.055f;
59+
color.b = color.b < threshold ? color.b * 12.92f : 1.055f * pow(color.b, 1.0f / 2.4f) - 0.055f;
60+
#elif defined(SRGB_FBOOL)
61+
float threshold = 0.0031308f;
62+
63+
vec3 yes = vec3(float(color.r < threshold), float(color.g < threshold), float(color.b < threshold));
64+
vec3 no = yes * -1.0f + 1.0f;
65+
66+
vec3 low = color * 12.92f;
67+
vec3 high = pow(color, vec3( 1.0f / 2.4f)) - 0.055f;
68+
69+
color = (yes * low) + (no * high);
70+
#elif defined(SRGB_BOOL)
71+
float threshold = 0.0031308f;
72+
73+
bvec3 yes = bvec3(color.r < threshold, color.g < threshold, color.b < threshold);
74+
bvec3 no = bvec3(!yes.x, !yes.y, !yes.z);
75+
76+
vec3 low = color * 12.92f;
77+
vec3 high = pow(color, vec3( 1.0f / 2.4f)) - 0.055f;
78+
79+
color = (float(yes) * low) + (float(no) * high);
80+
#elif defined(SRGB_MIX)
81+
float threshold = 0.0031308f;
82+
83+
bvec3 cutoff = lessThan(color, vec3(threshold));
84+
vec3 low = vec3(12.92f) * color;
85+
vec3 high = vec3(1.055f) * pow(color, vec3(1.0f / 2.4f)) - vec3(0.055f);
86+
87+
color = mix(high, low, cutoff);
88+
#else
89+
#error undefined SRGB computation
90+
#endif
91+
}

0 commit comments

Comments
 (0)