Skip to content

renderer: implement mapOverBrightBits in GLSL #1035

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

Closed
wants to merge 1 commit into from
Closed
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
2 changes: 2 additions & 0 deletions src/engine/renderer/gl_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1573,6 +1573,7 @@ void GLShader_generic2D::SetShaderProgramUniforms( shaderProgram_t *shaderProgra

GLShader_generic::GLShader_generic( GLShaderManager *manager ) :
GLShader( "generic", ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT, manager ),
u_MapOverBrightBitsShift( this ),
u_TextureMatrix( this ),
u_ViewOrigin( this ),
u_ViewUp( this ),
Expand Down Expand Up @@ -1610,6 +1611,7 @@ void GLShader_generic::SetShaderProgramUniforms( shaderProgram_t *shaderProgram
GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) :
GLShader( "lightMapping",
ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_COLOR, manager ),
u_MapOverBrightBitsShift( this ),
u_TextureMatrix( this ),
u_SpecularExponent( this ),
u_ColorModulate( this ),
Expand Down
17 changes: 17 additions & 0 deletions src/engine/renderer/gl_shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,21 @@ class GLCompileMacro_USE_ALPHA_TESTING :
}
};

class u_MapOverBrightBitsShift :
GLUniform1i
{
public:
u_MapOverBrightBitsShift( GLShader *shader ) :
GLUniform1i( shader, "u_MapOverBrightBitsShift" )
{
}

void SetUniform_MapOverBrightBitsShift( int mapOverBrightBitsShift )
{
this->SetValue( mapOverBrightBitsShift );
}
};

