From 71d768cceb9ae382ca53e4be322ec26f1443f65e Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Fri, 15 May 2020 16:25:36 +0200 Subject: [PATCH] Fixed all known problems with sRGB -> linear RGB conversions (fog, GUIs, screen effects) --- README.md | 4 +- RELEASE-NOTES.md | 8 +- base/renderprogs/blendLight.ps.hlsl | 11 ++- base/renderprogs/fog.ps.hlsl | 11 ++- base/renderprogs/fog_skinned.ps.hlsl | 11 ++- base/renderprogs/global.inc.hlsl | 86 ++++++++++-------- neo/renderer/Framebuffer.h | 2 +- neo/renderer/Image_intrinsic.cpp | 7 +- neo/renderer/OpenGL/Framebuffer_GL.cpp | 31 ++++--- neo/renderer/RenderBackend.cpp | 76 ++++++++++++---- neo/renderer/RenderProgs_embedded.h | 119 ++++++++++++++++--------- 11 files changed, 249 insertions(+), 117 deletions(-) diff --git a/README.md b/README.md index d26b9f40..a8c4492a 100644 --- a/README.md +++ b/README.md @@ -408,8 +408,8 @@ convertMapToJSON | 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 diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 98031aec..524384fe 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -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 diff --git a/base/renderprogs/blendLight.ps.hlsl b/base/renderprogs/blendLight.ps.hlsl index 5a48232a..6dd83028 100644 --- a/base/renderprogs/blendLight.ps.hlsl +++ b/base/renderprogs/blendLight.ps.hlsl @@ -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; } diff --git a/base/renderprogs/fog.ps.hlsl b/base/renderprogs/fog.ps.hlsl index 0223498f..95c7fd70 100644 --- a/base/renderprogs/fog.ps.hlsl +++ b/base/renderprogs/fog.ps.hlsl @@ -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; } diff --git a/base/renderprogs/fog_skinned.ps.hlsl b/base/renderprogs/fog_skinned.ps.hlsl index 30a0370e..95c7fd70 100644 --- a/base/renderprogs/fog_skinned.ps.hlsl +++ b/base/renderprogs/fog_skinned.ps.hlsl @@ -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; } diff --git a/base/renderprogs/global.inc.hlsl b/base/renderprogs/global.inc.hlsl index 21dc060f..3c10a87b 100644 --- a/base/renderprogs/global.inc.hlsl +++ b/base/renderprogs/global.inc.hlsl @@ -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 // ---------------------- diff --git a/neo/renderer/Framebuffer.h b/neo/renderer/Framebuffer.h index 7b2d6216..e6fd5630 100644 --- a/neo/renderer/Framebuffer.h +++ b/neo/renderer/Framebuffer.h @@ -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; }; diff --git a/neo/renderer/Image_intrinsic.cpp b/neo/renderer/Image_intrinsic.cpp index 5d3b6b55..e90cdc48 100644 --- a/neo/renderer/Image_intrinsic.cpp +++ b/neo/renderer/Image_intrinsic.cpp @@ -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 ); diff --git a/neo/renderer/OpenGL/Framebuffer_GL.cpp b/neo/renderer/OpenGL/Framebuffer_GL.cpp index e0c9992f..db7a584b 100644 --- a/neo/renderer/OpenGL/Framebuffer_GL.cpp +++ b/neo/renderer/OpenGL/Framebuffer_GL.cpp @@ -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 diff --git a/neo/renderer/RenderBackend.cpp b/neo/renderer/RenderBackend.cpp index 6d69c158..d65d051b 100644 --- a/neo/renderer/RenderBackend.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -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(); diff --git a/neo/renderer/RenderProgs_embedded.h b/neo/renderer/RenderProgs_embedded.h index 6aba3048..9e58c0b8 100644 --- a/neo/renderer/RenderProgs_embedded.h +++ b/neo/renderer/RenderProgs_embedded.h @@ -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"