Fixed all known problems with sRGB -> linear RGB conversions (fog, GUIs, screen effects)

This commit is contained in:
Robert Beckebans 2020-05-15 16:25:36 +02:00
parent 5b56ab3392
commit 71d768cceb
11 changed files with 249 additions and 117 deletions

View file

@ -408,8 +408,8 @@ convertMapToJSON <mapfile> | Command: Convert .map file to new .json
* Some shadows might almost disappear due to the shadow filtering
* [HDR] HDR does not work with old-school stencil shadows
* [HDR] MSAA anti-aliasing modes don't work with HDR: Use SMAA
* [HDR] HDR causes problems with the grabber gun
* [HDR] HDR darkens the screen when you get hit by an enemy
* ~~[HDR] HDR causes problems with the grabber gun~~
* ~~[HDR] HDR darkens the screen when you get hit by an enemy~~
* [Vulkan] Shadow Mapping is not supported yet
* [Vulkan] HDR is not supported yet
* [Vulkan] Post processing and SMAA is not supported yet

View file

@ -51,7 +51,11 @@ The main goal is that the new content looks the same in RBDOOM-3-BFG as in Blend
* Added HACK to look for PBR reflection maps with the suffix _rmao if a specular map was specified and ends with _s.tga. This allows to override the materials with PBR textures without touching the material .mtr files.
* Fixed ambient lights being too bright in HDR mode
* Fixed ambient lights, 3D GUIs and fog being too bright in HDR mode
* Fixed darkening of the screen in HDR mode when you get hit by an enemy
* Fixed ellipse bug when using Grabber gun in HDR mode #407
[VULKAN]
@ -77,7 +81,7 @@ The main goal is that the new content looks the same in RBDOOM-3-BFG as in Blend
* Added Blue Noise based Filmic Dithering by Timothy Lottes and Chromatic Aberration
* Added Contrast Adaptive Sharpening (AMD) from Just Marshal (IcedTech)
* Added Contrast Adaptive Sharpening (AMD) by Justin Marshal (IcedTech)
* Improved Shadow Mapping quality with Vogel Disk Sampling by Panos Karabelas and using dithering the result with Blue Noise magic by Alan Wolfe

View file