class u_TextureMatrix :
GLUniformMatrix4f
{
Expand Down Expand Up @@ -2238,6 +2253,7 @@ class GLShader_generic2D :

class GLShader_generic :
public GLShader,
public u_MapOverBrightBitsShift,
public u_TextureMatrix,
public u_ViewOrigin,
public u_ViewUp,
Expand Down Expand Up @@ -2267,6 +2283,7 @@ class GLShader_generic :

class GLShader_lightMapping :
public GLShader,
public u_MapOverBrightBitsShift,
public u_TextureMatrix,
public u_SpecularExponent,
public u_ColorModulate,
Expand Down
23 changes: 23 additions & 0 deletions src/engine/renderer/glsl_source/generic_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,26 @@ IN(smooth) vec2 var_FadeDepth;
uniform sampler2D u_DepthMap;
#endif

#if !defined(GENERIC_2D) && defined(USE_TCGEN_LIGHTMAP)
uniform int u_MapOverBrightBitsShift;
#endif

DECLARE_OUTPUT(vec4)

void mapOverBrightBits(inout vec3 color, in float shift)
{
if (shift > 1)
{
color *= shift;
float maxComponent = 1.0;
maxComponent = max(maxComponent, color.r);
maxComponent = max(maxComponent, color.g);
maxComponent = max(maxComponent, color.b);
maxComponent = 1.0 / maxComponent;
color *= maxComponent;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was actually repoducing a bug (light being clamped and then wrong)…

}
}

void main()
{
vec4 color = texture2D(u_ColorMap, var_TexCoords);
Expand All @@ -53,7 +71,12 @@ void main()
color.a *= smoothstep(gl_FragCoord.z, fadeDepth, depth);
#endif

#if !defined(GENERIC_2D) && defined(USE_TCGEN_LIGHTMAP)
mapOverBrightBits(color.rgb, u_MapOverBrightBitsShift);
#endif

color *= var_Color;

outputColor = color;

#if defined(GENERIC_2D)
Expand Down
20 changes: 20 additions & 0 deletions src/engine/renderer/glsl_source/lightMapping_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,24 @@ IN(smooth) vec3 var_Normal;
uniform vec3 u_LightGridScale;
#endif

uniform int u_MapOverBrightBitsShift;

DECLARE_OUTPUT(vec4)

void mapOverBrightBits(inout vec3 color, in float shift)
{
if (shift > 1)
{
color *= shift;
float maxComponent = 1.0;
maxComponent = max(maxComponent, color.r);
maxComponent = max(maxComponent, color.g);
maxComponent = max(maxComponent, color.b);
maxComponent = 1.0 / maxComponent;
color *= maxComponent;
}
}

void main()
{
// Compute view direction in world space.
Expand Down Expand Up @@ -124,6 +140,8 @@ void main()
vec3 ambientColor, lightColor;
ReadLightGrid(texture3D(u_LightGrid1, lightGridPos), ambientColor, lightColor);

mapOverBrightBits(ambientColor.rgb, u_MapOverBrightBitsShift);

color.rgb = ambientColor * r_AmbientScale * diffuse.rgb;
#endif

Expand Down Expand Up @@ -153,6 +171,8 @@ void main()
lightColor /= clamp(dot(normalize(var_Normal), lightDir), 0.3, 1.0);
#endif

mapOverBrightBits(lightColor.rgb, u_MapOverBrightBitsShift);

// Blend static light.
#if defined(USE_DELUXE_MAPPING) || defined(USE_GRID_DELUXE_MAPPING)
computeDeluxeLight(lightDir, normal, viewDir, lightColor, diffuse, material, color);
Expand Down
125 changes: 7 additions & 118 deletions src/engine/renderer/tr_bsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,118 +46,6 @@ static int c_vboShadowSurfaces;

//===============================================================================

/*
===============
R_ColorShiftLightingBytes
===============
*/
static void R_ColorShiftLightingBytes( byte in[ 4 ], byte out[ 4 ] )
{
int shift, r, g, b;

/* Shift the color data based on overbright range.

Historically the shift was:

shift = tr.mapOverBrightBits - tr.overbrightBits;

But in Dæmon engine tr.overbrightBits is always zero
as this value is zero when there hardware overbright
bit is disabled, and the engine doesn't implement
hardware overbright bit at all.

The original code was there to only shift in software
what hardware overbright bit feature was not doing, but
this implementation is entirely software. */
shift = tr.mapOverBrightBits;

// shift the data based on overbright range
r = in[ 0 ] << shift;
g = in[ 1 ] << shift;
b = in[ 2 ] << shift;

// normalize by color instead of saturating to white
if ( ( r | g | b ) > 255 )
{
int max;

max = r > g ? r : g;
max = max > b ? max : b;
r = r * 255 / max;
g = g * 255 / max;
b = b * 255 / max;
}

out[ 0 ] = r;
out[ 1 ] = g;
out[ 2 ] = b;
out[ 3 ] = in[ 3 ];
}

static void R_ColorShiftLightingBytesCompressed( byte in[ 8 ], byte out[ 8 ] )
{
unsigned short rgb565;
byte rgba[4];

// color shift the endpoint colors in the dxt block
rgb565 = in[1] << 8 | in[0];
rgba[0] = (rgb565 >> 8) & 0xf8;
rgba[1] = (rgb565 >> 3) & 0xfc;
rgba[2] = (rgb565 << 3) & 0xf8;
rgba[3] = 0xff;
R_ColorShiftLightingBytes( rgba, rgba );
rgb565 = ((rgba[0] >> 3) << 11) |
((rgba[1] >> 2) << 5) |
((rgba[2] >> 3) << 0);
out[0] = rgb565 & 0xff;
out[1] = rgb565 >> 8;

rgb565 = in[3] << 8 | in[2];
rgba[0] = (rgb565 >> 8) & 0xf8;
rgba[1] = (rgb565 >> 3) & 0xfc;
rgba[2] = (rgb565 << 3) & 0xf8;
rgba[3] = 0xff;
R_ColorShiftLightingBytes( rgba, rgba );
rgb565 = ((rgba[0] >> 3) << 11) |
((rgba[1] >> 2) << 5) |
((rgba[2] >> 3) << 0);
out[2] = rgb565 & 0xff;
out[3] = rgb565 >> 8;
}

/*
===============
R_ProcessLightmap

returns maxIntensity
===============
*/
float R_ProcessLightmap( byte *pic, int in_padding, int width, int height, int bits, byte *pic_out )
{
int j;
float maxIntensity = 0;

if( bits & IF_BC1 ) {
for ( j = 0; j < ((width + 3) >> 2) * ((height + 3) >> 2); j++ )
{
R_ColorShiftLightingBytesCompressed( &pic[ j * 8 ], &pic_out[ j * 8 ] );
}
} else if( bits & (IF_BC2 | IF_BC3) ) {
for ( j = 0; j < ((width + 3) >> 2) * ((height + 3) >> 2); j++ )
{
R_ColorShiftLightingBytesCompressed( &pic[ j * 16 ], &pic_out[ j * 16 ] );
}
} else {
for ( j = 0; j < width * height; j++ )
{
R_ColorShiftLightingBytes( &pic[ j * in_padding ], &pic_out[ j * 4 ] );
pic_out[ j * 4 + 3 ] = 255;
}
}

return maxIntensity;
}

static int LightmapNameCompare( const char *s1, const char *s2 )
{
int c1, c2;
Expand Down Expand Up @@ -640,7 +528,7 @@ static void R_LoadLightmaps( lump_t *l, const char *bspName )
lightMapBuffer[( index * 4 ) + 2 ] = buf_p[( ( x + ( y * internalLightMapSize ) ) * 3 ) + 2 ];
lightMapBuffer[( index * 4 ) + 3 ] = 255;

R_ColorShiftLightingBytes( &lightMapBuffer[( index * 4 ) + 0 ], &lightMapBuffer[( index * 4 ) + 0 ] );
// Color shift for overbright bits is now done in GLSL.
}
}

Expand Down Expand Up @@ -925,7 +813,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf, in
cv->verts[ i ].lightColor = Color::Adapt( verts[ i ].color );


R_ColorShiftLightingBytes( cv->verts[ i ].lightColor.ToArray(), cv->verts[ i ].lightColor.ToArray() );
// Color shift for overbright bits is now done in GLSL.
}

// copy triangles
Expand Down Expand Up @@ -1132,7 +1020,7 @@ static void ParseMesh( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf )

points[ i ].lightColor = Color::Adapt( verts[ i ].color );

R_ColorShiftLightingBytes( points[ i ].lightColor.ToArray(), points[ i ].lightColor.ToArray() );
// Color shift for overbright bits is now done in GLSL.
}

