mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-03-10 00:25:22 +00:00
Raytracing: convert from linear RGB to sRGB in preview mode.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17354
This commit is contained in:
parent
87c42db898
commit
6b3396ea2d
3d-viewer/3d_rendering
@ -48,6 +48,12 @@ COLOR_RGBA::COLOR_RGBA( const SFVEC4F& aColor )
|
||||
}
|
||||
|
||||
|
||||
COLOR_RGBA::operator SFVEC4F() const
|
||||
{
|
||||
return SFVEC4F( r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f );
|
||||
}
|
||||
|
||||
|
||||
COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2 )
|
||||
{
|
||||
const unsigned int r = aC1.r + aC2.r;
|
||||
|
@ -60,6 +60,8 @@ union COLOR_RGBA
|
||||
b = aB;
|
||||
a = aA;
|
||||
}
|
||||
|
||||
operator SFVEC4F() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -37,6 +37,53 @@
|
||||
#include <wx/log.h>
|
||||
|
||||
|
||||
#ifdef USE_SRGB_SPACE
|
||||
|
||||
/// @todo This should be removed in future when KiCad supports a greater version of glm lib.
|
||||
#define SRGB_GAMA 2.4f
|
||||
|
||||
|
||||
// This function implements the conversion from linear RGB to sRGB
|
||||
// https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L12
|
||||
static SFVEC3F convertLinearToSRGB( const SFVEC3F& aRGBcolor )
|
||||
{
|
||||
const float gammaCorrection = 1.0f / SRGB_GAMA;
|
||||
const SFVEC3F clampedColor = glm::clamp( aRGBcolor, SFVEC3F( 0.0f ), SFVEC3F( 1.0f ) );
|
||||
|
||||
return glm::mix( glm::pow( clampedColor, SFVEC3F(gammaCorrection) ) * 1.055f - 0.055f,
|
||||
clampedColor * 12.92f,
|
||||
glm::lessThan( clampedColor, SFVEC3F(0.0031308f) ) );
|
||||
}
|
||||
|
||||
|
||||
static SFVEC4F convertLinearToSRGBA( const SFVEC4F& aRGBAcolor )
|
||||
{
|
||||
return SFVEC4F( convertLinearToSRGB( SFVEC3F( aRGBAcolor ) ), aRGBAcolor.a );
|
||||
}
|
||||
|
||||
|
||||
// This function implements the conversion from sRGB to linear RGB
|
||||
// https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L35
|
||||
SFVEC3F ConvertSRGBToLinear( const SFVEC3F& aSRGBcolor )
|
||||
{
|
||||
const float gammaCorrection = SRGB_GAMA;
|
||||
|
||||
return glm::mix( glm::pow( ( aSRGBcolor + SFVEC3F( 0.055f ) )
|
||||
* SFVEC3F( 0.94786729857819905213270142180095f ),
|
||||
SFVEC3F( gammaCorrection ) ),
|
||||
aSRGBcolor * SFVEC3F( 0.07739938080495356037151702786378f ),
|
||||
glm::lessThanEqual( aSRGBcolor, SFVEC3F( 0.04045f ) ) );
|
||||
}
|
||||
|
||||
|
||||
SFVEC4F ConvertSRGBAToLinear( const SFVEC4F& aSRGBAcolor )
|
||||
{
|
||||
return SFVEC4F( ConvertSRGBToLinear( SFVEC3F( aSRGBAcolor ) ), aSRGBAcolor.a );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
RENDER_3D_RAYTRACE_BASE::RENDER_3D_RAYTRACE_BASE( BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) :
|
||||
RENDER_3D_BASE( aAdapter, aCamera ),
|
||||
m_postShaderSsao( aCamera )
|
||||
@ -116,6 +163,19 @@ static inline void SetPixel( uint8_t* p, const COLOR_RGBA& v )
|
||||
}
|
||||
|
||||
|
||||
static void SetPixelSRGBA( uint8_t* p, const COLOR_RGBA& v )
|
||||
{
|
||||
SFVEC4F color = v;
|
||||
|
||||
#ifdef USE_SRGB_SPACE
|
||||
color = convertLinearToSRGB( color );
|
||||
#endif
|
||||
|
||||
COLOR_RGBA rgba( color );
|
||||
SetPixel( p, rgba );
|
||||
}
|
||||
|
||||
|
||||
SFVEC4F RENDER_3D_RAYTRACE_BASE::premultiplyAlpha( const SFVEC4F& aInput )
|
||||
{
|
||||
return SFVEC4F( aInput.r * aInput.a, aInput.g * aInput.a, aInput.b * aInput.a, aInput.a );
|
||||
@ -238,53 +298,6 @@ void RENDER_3D_RAYTRACE_BASE::renderTracing( uint8_t* ptrPBO, REPORTER* aStatusR
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_SRGB_SPACE
|
||||
|
||||
/// @todo This should be removed in future when KiCad supports a greater version of glm lib.
|
||||
#define SRGB_GAMA 2.4f
|
||||
|
||||
|
||||
// This function implements the conversion from linear RGB to sRGB
|
||||
// https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L12
|
||||
static SFVEC3F convertLinearToSRGB( const SFVEC3F& aRGBcolor )
|
||||
{
|
||||
const float gammaCorrection = 1.0f / SRGB_GAMA;
|
||||
const SFVEC3F clampedColor = glm::clamp( aRGBcolor, SFVEC3F( 0.0f ), SFVEC3F( 1.0f ) );
|
||||
|
||||
return glm::mix( glm::pow( clampedColor, SFVEC3F(gammaCorrection) ) * 1.055f - 0.055f,
|
||||
clampedColor * 12.92f,
|
||||
glm::lessThan( clampedColor, SFVEC3F(0.0031308f) ) );
|
||||
}
|
||||
|
||||
|
||||
static SFVEC4F convertLinearToSRGBA( const SFVEC4F& aRGBAcolor )
|
||||
{
|
||||
return SFVEC4F( convertLinearToSRGB( SFVEC3F( aRGBAcolor ) ), aRGBAcolor.a );
|
||||
}
|
||||
|
||||
|
||||
// This function implements the conversion from sRGB to linear RGB
|
||||
// https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L35
|
||||
SFVEC3F ConvertSRGBToLinear( const SFVEC3F& aSRGBcolor )
|
||||
{
|
||||
const float gammaCorrection = SRGB_GAMA;
|
||||
|
||||
return glm::mix( glm::pow( ( aSRGBcolor + SFVEC3F( 0.055f ) )
|
||||
* SFVEC3F( 0.94786729857819905213270142180095f ),
|
||||
SFVEC3F( gammaCorrection ) ),
|
||||
aSRGBcolor * SFVEC3F( 0.07739938080495356037151702786378f ),
|
||||
glm::lessThanEqual( aSRGBcolor, SFVEC3F( 0.04045f ) ) );
|
||||
}
|
||||
|
||||
|
||||
SFVEC4F ConvertSRGBAToLinear( const SFVEC4F& aSRGBAcolor )
|
||||
{
|
||||
return SFVEC4F( ConvertSRGBToLinear( SFVEC3F( aSRGBAcolor ) ), aSRGBAcolor.a );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE_BASE::renderFinalColor( uint8_t* ptrPBO, const SFVEC4F& rgbColor,
|
||||
bool applyColorSpaceConversion )
|
||||
{
|
||||
@ -791,6 +804,10 @@ void RENDER_3D_RAYTRACE_BASE::renderPreview( uint8_t* ptrPBO )
|
||||
{
|
||||
m_isPreview = true;
|
||||
|
||||
m_backgroundColorTop = ConvertSRGBAToLinear( premultiplyAlpha( m_boardAdapter.m_BgColorTop ) );
|
||||
m_backgroundColorBottom =
|
||||
ConvertSRGBAToLinear( premultiplyAlpha( m_boardAdapter.m_BgColorBot ) );
|
||||
|
||||
std::atomic<size_t> nextBlock( 0 );
|
||||
std::atomic<size_t> threadsFinished( 0 );
|
||||
|
||||
@ -827,8 +844,8 @@ void RENDER_3D_RAYTRACE_BASE::renderPreview( uint8_t* ptrPBO )
|
||||
// Calculate background gradient color
|
||||
SFVEC4F bgColor[RAYPACKET_DIM];
|
||||
|
||||
SFVEC4F bgTopColor = premultiplyAlpha( m_boardAdapter.m_BgColorTop );
|
||||
SFVEC4F bgBotColor = premultiplyAlpha( m_boardAdapter.m_BgColorBot );
|
||||
SFVEC4F bgTopColor = m_backgroundColorTop;
|
||||
SFVEC4F bgBotColor = m_backgroundColorBottom;
|
||||
|
||||
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
|
||||
{
|
||||
@ -1350,28 +1367,29 @@ void RENDER_3D_RAYTRACE_BASE::renderPreview( uint8_t* ptrPBO )
|
||||
&ptrPBO[( 4 * x + m_blockPositionsFast[iBlock].x
|
||||
+ m_realBufferSize.x
|
||||
* ( m_blockPositionsFast[iBlock].y + 4 * y ) ) * 4];
|
||||
SetPixel( ptr + 0, cLT );
|
||||
SetPixel( ptr + 4, BlendColor( cLT, cLRT, cLTC ) );
|
||||
SetPixel( ptr + 8, cLRT );
|
||||
SetPixel( ptr + 12, BlendColor( cLRT, cRT, cRTC ) );
|
||||
|
||||
SetPixelSRGBA( ptr + 0, cLT );
|
||||
SetPixelSRGBA( ptr + 4, BlendColor( cLT, cLRT, cLTC ) );
|
||||
SetPixelSRGBA( ptr + 8, cLRT );
|
||||
SetPixelSRGBA( ptr + 12, BlendColor( cLRT, cRT, cRTC ) );
|
||||
|
||||
ptr += m_realBufferSize.x * 4;
|
||||
SetPixel( ptr + 0, BlendColor( cLT , cLTB, cLTC ) );
|
||||
SetPixel( ptr + 4, BlendColor( cLTC, BlendColor( cLT , cC ) ) );
|
||||
SetPixel( ptr + 8, BlendColor( cC, BlendColor( cLRT, cLTC, cRTC ) ) );
|
||||
SetPixel( ptr + 12, BlendColor( cRTC, BlendColor( cRT , cC ) ) );
|
||||
SetPixelSRGBA( ptr + 0, BlendColor( cLT , cLTB, cLTC ) );
|
||||
SetPixelSRGBA( ptr + 4, BlendColor( cLTC, BlendColor( cLT , cC ) ) );
|
||||
SetPixelSRGBA( ptr + 8, BlendColor( cC, BlendColor( cLRT, cLTC, cRTC ) ) );
|
||||
SetPixelSRGBA( ptr + 12, BlendColor( cRTC, BlendColor( cRT , cC ) ) );
|
||||
|
||||
ptr += m_realBufferSize.x * 4;
|
||||
SetPixel( ptr + 0, cLTB );
|
||||
SetPixel( ptr + 4, BlendColor( cC, BlendColor( cLTB, cLTC, cLBC ) ) );
|
||||
SetPixel( ptr + 8, cC );
|
||||
SetPixel( ptr + 12, BlendColor( cC, BlendColor( cRTB, cRTC, cRBC ) ) );
|
||||
SetPixelSRGBA( ptr + 0, cLTB );
|
||||
SetPixelSRGBA( ptr + 4, BlendColor( cC, BlendColor( cLTB, cLTC, cLBC ) ) );
|
||||
SetPixelSRGBA( ptr + 8, cC );
|
||||
SetPixelSRGBA( ptr + 12, BlendColor( cC, BlendColor( cRTB, cRTC, cRBC ) ) );
|
||||
|
||||
ptr += m_realBufferSize.x * 4;
|
||||
SetPixel( ptr + 0, BlendColor( cLB , cLTB, cLBC ) );
|
||||
SetPixel( ptr + 4, BlendColor( cLBC, BlendColor( cLB , cC ) ) );
|
||||
SetPixel( ptr + 8, BlendColor( cC, BlendColor( cLRB, cLBC, cRBC ) ) );
|
||||
SetPixel( ptr + 12, BlendColor( cRBC, BlendColor( cRB , cC ) ) );
|
||||
SetPixelSRGBA( ptr + 0, BlendColor( cLB , cLTB, cLBC ) );
|
||||
SetPixelSRGBA( ptr + 4, BlendColor( cLBC, BlendColor( cLB , cC ) ) );
|
||||
SetPixelSRGBA( ptr + 8, BlendColor( cC, BlendColor( cLRB, cLBC, cRBC ) ) );
|
||||
SetPixelSRGBA( ptr + 12, BlendColor( cRBC, BlendColor( cRB , cC ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1497,7 +1515,7 @@ SFVEC4F RENDER_3D_RAYTRACE_BASE::shadeHit( const SFVEC4F& aBgColor, const RAY& a
|
||||
1.0 );
|
||||
}
|
||||
|
||||
// Only use the headlight for preview
|
||||
// Only use the headlight (or whatever the first light is) for preview
|
||||
if( m_isPreview )
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user