@@ -451,6 +451,14 @@ static void R_LoadLightmaps( lump_t *l, const char *bspName )
451
451
return ;
452
452
}
453
453
454
+ int lightmapBits = IF_LIGHTMAP | IF_NOPICMIP;
455
+ int deluxemapBits = IF_NORMALMAP | IF_NOPICMIP;
456
+
457
+ if ( tr.worldLinearizeLightMap )
458
+ {
459
+ lightmapBits |= IF_SRGB;
460
+ }
461
+
454
462
int len = l->filelen ;
455
463
if ( !len )
456
464
{
@@ -493,7 +501,7 @@ static void R_LoadLightmaps( lump_t *l, const char *bspName )
493
501
LoadRGBEToBytes ( va ( " %s/%s" , mapName, filename.c_str () ), &ldrImage, &width, &height );
494
502
495
503
imageParams_t imageParams = {};
496
- imageParams.bits = IF_NOPICMIP | IF_LIGHTMAP ;
504
+ imageParams.bits = lightmapBits ;
497
505
imageParams.filterType = filterType_t::FT_DEFAULT;
498
506
imageParams.wrapType = wrapTypeEnum_t::WT_CLAMP;
499
507
@@ -520,7 +528,7 @@ static void R_LoadLightmaps( lump_t *l, const char *bspName )
520
528
Log::Debug (" ...loading external lightmap '%s/%s'" , mapName, filename);
521
529
522
530
imageParams_t imageParams = {};
523
- imageParams.bits = IF_NOPICMIP | IF_NORMALMAP ;
531
+ imageParams.bits = deluxemapBits ;
524
532
imageParams.filterType = filterType_t::FT_DEFAULT;
525
533
imageParams.wrapType = wrapTypeEnum_t::WT_CLAMP;
526
534
@@ -549,7 +557,7 @@ static void R_LoadLightmaps( lump_t *l, const char *bspName )
549
557
550
558
if (!tr.worldDeluxeMapping || i % 2 == 0 ) {
551
559
imageParams_t imageParams = {};
552
- imageParams.bits = IF_NOPICMIP | IF_LIGHTMAP ;
560
+ imageParams.bits = lightmapBits ;
553
561
imageParams.filterType = filterType_t::FT_LINEAR;
554
562
imageParams.wrapType = wrapTypeEnum_t::WT_CLAMP;
555
563
@@ -559,7 +567,7 @@ static void R_LoadLightmaps( lump_t *l, const char *bspName )
559
567
else if (tr.worldDeluxeMapping )
560
568
{
561
569
imageParams_t imageParams = {};
562
- imageParams.bits = IF_NOPICMIP | IF_NORMALMAP ;
570
+ imageParams.bits = deluxemapBits ;
563
571
imageParams.filterType = filterType_t::FT_LINEAR;
564
572
imageParams.wrapType = wrapTypeEnum_t::WT_CLAMP;
565
573
@@ -629,7 +637,7 @@ static void R_LoadLightmaps( lump_t *l, const char *bspName )
629
637
}
630
638
631
639
imageParams_t imageParams = {};
632
- imageParams.bits = IF_NOPICMIP | IF_LIGHTMAP ;
640
+ imageParams.bits = lightmapBits ;
633
641
imageParams.filterType = filterType_t::FT_DEFAULT;
634
642
imageParams.wrapType = wrapTypeEnum_t::WT_CLAMP;
635
643
@@ -972,6 +980,11 @@ static void ParseTriangleSurface( dsurface_t* ds, drawVert_t* verts, bspSurface_
972
980
973
981
cv->verts [ i ].lightColor = Color::Adapt ( verts[ i ].color );
974
982
983
+ if ( tr.worldLinearizeLightMap )
984
+ {
985
+ cv->verts [ i ].lightColor .ConvertFromSRGB ();
986
+ }
987
+
975
988
if ( tr.overbrightBits < tr.mapOverBrightBits ) {
976
989
R_ColorShiftLightingBytes ( cv->verts [ i ].lightColor .ToArray () );
977
990
}
@@ -1206,6 +1219,11 @@ static void ParseMesh( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf )
1206
1219
1207
1220
points[ i ].lightColor = Color::Adapt ( verts[ i ].color );
1208
1221
1222
+ if ( tr.worldLinearizeLightMap )
1223
+ {
1224
+ points[ i ].lightColor .ConvertFromSRGB ();
1225
+ }
1226
+
1209
1227
if ( tr.overbrightBits < tr.mapOverBrightBits )
1210
1228
{
1211
1229
R_ColorShiftLightingBytes ( points[ i ].lightColor .ToArray () );
@@ -3502,6 +3520,12 @@ void R_LoadLightGrid( lump_t *l )
3502
3520
{
3503
3521
ambientColor[ j ] = tmpAmbient[ j ] * ( 1 .0f / 255 .0f );
3504
3522
directedColor[ j ] = tmpDirected[ j ] * ( 1 .0f / 255 .0f );
3523
+
3524
+ if ( tr.worldLinearizeLightMap )
3525
+ {
3526
+ ambientColor[ j ] = convertFromSRGB ( ambientColor[ j ] );
3527
+ directedColor[ j ] = convertFromSRGB ( directedColor[ j ] );
3528
+ }
3505
3529
}
3506
3530
3507
3531
const float forceAmbient = r_forceAmbient.Get ();
@@ -3766,6 +3790,75 @@ void R_LoadEntities( lump_t *l, std::string &externalEntities )
3766
3790
tr.worldDeluxeMapping = glConfig2.deluxeMapping ;
3767
3791
}
3768
3792
3793
+ bool sRGBtex = false ;
3794
+ bool sRGBcolor = false ;
3795
+ bool sRGBlight = false ;
3796
+
3797
+ s = strstr ( value, " -sRGB" );
3798
+
3799
+ if ( s && ( s[5 ] == ' ' || s[5 ] == ' \0 ' ) )
3800
+ {
3801
+ sRGBtex = true ;
3802
+ sRGBcolor = true ;
3803
+ sRGBlight = true ;
3804
+ }
3805
+
3806
+ s = strstr ( value, " -nosRGB" );
3807
+
3808
+ if ( s && ( s[5 ] == ' ' || s[5 ] == ' \0 ' ) )
3809
+ {
3810
+ sRGBtex = false ;
3811
+ sRGBcolor = false ;
3812
+ sRGBlight = false ;
3813
+ }
3814
+
3815
+ if ( strstr ( value, " -sRGBlight" ) )
3816
+ {
3817
+ sRGBlight = true ;
3818
+ }
3819
+
3820
+ if ( strstr ( value, " -nosRGBlight" ) )
3821
+ {
3822
+ sRGBlight = false ;
3823
+ }
3824
+
3825
+ if ( strstr ( value, " -sRGBcolor" ) )
3826
+ {
3827
+ sRGBcolor = true ;
3828
+ }
3829
+
3830
+ if ( strstr ( value, " -nosRGBcolor" ) )
3831
+ {
3832
+ sRGBcolor = false ;
3833
+ }
3834
+
3835
+ if ( strstr ( value, " -sRGBtex" ) )
3836
+ {
3837
+ sRGBtex = true ;
3838
+ }
3839
+
3840
+ if ( strstr ( value, " -nosRGBtex" ) )
3841
+ {
3842
+ sRGBtex = false ;
3843
+ }
3844
+
3845
+ if ( sRGBlight )
3846
+ {
3847
+ Log::Debug ( " Map features lights in sRGB colorspace." );
3848
+ tr.worldLinearizeLightMap = true ;
3849
+ }
3850
+
3851
+ if ( sRGBcolor && sRGBtex )
3852
+ {
3853
+ Log::Debug ( " Map features lights computed with linear colors and textures." );
3854
+ tr.worldLinearizeTexture = true ;
3855
+ }
3856
+ else if ( sRGBcolor != sRGBtex )
3857
+ {
3858
+ Log::Warn ( " Map features lights computed with a mix of linear and non-linear colors or textures, acting like both colors and textures were linear when lights were computed." );
3859
+ tr.worldLinearizeTexture = true ;
3860
+ }
3861
+
3769
3862
continue ;
3770
3863
}
3771
3864
@@ -4517,6 +4610,8 @@ void RE_LoadWorldMap( const char *name )
4517
4610
tr.overbrightBits = std::min ( tr.mapOverBrightBits , r_overbrightBits.Get () ); // set by RE_LoadWorldMap
4518
4611
tr.mapLightFactor = 1 .0f ; // set by RE_LoadWorldMap
4519
4612
tr.identityLight = 1 .0f ; // set by RE_LoadWorldMap
4613
+ tr.worldLinearizeTexture = false ;
4614
+ tr.worldLinearizeLightMap = false ;
4520
4615
4521
4616
s_worldData = {};
4522
4617
Q_strncpyz ( s_worldData.name , name, sizeof ( s_worldData.name ) );
0 commit comments