// center texture coords
Expand Down Expand Up @@ -1256,7 +1144,7 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf,

cv->verts[ i ].lightColor = Color::Adapt( verts[ i ].color );

R_ColorShiftLightingBytes( cv->verts[ i ].lightColor.ToArray(), cv->verts[ i ].lightColor.ToArray() );
// Color shift for overbright bits is now done in GLSL.
}

// copy triangles
Expand Down Expand Up @@ -4044,8 +3932,7 @@ void R_LoadLightGrid( lump_t *l )
tmpDirected[ 2 ] = in->directed[ 2 ];
tmpDirected[ 3 ] = 255;

R_ColorShiftLightingBytes( tmpAmbient, tmpAmbient );
R_ColorShiftLightingBytes( tmpDirected, tmpDirected );
// Color shift for overbright bits is now done in GLSL.

for ( j = 0; j < 3; j++ )
{
Expand Down Expand Up @@ -6922,4 +6809,6 @@ void RE_LoadWorldMap( const char *name )
}
}
}

tr.mapOverBrightBitsShift = pow(2, tr.mapOverBrightBits);
}
5 changes: 1 addition & 4 deletions src/engine/renderer/tr_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1798,10 +1798,7 @@ image_t *R_FindImageFile( const char *imageName, imageParams_t &imageParams )
return nullptr;
}

if ( imageParams.bits & IF_LIGHTMAP )
{
R_ProcessLightmap( pic[ 0 ], 4, width, height, imageParams.bits, pic[ 0 ] );
}
// Color shift for overbright bits is now done in GLSL.

image = R_CreateImage( ( char * ) buffer, (const byte **)pic, width, height, numMips, imageParams );

Expand Down
4 changes: 2 additions & 2 deletions src/engine/renderer/tr_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -2822,7 +2822,8 @@ enum class deluxeMode_t { NONE, GRID, MAP };

viewParms_t viewParms;

int mapOverBrightBits; // r_mapOverbrightBits->integer, but can be overridden by mapper using the worldspawn
int mapOverBrightBits; // r_mapOverbrightBits->integer, but can be overridden by mapper using the worldspawn
int mapOverBrightBitsShift; // pow(2, mapOverbrightBits)

orientationr_t orientation; // for current entity

Expand Down Expand Up @@ -3305,7 +3306,6 @@ inline bool checkGLErrors()
void RE_Shutdown( bool destroyWindow );

bool R_GetEntityToken( char *buffer, int size );
float R_ProcessLightmap( byte *pic, int in_padding, int width, int height, int bits, byte *pic_out ); // Arnout

model_t *R_AllocModel();

Expand Down
13 changes: 13 additions & 0 deletions src/engine/renderer/tr_shade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,12 @@ static void Render_generic( shaderStage_t *pStage )
gl_genericShader->SetUniform_AlphaTest(pStage->stateBits);
}

// u_MapOverBrightBitsShift
if ( pStage->tcGen_Lightmap )
{
gl_genericShader->SetUniform_MapOverBrightBitsShift( tr.mapOverBrightBitsShift );
}

// u_ColorGen
switch ( pStage->rgbGen )
{
Expand Down Expand Up @@ -895,6 +901,7 @@ static void Render_lightMapping( shaderStage_t *pStage )

lightMode_t lightMode = lightMode_t::FULLBRIGHT;
deluxeMode_t deluxeMode = deluxeMode_t::NONE;
int mapOverBrightBitsShift = 1;

/* TODO: investigate what this is. It's probably a hack to detect some
specific use case. Without knowing which use case this takes care about,
Expand Down Expand Up @@ -949,6 +956,7 @@ static void Render_lightMapping( shaderStage_t *pStage )
switch ( lightMode )
{
case lightMode_t::VERTEX:
mapOverBrightBitsShift = tr.mapOverBrightBitsShift;
// Do not rewrite pStage->rgbGen.
colorGen = colorGen_t::CGEN_VERTEX;
tess.svars.color.SetRed( 0.0f );
Expand All @@ -957,12 +965,14 @@ static void Render_lightMapping( shaderStage_t *pStage )
break;

case lightMode_t::GRID:
mapOverBrightBitsShift = tr.mapOverBrightBitsShift;
// Store lightGrid1 as lightmap,
// the GLSL code will know how to deal with it.
lightmap = tr.lightGrid1Image;
break;

case lightMode_t::MAP:
mapOverBrightBitsShift = tr.mapOverBrightBitsShift;
lightmap = GetLightMap();

if ( r_showLightMaps->integer )
Expand Down Expand Up @@ -1085,6 +1095,9 @@ static void Render_lightMapping( shaderStage_t *pStage )
// u_AlphaTest
gl_lightMappingShader->SetUniform_AlphaTest( pStage->stateBits );

// u_MapOverBrightBitsShift
gl_lightMappingShader->SetUniform_MapOverBrightBitsShift( mapOverBrightBitsShift );

// bind u_HeightMap
if ( pStage->enableReliefMapping )
{
Expand Down
Loading