@ -4,6 +4,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
@ -45,5 +46,13 @@ struct PS_OUT {
void main( PS_IN fragment, out PS_OUT result )
{
result.color = sRGBAToLinearRGBA( idtex2Dproj( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * rpColor );
float4 c = idtex2Dproj( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * rpColor;
#if defined( USE_LINEAR_RGB )
c = clamp( c, 0.0, 1.0 );
c = float4( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ), Linear1( c.a ) );
#endif
result.color = c;
}

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2020 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -45,6 +46,14 @@ struct PS_OUT {
void main( PS_IN fragment, out PS_OUT result )
{
result.color = sRGBAToLinearRGBA( tex2D( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * rpColor );
float4 c = tex2D( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * rpColor;
#if defined( USE_LINEAR_RGB )
c = clamp( c, 0.0, 1.0 );
c = float4( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ), Linear1( c.a ) );
#endif
result.color = c;
}

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2020 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -45,6 +46,14 @@ struct PS_OUT {
void main( PS_IN fragment, out PS_OUT result )
{
result.color = tex2D( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * sRGBAToLinearRGBA( rpColor );
float4 c = tex2D( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * rpColor;
#if defined( USE_LINEAR_RGB )
c = clamp( c, 0.0, 1.0 );
c = float4( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ), Linear1( c.a ) );
#endif
result.color = c;
}

View file

@ -130,48 +130,11 @@ static float dot4( float2 a, float4 b ) { return dot( float4( a, 0, 1 ), b ); }
#define DEG2RAD( a ) ( ( a ) * PI / 180.0f )
#define RAD2DEG( a ) ( ( a ) * 180.0f / PI )
// ----------------------
// sRGB <-> Linear RGB Color Conversion
// ----------------------
half3 sRGBToLinearRGB( half3 rgb )
{
#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )
return max( pow( rgb, half3( 2.2 ) ), half3( 0.0 ) );
#else
return rgb;
#endif
}
half4 sRGBAToLinearRGBA( half4 rgba )
{
#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )
return float4( max( pow( rgba.rgb, half3( 2.2 ) ), half3( 0.0 ) ), rgba.a );
#else
return rgba;
#endif
}
half3 LinearRGBToSRGB( half3 rgb )
{
#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )
return pow( rgb, half3( 1.0 ) / half3( 2.2 ) );
#else
return rgb;
#endif
}
half4 LinearRGBToSRGB( half4 rgba )
{
#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )
rgba.rgb = pow( rgba.rgb, half3( 1.0 ) / half3( 2.2 ) );
return rgba; //pow( rgba, half4( 1.0 ) / half4( 2.2 ) );
#else
return rgba;
#endif
}
float Linear1( float c )
{
return ( c <= 0.04045 ) ? c / 12.92 : pow( ( c + 0.055 ) / 1.055, 2.4 );
@ -198,6 +161,53 @@ float PhotoLuma( float3 c )
return dot( c, photoLuma );
}
float3 sRGBToLinearRGB( float3 c )
{
#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )
c = clamp( c, 0.0, 1.0 );
return Linear3( c );
#else
return c;
#endif
}
float4 sRGBAToLinearRGBA( float4 c )
{
#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )
c = clamp( c, 0.0, 1.0 );
return float4( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ), Linear1( c.a ) );
#else
return c;
#endif
}
float3 LinearRGBToSRGB( float3 c )
{
#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )
c = clamp( c, 0.0, 1.0 );
return Srgb3( c );
#else
return c;
#endif
}
float4 LinearRGBToSRGB( float4 c )
{
#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )
c = clamp( c, 0.0, 1.0 );
return float4( Srgb1( c.r ), Srgb1( c.g ), Srgb1( c.b ), c.a );
#else
return c;
#endif
}
// RB end
// ----------------------

View file

@ -132,7 +132,7 @@ struct globalFramebuffers_t
Framebuffer* bloomRenderFBO[MAX_BLOOM_BUFFERS];
Framebuffer* ambientOcclusionFBO[MAX_SSAO_BUFFERS];
Framebuffer* csDepthFBO[MAX_HIERARCHICAL_ZBUFFERS];
// Framebuffer* geometryBufferFBO;
Framebuffer* geometryBufferFBO;
Framebuffer* smaaEdgesFBO;
Framebuffer* smaaBlendFBO;
};

View file

@ -267,6 +267,11 @@ static void R_SMAAImage_ResNative( idImage* image )
image->GenerateImage( NULL, renderSystem->GetWidth(), renderSystem->GetHeight(), TF_LINEAR, TR_CLAMP, TD_LOOKUP_TABLE_RGBA );
}
static void R_GeometryBufferImage_ResNative( idImage* image )
{
image->GenerateImage( NULL, renderSystem->GetWidth(), renderSystem->GetHeight(), TF_LINEAR, TR_CLAMP, TD_RGBA16F );
}
static void R_SSAOImage_ResHalf( idImage* image )
{
image->GenerateImage( NULL, renderSystem->GetWidth() / 2, renderSystem->GetHeight() / 2, TF_LINEAR, TR_CLAMP, TD_LOOKUP_TABLE_RGBA );
@ -1007,7 +1012,7 @@ void idImageManager::CreateIntrinsicImages()
smaaEdgesImage = globalImages->ImageFromFunction( "_smaaEdges", R_SMAAImage_ResNative );
smaaBlendImage = globalImages->ImageFromFunction( "_smaaBlend", R_SMAAImage_ResNative );
currentNormalsImage = ImageFromFunction( "_currentNormals", R_SMAAImage_ResNative );
currentNormalsImage = ImageFromFunction( "_currentNormals", R_GeometryBufferImage_ResNative );
ambientOcclusionImage[0] = ImageFromFunction( "_ao0", R_SMAAImage_ResNative );
ambientOcclusionImage[1] = ImageFromFunction( "_ao1", R_SMAAImage_ResNative );

View file

@ -2,7 +2,7 @@
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 2014-2018 Robert Beckebans
Copyright (C) 2014-2020 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -178,11 +178,17 @@ void Framebuffer::Init()
// GEOMETRY BUFFER
//globalFramebuffers.geometryBufferFBO = new Framebuffer( "_gbuffer", screenWidth, screenHeight );
//globalFramebuffers.geometryBufferFBO->Bind();
//globalFramebuffers.geometryBufferFBO->AddColorBuffer( GL_RGBA8, 0 );
//globalFramebuffers.geometryBufferFBO->AttachImage2D( GL_TEXTURE_2D, globalImages->currentNormalsImage, 0 );
//globalFramebuffers.geometryBufferFBO->Check();
globalFramebuffers.geometryBufferFBO = new Framebuffer( "_gbuffer", screenWidth, screenHeight );
globalFramebuffers.geometryBufferFBO->Bind();
globalFramebuffers.geometryBufferFBO->AddColorBuffer( GL_RGBA16F, 0 );
globalFramebuffers.geometryBufferFBO->AddDepthBuffer( GL_DEPTH24_STENCIL8 );
// it is ideal to share the depth buffer between the HDR main context and the geometry render target
globalFramebuffers.geometryBufferFBO->AttachImage2D( GL_TEXTURE_2D, globalImages->currentNormalsImage, 0 );
globalFramebuffers.geometryBufferFBO->AttachImageDepth( GL_TEXTURE_2D, globalImages->currentDepthImage );
globalFramebuffers.geometryBufferFBO->Check();
// SMAA
@ -296,14 +302,15 @@ void Framebuffer::CheckFramebuffers()
// GEOMETRY BUFFER
//globalImages->currentNormalsImage->Resize( screenWidth, screenHeight );
globalImages->currentNormalsImage->Resize( screenWidth, screenHeight );
//globalFramebuffers.geometryBufferFBO->width = screenWidth;
//globalFramebuffers.geometryBufferFBO->height = screenHeight;
globalFramebuffers.geometryBufferFBO->width = screenWidth;
globalFramebuffers.geometryBufferFBO->height = screenHeight;
//globalFramebuffers.geometryBufferFBO->Bind();
//globalFramebuffers.geometryBufferFBO->AttachImage2D( GL_TEXTURE_2D, globalImages->currentNormalsImage, 0 );
//globalFramebuffers.geometryBufferFBO->Check();
globalFramebuffers.geometryBufferFBO->Bind();
globalFramebuffers.geometryBufferFBO->AttachImage2D( GL_TEXTURE_2D, globalImages->currentNormalsImage, 0 );
globalFramebuffers.geometryBufferFBO->AttachImageDepth( GL_TEXTURE_2D, globalImages->currentDepthImage );
globalFramebuffers.geometryBufferFBO->Check();
// SMAA

View file

@ -2068,11 +2068,13 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
return;
}
/*
if( !fillGbuffer )
{
// clear gbuffer
GL_Clear( true, false, false, 0, 0.0f, 0.0f, 0.0f, 1.0f, false );
}
*/
if( !fillGbuffer && r_useSSAO.GetBool() && r_ssaoDebug.GetBool() )
{
@ -2109,19 +2111,15 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
return;
}
renderLog.OpenMainBlock( MRB_AMBIENT_PASS );
renderLog.OpenBlock( "Render_AmbientPass", colorBlue );
/*
if( fillGbuffer )
{
globalFramebuffers.geometryBufferFBO->Bind();
glClearColor( 0, 0, 0, 0 );
glClear( GL_COLOR_BUFFER_BIT );
GL_Clear( true, false, false, 0, 0.0f, 0.0f, 0.0f, 1.0f, false );
}
*/
renderLog.OpenMainBlock( MRB_AMBIENT_PASS );
renderLog.OpenBlock( "Render_AmbientPass", colorBlue );
// RB: not needed
// GL_StartDepthPass( backEnd.viewDef->scissor );
@ -2133,8 +2131,12 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
// with the general purpose path
GL_State( GLS_DEFAULT );
#define BLEND_NORMALS 1
// RB: even use additive blending to blend the normals
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
//GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
GL_Color( colorWhite );
@ -2390,6 +2392,18 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
// draw any previous interaction
if( inter.bumpImage != NULL )
{
#if BLEND_NORMALS
if( inter.vertexColor == SVC_IGNORE )
{
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
}
else
{
// RB: this is a bit hacky: use additive blending to blend the normals
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
}
#endif
DrawSingleInteraction( &inter, false, useIBL, false );
}
inter.bumpImage = surfaceStage->texture.image;
@ -2411,6 +2425,18 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
// draw any previous interaction
if( inter.diffuseImage != NULL )
{
#if BLEND_NORMALS
if( inter.vertexColor == SVC_IGNORE )
{
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
}
else
{
// RB: this is a bit hacky: use additive blending to blend the normals
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
}
#endif
DrawSingleInteraction( &inter, false, useIBL, false );
}
@ -2431,6 +2457,18 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
// draw any previous interaction
if( inter.specularImage != NULL )
{
#if BLEND_NORMALS
if( inter.vertexColor == SVC_IGNORE )
{
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
}
else
{
// RB: this is a bit hacky: use additive blending to blend the normals
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
}
#endif
DrawSingleInteraction( &inter, false, useIBL, false );
}
inter.specularImage = surfaceStage->texture.image;
@ -2443,6 +2481,18 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
}
// draw the final interaction
#if BLEND_NORMALS
if( inter.vertexColor == SVC_IGNORE )
{
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
}
else
{
// RB: this is a bit hacky: use additive blending to blend the normals
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
}
#endif
DrawSingleInteraction( &inter, false, useIBL, false );
renderLog.CloseBlock();
@ -2456,14 +2506,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
if( fillGbuffer )
{
// FIXME: this copies RGBA16F into _currentNormals if HDR is enabled
const idScreenRect& viewport = viewDef->viewport;
globalImages->currentNormalsImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() );
//GL_Clear( true, false, false, STENCIL_SHADOW_TEST_VALUE, 0.0f, 0.0f, 0.0f, 1.0f, false );
/*
// go back to main render target
if( hdrIsActive )
{
globalFramebuffers.hdrFBO->Bind();
@ -2472,7 +2515,6 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
{
Framebuffer::Unbind();
}
*/
}
renderProgManager.Unbind();

View file

@ -144,48 +144,11 @@ static const cgShaderDef_t cg_renderprogs[] =
"#define DEG2RAD( a ) ( ( a ) * PI / 180.0f )\n"
"#define RAD2DEG( a ) ( ( a ) * 180.0f / PI )\n"
"\n"
"\n"
"// ----------------------\n"
"// sRGB <-> Linear RGB Color Conversion\n"
"// ----------------------\n"
"\n"
"half3 sRGBToLinearRGB( half3 rgb )\n"
"{\n"
"#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )\n"
" return max( pow( rgb, half3( 2.2 ) ), half3( 0.0 ) );\n"
"#else\n"
" return rgb;\n"
"#endif\n"
"}\n"
"\n"
"half4 sRGBAToLinearRGBA( half4 rgba )\n"
"{\n"
"#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )\n"
" return float4( max( pow( rgba.rgb, half3( 2.2 ) ), half3( 0.0 ) ), rgba.a );\n"
"#else\n"
" return rgba;\n"
"#endif\n"
"}\n"
"\n"
"half3 LinearRGBToSRGB( half3 rgb )\n"
"{\n"
"#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )\n"
" return pow( rgb, half3( 1.0 ) / half3( 2.2 ) );\n"
"#else\n"
" return rgb;\n"
"#endif\n"
"}\n"
"\n"
"half4 LinearRGBToSRGB( half4 rgba )\n"
"{\n"
"#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )\n"
" rgba.rgb = pow( rgba.rgb, half3( 1.0 ) / half3( 2.2 ) );\n"
" return rgba; //pow( rgba, half4( 1.0 ) / half4( 2.2 ) );\n"
"#else\n"
" return rgba;\n"
"#endif\n"
"}\n"
"\n"
"\n"
"float Linear1( float c )\n"
"{\n"
" return ( c <= 0.04045 ) ? c / 12.92 : pow( ( c + 0.055 ) / 1.055, 2.4 );\n"
@ -212,6 +175,53 @@ static const cgShaderDef_t cg_renderprogs[] =
" return dot( c, photoLuma );\n"
"}\n"
"\n"
"float3 sRGBToLinearRGB( float3 c )\n"
"{\n"
"#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )\n"
" c = clamp( c, 0.0, 1.0 );\n"
"\n"
" return Linear3( c );\n"
"#else\n"
" return c;\n"
"#endif\n"
"}\n"
"\n"
"float4 sRGBAToLinearRGBA( float4 c )\n"
"{\n"
"#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )\n"
" c = clamp( c, 0.0, 1.0 );\n"
"\n"
" return float4( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ), Linear1( c.a ) );\n"
"#else\n"
" return c;\n"
"#endif\n"
"}\n"
"\n"
"float3 LinearRGBToSRGB( float3 c )\n"
"{\n"
"#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )\n"
" c = clamp( c, 0.0, 1.0 );\n"
"\n"
" return Srgb3( c );\n"
"#else\n"
" return c;\n"
"#endif\n"
"}\n"
"\n"
"float4 LinearRGBToSRGB( float4 c )\n"
"{\n"
"#if defined( USE_LINEAR_RGB ) && !defined( USE_SRGB )\n"
" c = clamp( c, 0.0, 1.0 );\n"
"\n"
" return float4( Srgb1( c.r ), Srgb1( c.g ), Srgb1( c.b ), c.a );\n"
"#else\n"
" return c;\n"
"#endif\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"// RB end\n"
"\n"
"// ----------------------\n"
@ -4226,6 +4236,7 @@ static const cgShaderDef_t cg_renderprogs[] =
"Doom 3 BFG Edition GPL Source Code\n"
"Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.\n"
"\n"
"\n"
"This file is part of the Doom 3 BFG Edition GPL Source Code (\"Doom 3 BFG Edition Source Code\").\n"
"\n"
"Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify\n"
@ -4267,7 +4278,15 @@ static const cgShaderDef_t cg_renderprogs[] =
"\n"
"void main( PS_IN fragment, out PS_OUT result )\n"
"{\n"
" result.color = sRGBAToLinearRGBA( idtex2Dproj( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * rpColor );\n"
" float4 c = idtex2Dproj( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * rpColor;\n"
"\n"
"#if defined( USE_LINEAR_RGB )\n"
" c = clamp( c, 0.0, 1.0 );\n"
"\n"
" c = float4( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ), Linear1( c.a ) );\n"
"#endif\n"
"\n"
" result.color = c;\n"
"}\n"
"\n"
@ -7456,6 +7475,7 @@ static const cgShaderDef_t cg_renderprogs[] =
"\n"
"Doom 3 BFG Edition GPL Source Code\n"
"Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.\n"
"Copyright (C) 2020 Robert Beckebans\n"
"\n"
"This file is part of the Doom 3 BFG Edition GPL Source Code (\"Doom 3 BFG Edition Source Code\").\n"
"\n"
@ -7498,7 +7518,15 @@ static const cgShaderDef_t cg_renderprogs[] =
"\n"
"void main( PS_IN fragment, out PS_OUT result )\n"
"{\n"
" result.color = sRGBAToLinearRGBA( tex2D( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * rpColor );\n"
" float4 c = tex2D( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * rpColor;\n"
"\n"
"#if defined( USE_LINEAR_RGB )\n"
" c = clamp( c, 0.0, 1.0 );\n"
"\n"
" c = float4( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ), Linear1( c.a ) );\n"
"#endif\n"
"\n"
" result.color = c;\n"
"}\n"
"\n"
"\n"
@ -7577,6 +7605,7 @@ static const cgShaderDef_t cg_renderprogs[] =
"\n"
"Doom 3 BFG Edition GPL Source Code\n"
"Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.\n"
"Copyright (C) 2020 Robert Beckebans\n"
"\n"
"This file is part of the Doom 3 BFG Edition GPL Source Code (\"Doom 3 BFG Edition Source Code\").\n"
"\n"
@ -7619,7 +7648,15 @@ static const cgShaderDef_t cg_renderprogs[] =
"\n"
"void main( PS_IN fragment, out PS_OUT result )\n"
"{\n"
" result.color = tex2D( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * sRGBAToLinearRGBA( rpColor );\n"
" float4 c = tex2D( samp0, fragment.texcoord0 ) * tex2D( samp1, fragment.texcoord1 ) * rpColor;\n"
"\n"
"#if defined( USE_LINEAR_RGB )\n"
" c = clamp( c, 0.0, 1.0 );\n"
"\n"
" c = float4( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ), Linear1( c.a ) );\n"
"#endif\n"
"\n"
" result.color = c;\n"
"}\n"
"\n"
"\n"