3D viewer: support transparent background in Raytracing mode.

This commit is contained in:
Alex Shvartzkop 2024-02-29 23:39:48 +03:00
parent 4a945172db
commit fb089a182b
13 changed files with 279 additions and 163 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -46,6 +46,19 @@ static void dbg_save_rgb_buffer( const wxString& aFileName, unsigned char *aRGBp
} }
static void dbg_save_rgb_a_buffer( const wxString& aFileName, unsigned char* aRGBpixelBuffer,
unsigned char* aAlphaBuffer, unsigned int aXSize,
unsigned int aYSize )
{
wxImage image( aXSize, aYSize );
image.SetData( aRGBpixelBuffer );
image.SetAlpha( aAlphaBuffer );
image = image.Mirror( false );
image.SaveFile( aFileName + wxT( ".png" ), wxBITMAP_TYPE_PNG );
image.Destroy();
}
void DBG_SaveBuffer( const wxString& aFileName, const unsigned char *aInBuffer, void DBG_SaveBuffer( const wxString& aFileName, const unsigned char *aInBuffer,
unsigned int aXSize, unsigned int aYSize ) unsigned int aXSize, unsigned int aYSize )
{ {
@ -110,6 +123,31 @@ void DBG_SaveBuffer( const wxString& aFileName, const SFVEC3F *aInBuffer,
} }
void DBG_SaveBuffer( const wxString& aFileName, const SFVEC4F *aInBuffer,
unsigned int aXSize, unsigned int aYSize )
{
const unsigned int wxh = aXSize * aYSize;
unsigned char *pixelbuffer = (unsigned char*) malloc( wxh * 4 );
unsigned char *alphabuffer = (unsigned char*) malloc( wxh );
for( unsigned int i = 0; i < wxh; ++i )
{
const SFVEC4F &v = aInBuffer[i];
const unsigned int ix3 = i * 3;
// Set RGB value with all same values intensities
pixelbuffer[ix3 + 0] = (unsigned char) glm::min( (int) ( v.r * 255.0f ), 255 );
pixelbuffer[ix3 + 1] = (unsigned char) glm::min( (int) ( v.g * 255.0f ), 255 );
pixelbuffer[ix3 + 2] = (unsigned char) glm::min( (int) ( v.b * 255.0f ), 255 );
alphabuffer[i] = (unsigned char) glm::min( (int) ( v.a * 255.0f ), 255 );
}
dbg_save_rgb_a_buffer( aFileName, pixelbuffer, alphabuffer, aXSize, aYSize );
}
void DBG_SaveNormalsBuffer( const wxString& aFileName, const SFVEC3F *aInNormalsBuffer, void DBG_SaveNormalsBuffer( const wxString& aFileName, const SFVEC3F *aInNormalsBuffer,
unsigned int aXSize, unsigned int aYSize ) unsigned int aXSize, unsigned int aYSize )
{ {

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -42,6 +42,9 @@ void DBG_SaveBuffer( const wxString& aFileName, const float *aInBuffer,
void DBG_SaveBuffer( const wxString& aFileName, const SFVEC3F *aInBuffer, void DBG_SaveBuffer( const wxString& aFileName, const SFVEC3F *aInBuffer,
unsigned int aXSize, unsigned int aYSize ); unsigned int aXSize, unsigned int aYSize );
void DBG_SaveBuffer( const wxString& aFileName, const SFVEC4F *aInBuffer,
unsigned int aXSize, unsigned int aYSize );
void DBG_SaveNormalsBuffer( const wxString& aFileName, const SFVEC3F *aInNormalsBuffer, void DBG_SaveNormalsBuffer( const wxString& aFileName, const SFVEC3F *aInNormalsBuffer,
unsigned int aXSize, unsigned int aYSize ); unsigned int aXSize, unsigned int aYSize );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,47 +23,60 @@
*/ */
/** /**
* @file color_rgb.cpp * @file color_rgba.cpp
*/ */
#include "color_rgb.h" #include "color_rgba.h"
COLOR_RGB::COLOR_RGB( const SFVEC3F& aColor ) COLOR_RGBA::COLOR_RGBA( const SFVEC3F& aColor )
{ {
r = (unsigned int) glm::clamp( (int) ( aColor.r * 255 ), 0, 255 ); r = (unsigned int) glm::clamp( (int) ( aColor.r * 255 ), 0, 255 );
g = (unsigned int) glm::clamp( (int) ( aColor.g * 255 ), 0, 255 ); g = (unsigned int) glm::clamp( (int) ( aColor.g * 255 ), 0, 255 );
b = (unsigned int) glm::clamp( (int) ( aColor.b * 255 ), 0, 255 ); b = (unsigned int) glm::clamp( (int) ( aColor.b * 255 ), 0, 255 );
a = 255;
} }
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2 ) COLOR_RGBA::COLOR_RGBA( const SFVEC4F& aColor )
{
r = (unsigned int) glm::clamp( (int) ( aColor.r * 255 ), 0, 255 );
g = (unsigned int) glm::clamp( (int) ( aColor.g * 255 ), 0, 255 );
b = (unsigned int) glm::clamp( (int) ( aColor.b * 255 ), 0, 255 );
a = (unsigned int) glm::clamp( (int) ( aColor.a * 255 ), 0, 255 );
}
COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2 )
{ {
const unsigned int r = aC1.r + aC2.r; const unsigned int r = aC1.r + aC2.r;
const unsigned int g = aC1.g + aC2.g; const unsigned int g = aC1.g + aC2.g;
const unsigned int b = aC1.b + aC2.b; const unsigned int b = aC1.b + aC2.b;
const unsigned int a = aC1.a + aC2.a;
return COLOR_RGB( ( r >> 1 ), ( g >> 1 ), ( b >> 1 ) ); return COLOR_RGBA( ( r >> 1 ), ( g >> 1 ), ( b >> 1 ), ( a >> 1 ) );
} }
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2, const COLOR_RGB& aC3 ) COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2, const COLOR_RGBA& aC3 )
{ {
const unsigned int r = aC1.r + aC2.r + aC3.r; const unsigned int r = aC1.r + aC2.r + aC3.r;
const unsigned int g = aC1.g + aC2.g + aC3.g; const unsigned int g = aC1.g + aC2.g + aC3.g;
const unsigned int b = aC1.b + aC2.b + aC3.b; const unsigned int b = aC1.b + aC2.b + aC3.b;
const unsigned int a = aC1.a + aC2.a + aC3.a;
return COLOR_RGB( ( r / 3 ), ( g / 3 ), ( b / 3 ) ); return COLOR_RGBA( ( r / 3 ), ( g / 3 ), ( b / 3 ), ( a / 3 ) );
} }
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2, const COLOR_RGB& aC3, COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2, const COLOR_RGBA& aC3,
const COLOR_RGB& aC4 ) const COLOR_RGBA& aC4 )
{ {
const unsigned int r = aC1.r + aC2.r + aC3.r + aC4.r; const unsigned int r = aC1.r + aC2.r + aC3.r + aC4.r;
const unsigned int g = aC1.g + aC2.g + aC3.g + aC4.g; const unsigned int g = aC1.g + aC2.g + aC3.g + aC4.g;
const unsigned int b = aC1.b + aC2.b + aC3.b + aC4.b; const unsigned int b = aC1.b + aC2.b + aC3.b + aC4.b;
const unsigned int a = aC1.a + aC2.a + aC3.a + aC4.a;
return COLOR_RGB( ( r >> 2 ), ( g >> 2 ), ( b >> 2 ) ); return COLOR_RGBA( ( r >> 2 ), ( g >> 2 ), ( b >> 2 ), ( a >> 2 ) );
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,39 +23,49 @@
*/ */
/** /**
* @file color_rgb.h * @file color_rgba.h
*/ */
#ifndef COLOR_RGB_H #ifndef COLOR_RGBA_H
#define COLOR_RGB_H #define COLOR_RGBA_H
#include <plugins/3dapi/xv3d_types.h> #include <plugins/3dapi/xv3d_types.h>
union COLOR_RGB union COLOR_RGBA
{ {
unsigned char c[3]; unsigned char c[4];
struct struct
{ {
unsigned char r; unsigned char r;
unsigned char g; unsigned char g;
unsigned char b; unsigned char b;
unsigned char a;
}; };
COLOR_RGB( const SFVEC3F& aColor ); COLOR_RGBA( const SFVEC3F& aColor );
COLOR_RGB() { r = 0; g = 0; b = 0; } COLOR_RGBA( const SFVEC4F& aColor );
COLOR_RGB( unsigned char aR, unsigned char aG, unsigned char aB ) COLOR_RGBA() { r = 0; g = 0; b = 0; a = 0; }
COLOR_RGBA( unsigned char aR, unsigned char aG, unsigned char aB )
{ {
r = aR; r = aR;
g = aG; g = aG;
b = aB; b = aB;
} }
COLOR_RGBA( unsigned char aR, unsigned char aG, unsigned char aB, unsigned char aA )
{
r = aR;
g = aG;
b = aB;
a = aA;
}
}; };
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2 ); COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2 );
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2, const COLOR_RGB& aC3 ); COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2, const COLOR_RGBA& aC3 );
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2, const COLOR_RGB& aC3, COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2, const COLOR_RGBA& aC3,
const COLOR_RGB& aC4 ); const COLOR_RGBA& aC4 );
#endif // COLOR_RGB_H #endif // COLOR_RGBA_H

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2023 CERN * Copyright (C) 2023 CERN
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -444,6 +444,12 @@ void RENDER_3D_OPENGL::renderBoardBody( bool aSkipRenderHoles )
} }
static inline SFVEC4F premultiplyAlpha( const SFVEC4F& aInput )
{
return SFVEC4F( aInput.r * aInput.a, aInput.g * aInput.a, aInput.b * aInput.a, aInput.a );
}
bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter, bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
REPORTER* aWarningReporter ) REPORTER* aWarningReporter )
{ {
@ -503,7 +509,8 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
OglResetTextureState(); OglResetTextureState();
// Draw the background ( rectangle with color gradient) // Draw the background ( rectangle with color gradient)
OglDrawBackground( m_boardAdapter.m_BgColorTop, m_boardAdapter.m_BgColorBot ); OglDrawBackground( premultiplyAlpha( m_boardAdapter.m_BgColorTop ),
premultiplyAlpha( m_boardAdapter.m_BgColorBot ) );
glEnable( GL_DEPTH_TEST ); glEnable( GL_DEPTH_TEST );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -63,7 +63,7 @@ void POST_SHADER::UpdateSize( unsigned int xSize, unsigned int ySize )
const unsigned int n_elements = xSize * ySize; const unsigned int n_elements = xSize * ySize;
m_normals = new SFVEC3F[n_elements]; m_normals = new SFVEC3F[n_elements];
m_color = new SFVEC3F[n_elements]; m_color = new SFVEC4F[n_elements];
m_depth = new float[n_elements]; m_depth = new float[n_elements];
m_wc_hitposition = new SFVEC3F[n_elements]; m_wc_hitposition = new SFVEC3F[n_elements];
m_shadow_att_factor = new float[n_elements]; m_shadow_att_factor = new float[n_elements];
@ -77,7 +77,7 @@ void POST_SHADER::UpdateSize( const SFVEC2UI& aSize )
void POST_SHADER::SetPixelData( unsigned int x, unsigned int y, const SFVEC3F& aNormal, void POST_SHADER::SetPixelData( unsigned int x, unsigned int y, const SFVEC3F& aNormal,
const SFVEC3F& aColor, const SFVEC3F& aHitPosition, const SFVEC4F& aColor, const SFVEC3F& aHitPosition,
float aDepth, float aShadowAttFactor ) float aDepth, float aShadowAttFactor )
{ {
wxASSERT( x < m_size.x ); wxASSERT( x < m_size.x );
@ -125,7 +125,7 @@ const SFVEC3F& POST_SHADER::GetNormalAt( const SFVEC2F& aPos ) const
} }
const SFVEC3F& POST_SHADER::GetColorAt( const SFVEC2F& aPos ) const const SFVEC4F& POST_SHADER::GetColorAt( const SFVEC2F& aPos ) const
{ {
return m_color[GetIndex( aPos )]; return m_color[GetIndex( aPos )];
} }
@ -149,13 +149,13 @@ const SFVEC3F& POST_SHADER::GetNormalAt( const SFVEC2I& aPos ) const
} }
const SFVEC3F& POST_SHADER::GetColorAt( const SFVEC2I& aPos ) const const SFVEC4F& POST_SHADER::GetColorAt( const SFVEC2I& aPos ) const
{ {
return m_color[GetIndex( aPos )]; return m_color[GetIndex( aPos )];
} }
const SFVEC3F& POST_SHADER::GetColorAtNotProtected( const SFVEC2I& aPos ) const const SFVEC4F& POST_SHADER::GetColorAtNotProtected( const SFVEC2I& aPos ) const
{ {
return m_color[ aPos.x + m_size.x * aPos.y ]; return m_color[ aPos.x + m_size.x * aPos.y ];
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -46,7 +46,7 @@ public:
* @param aShadeColor The result of the shader. * @param aShadeColor The result of the shader.
* @return the result of the shade process * @return the result of the shade process
*/ */
virtual SFVEC3F ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC3F& aInputColor, virtual SFVEC4F ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC4F& aInputColor,
const SFVEC3F& aShadeColor ) const = 0; const SFVEC3F& aShadeColor ) const = 0;
void UpdateSize( const SFVEC2UI& aSize ); void UpdateSize( const SFVEC2UI& aSize );
@ -56,10 +56,10 @@ public:
void InitFrame() { m_tmin = FLT_MAX; m_tmax = 0.0f; } void InitFrame() { m_tmin = FLT_MAX; m_tmax = 0.0f; }
void SetPixelData( unsigned int x, unsigned int y, const SFVEC3F& aNormal, void SetPixelData( unsigned int x, unsigned int y, const SFVEC3F& aNormal,
const SFVEC3F& aColor, const SFVEC3F& aHitPosition, const SFVEC4F& aColor, const SFVEC3F& aHitPosition,
float aDepth, float aShadowAttFactor ); float aDepth, float aShadowAttFactor );
const SFVEC3F& GetColorAtNotProtected( const SFVEC2I& aPos ) const; const SFVEC4F& GetColorAtNotProtected( const SFVEC2I& aPos ) const;
void DebugBuffersOutputAsImages() const; void DebugBuffersOutputAsImages() const;
@ -88,12 +88,12 @@ public:
protected: protected:
const SFVEC3F& GetNormalAt( const SFVEC2F& aPos ) const; const SFVEC3F& GetNormalAt( const SFVEC2F& aPos ) const;
const SFVEC3F& GetColorAt( const SFVEC2F& aPos ) const; const SFVEC4F& GetColorAt( const SFVEC2F& aPos ) const;
const SFVEC3F& GetPositionAt( const SFVEC2F& aPos ) const; const SFVEC3F& GetPositionAt( const SFVEC2F& aPos ) const;
float GetDepthAt( const SFVEC2F& aPos ) const; float GetDepthAt( const SFVEC2F& aPos ) const;
const SFVEC3F& GetNormalAt( const SFVEC2I& aPos ) const; const SFVEC3F& GetNormalAt( const SFVEC2I& aPos ) const;
const SFVEC3F& GetColorAt( const SFVEC2I& aPos ) const; const SFVEC4F& GetColorAt( const SFVEC2I& aPos ) const;
const SFVEC3F& GetPositionAt( const SFVEC2I& aPos ) const; const SFVEC3F& GetPositionAt( const SFVEC2I& aPos ) const;
const float& GetShadowFactorAt( const SFVEC2I& aPos ) const; const float& GetShadowFactorAt( const SFVEC2I& aPos ) const;
@ -109,7 +109,7 @@ protected:
SFVEC2UI m_size; SFVEC2UI m_size;
SFVEC3F* m_normals; SFVEC3F* m_normals;
SFVEC3F* m_color; SFVEC4F* m_color;
SFVEC3F* m_wc_hitposition; SFVEC3F* m_wc_hitposition;
float* m_depth; float* m_depth;
float* m_shadow_att_factor; float* m_shadow_att_factor;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -187,21 +187,21 @@ SFVEC3F POST_SHADER_SSAO::Shade( const SFVEC2I& aShaderPos ) const
ao += aoFF( aShaderPos, ddiff8, n, shadowAt8, shadowAt0, -npw, ph ); ao += aoFF( aShaderPos, ddiff8, n, shadowAt8, shadowAt0, -npw, ph );
gi += giFF( aShaderPos, ddiff , n, shadowAt1, npw, nph) * gi += giFF( aShaderPos, ddiff , n, shadowAt1, npw, nph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( npw, nph ) ) ); giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( npw, nph ) ) );
gi += giFF( aShaderPos, ddiff2, n, shadowAt2, npw, -nph) * gi += giFF( aShaderPos, ddiff2, n, shadowAt2, npw, -nph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( npw,-nph ) ) ); giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( npw,-nph ) ) );
gi += giFF( aShaderPos, ddiff3, n, shadowAt3, -npw, nph) * gi += giFF( aShaderPos, ddiff3, n, shadowAt3, -npw, nph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, nph ) ) ); giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( -npw, nph ) ) );
gi += giFF( aShaderPos, ddiff4, n, shadowAt4, -npw, -nph) * gi += giFF( aShaderPos, ddiff4, n, shadowAt4, -npw, -nph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw,-nph ) ) ); giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( -npw,-nph ) ) );
gi += giFF( aShaderPos, ddiff5, n, shadowAt5 , pw, nph) * gi += giFF( aShaderPos, ddiff5, n, shadowAt5 , pw, nph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( pw, nph ) ) ); giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( pw, nph ) ) );
gi += giFF( aShaderPos, ddiff6, n, shadowAt6, pw,-nph) * gi += giFF( aShaderPos, ddiff6, n, shadowAt6, pw,-nph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( pw,-nph ) ) ); giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( pw,-nph ) ) );
gi += giFF( aShaderPos, ddiff7, n, shadowAt7, npw, ph) * gi += giFF( aShaderPos, ddiff7, n, shadowAt7, npw, ph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( npw, ph ) ) ); giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( npw, ph ) ) );
gi += giFF( aShaderPos, ddiff8, n, shadowAt8, -npw, ph) * gi += giFF( aShaderPos, ddiff8, n, shadowAt8, -npw, ph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, ph ) ) ); giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( -npw, ph ) ) );
} }
// If it received direct light, it shouldn't consider much AO // If it received direct light, it shouldn't consider much AO
@ -227,18 +227,20 @@ SFVEC3F POST_SHADER_SSAO::Shade( const SFVEC2I& aShaderPos ) const
} }
SFVEC3F POST_SHADER_SSAO::ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC3F& aInputColor, SFVEC4F POST_SHADER_SSAO::ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC4F& aInputColor,
const SFVEC3F& aShadeColor ) const const SFVEC3F& aShadeColor ) const
{ {
SFVEC3F outColor; SFVEC4F outColor;
SFVEC3F inColor( aInputColor );
const SFVEC3F subtracted = aInputColor - aShadeColor; const SFVEC3F subtracted = inColor - aShadeColor;
const SFVEC3F mixed = glm::mix( aInputColor, aInputColor * 0.50f - aShadeColor * 0.05f, const SFVEC3F mixed = glm::mix( inColor, inColor * 0.50f - aShadeColor * 0.05f,
glm::min( aShadeColor, 1.0f ) ); glm::min( aShadeColor, 1.0f ) );
outColor.r = ( aShadeColor.r < 0.0f ) ? subtracted.r : mixed.r; outColor.r = ( aShadeColor.r < 0.0f ) ? subtracted.r : mixed.r;
outColor.g = ( aShadeColor.g < 0.0f ) ? subtracted.g : mixed.g; outColor.g = ( aShadeColor.g < 0.0f ) ? subtracted.g : mixed.g;
outColor.b = ( aShadeColor.b < 0.0f ) ? subtracted.b : mixed.b; outColor.b = ( aShadeColor.b < 0.0f ) ? subtracted.b : mixed.b;
outColor.a = std::max( aInputColor.a, ( aShadeColor.r + aShadeColor.g + aShadeColor.b ) / 3 );
return outColor; return outColor;
} }
@ -256,6 +258,18 @@ SFVEC3F POST_SHADER_SSAO::giColorCurve( const SFVEC3F& aColor ) const
} }
SFVEC4F POST_SHADER_SSAO::giColorCurve( const SFVEC4F& aColor ) const
{
return SFVEC4F( giColorCurve( SFVEC3F( aColor ) ), aColor.a );
}
SFVEC3F POST_SHADER_SSAO::giColorCurveShade( const SFVEC4F& aColor ) const
{
return giColorCurve( SFVEC3F( aColor ) );
}
SFVEC3F POST_SHADER_SSAO::Blur( const SFVEC2I& aShaderPos ) const SFVEC3F POST_SHADER_SSAO::Blur( const SFVEC2I& aShaderPos ) const
{ {
const float dCenter = GetDepthAt( aShaderPos ); const float dCenter = GetDepthAt( aShaderPos );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -40,7 +40,7 @@ public:
explicit POST_SHADER_SSAO( const CAMERA& aCamera ); explicit POST_SHADER_SSAO( const CAMERA& aCamera );
SFVEC3F Shade(const SFVEC2I& aShaderPos ) const override; SFVEC3F Shade(const SFVEC2I& aShaderPos ) const override;
SFVEC3F ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC3F& aInputColor, SFVEC4F ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC4F& aInputColor,
const SFVEC3F& aShadeColor ) const override; const SFVEC3F& aShadeColor ) const override;
SFVEC3F Blur( const SFVEC2I& aShaderPos ) const; SFVEC3F Blur( const SFVEC2I& aShaderPos ) const;
@ -77,6 +77,8 @@ private:
* @return transformed color. * @return transformed color.
*/ */
SFVEC3F giColorCurve( const SFVEC3F& aColor ) const; SFVEC3F giColorCurve( const SFVEC3F& aColor ) const;
SFVEC4F giColorCurve( const SFVEC4F& aColor ) const;
SFVEC3F giColorCurveShade( const SFVEC4F& aColor ) const;
SFVEC3F* m_shadedBuffer; SFVEC3F* m_shadedBuffer;

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2023 CERN * Copyright (C) 2023 CERN
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -170,7 +170,7 @@ void RENDER_3D_RAYTRACE::setupMaterials()
m_materials.m_Floor = BLINN_PHONG_MATERIAL( bgTop * 0.125f, SFVEC3F( 0.0f, 0.0f, 0.0f ), m_materials.m_Floor = BLINN_PHONG_MATERIAL( bgTop * 0.125f, SFVEC3F( 0.0f, 0.0f, 0.0f ),
( SFVEC3F( 1.0f ) - bgTop ) / 3.0f, ( SFVEC3F( 1.0f ) - bgTop ) / 3.0f,
0.10f * 128.0f, 0.0f, 0.50f ); 0.10f * 128.0f, 1.0f, 0.50f );
m_materials.m_Floor.SetCastShadows( false ); m_materials.m_Floor.SetCastShadows( false );
m_materials.m_Floor.SetReflectionRecursionCount( 1 ); m_materials.m_Floor.SetReflectionRecursionCount( 1 );
} }
@ -817,7 +817,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
const SFVEC3F v2 = SFVEC3F( v1.x, v3.y, v1.z ); const SFVEC3F v2 = SFVEC3F( v1.x, v3.y, v1.z );
const SFVEC3F v4 = SFVEC3F( v3.x, v1.y, v1.z ); const SFVEC3F v4 = SFVEC3F( v3.x, v1.y, v1.z );
SFVEC3F backgroundColor = ConvertSRGBToLinear( m_boardAdapter.m_BgColorTop ); SFVEC3F floorColor = ConvertSRGBToLinear( m_boardAdapter.m_BgColorTop );
TRIANGLE* newTriangle1 = new TRIANGLE( v1, v2, v3 ); TRIANGLE* newTriangle1 = new TRIANGLE( v1, v2, v3 );
TRIANGLE* newTriangle2 = new TRIANGLE( v3, v4, v1 ); TRIANGLE* newTriangle2 = new TRIANGLE( v3, v4, v1 );
@ -828,8 +828,8 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
newTriangle1->SetMaterial( &m_materials.m_Floor ); newTriangle1->SetMaterial( &m_materials.m_Floor );
newTriangle2->SetMaterial( &m_materials.m_Floor ); newTriangle2->SetMaterial( &m_materials.m_Floor );
newTriangle1->SetColor( backgroundColor ); newTriangle1->SetColor( floorColor );
newTriangle2->SetColor( backgroundColor ); newTriangle2->SetColor( floorColor );
// Ceiling triangles // Ceiling triangles
const float maxZ = glm::max( containerBBox.Max().z, boardBBox.Max().z ); const float maxZ = glm::max( containerBBox.Max().z, boardBBox.Max().z );
@ -848,8 +848,8 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
newTriangle3->SetMaterial( &m_materials.m_Floor ); newTriangle3->SetMaterial( &m_materials.m_Floor );
newTriangle4->SetMaterial( &m_materials.m_Floor ); newTriangle4->SetMaterial( &m_materials.m_Floor );
newTriangle3->SetColor( backgroundColor ); newTriangle3->SetColor( floorColor );
newTriangle4->SetColor( backgroundColor ); newTriangle4->SetColor( floorColor );
} }
} }
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -31,7 +31,7 @@
#include "render_3d_raytrace.h" #include "render_3d_raytrace.h"
#include "mortoncodes.h" #include "mortoncodes.h"
#include "../color_rgb.h" #include "../color_rgba.h"
#include "3d_fastmath.h" #include "3d_fastmath.h"
#include "3d_math.h" #include "3d_math.h"
#include "../common_ogl/ogl_utils.h" #include "../common_ogl/ogl_utils.h"
@ -136,12 +136,18 @@ void RENDER_3D_RAYTRACE::restartRenderState()
} }
static inline void SetPixel( GLubyte* p, const COLOR_RGB& v ) static inline void SetPixel( GLubyte* p, const COLOR_RGBA& v )
{ {
p[0] = v.c[0]; p[0] = v.c[0];
p[1] = v.c[1]; p[1] = v.c[1];
p[2] = v.c[2]; p[2] = v.c[2];
p[3] = 255; p[3] = v.c[3];
}
static inline SFVEC4F premultiplyAlpha( const SFVEC4F& aInput )
{
return SFVEC4F( aInput.r * aInput.a, aInput.g * aInput.a, aInput.b * aInput.a, aInput.a );
} }
@ -220,7 +226,8 @@ bool RENDER_3D_RAYTRACE::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( m_cameraLight ) if( m_cameraLight )
m_cameraLight->SetDirection( -m_camera.GetDir() ); m_cameraLight->SetDirection( -m_camera.GetDir() );
OglDrawBackground( m_boardAdapter.m_BgColorTop, m_boardAdapter.m_BgColorBot ); OglDrawBackground( premultiplyAlpha( m_boardAdapter.m_BgColorTop ),
premultiplyAlpha( m_boardAdapter.m_BgColorBot ) );
// Bind PBO // Bind PBO
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId ); glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
@ -306,8 +313,10 @@ void RENDER_3D_RAYTRACE::render( GLubyte* ptrPBO, REPORTER* aStatusReporter )
} }
} }
m_backgroundColorTop = ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_BgColorTop ); m_backgroundColorTop =
m_backgroundColorBottom = ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_BgColorBot ); ConvertSRGBAToLinear( premultiplyAlpha( m_boardAdapter.m_BgColorTop ) );
m_backgroundColorBottom =
ConvertSRGBAToLinear( premultiplyAlpha( m_boardAdapter.m_BgColorBot ) );
} }
switch( m_renderState ) switch( m_renderState )
@ -423,6 +432,11 @@ static SFVEC3F convertLinearToSRGB( const SFVEC3F& aRGBcolor )
glm::lessThan( clampedColor, SFVEC3F(0.0031308f) ) ); 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 // This function implements the conversion from sRGB to linear RGB
// https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L35 // https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L35
@ -437,13 +451,18 @@ SFVEC3F ConvertSRGBToLinear( const SFVEC3F& aSRGBcolor )
glm::lessThanEqual( aSRGBcolor, SFVEC3F( 0.04045f ) ) ); glm::lessThanEqual( aSRGBcolor, SFVEC3F( 0.04045f ) ) );
} }
SFVEC4F ConvertSRGBAToLinear( const SFVEC4F& aSRGBAcolor )
{
return SFVEC4F( ConvertSRGBToLinear( SFVEC3F( aSRGBAcolor ) ), aSRGBAcolor.a );
}
#endif #endif
void RENDER_3D_RAYTRACE::renderFinalColor( GLubyte* ptrPBO, const SFVEC3F& rgbColor, void RENDER_3D_RAYTRACE::renderFinalColor( GLubyte* ptrPBO, const SFVEC4F& rgbColor,
bool applyColorSpaceConversion ) bool applyColorSpaceConversion )
{ {
SFVEC3F color = rgbColor; SFVEC4F color = rgbColor;
#ifdef USE_SRGB_SPACE #ifdef USE_SRGB_SPACE
/// @note This should be used in future when the KiCad support a greater version of glm lib. /// @note This should be used in future when the KiCad support a greater version of glm lib.
@ -457,7 +476,7 @@ void RENDER_3D_RAYTRACE::renderFinalColor( GLubyte* ptrPBO, const SFVEC3F& rgbCo
ptrPBO[0] = (unsigned int) glm::clamp( (int) ( color.r * 255 ), 0, 255 ); ptrPBO[0] = (unsigned int) glm::clamp( (int) ( color.r * 255 ), 0, 255 );
ptrPBO[1] = (unsigned int) glm::clamp( (int) ( color.g * 255 ), 0, 255 ); ptrPBO[1] = (unsigned int) glm::clamp( (int) ( color.g * 255 ), 0, 255 );
ptrPBO[2] = (unsigned int) glm::clamp( (int) ( color.b * 255 ), 0, 255 ); ptrPBO[2] = (unsigned int) glm::clamp( (int) ( color.b * 255 ), 0, 255 );
ptrPBO[3] = 255; ptrPBO[3] = (unsigned int) glm::clamp( (int) ( color.a * 255 ), 0, 255 );
} }
@ -475,9 +494,9 @@ static void HITINFO_PACKET_init( HITINFO_PACKET* aHitPacket )
} }
void RENDER_3D_RAYTRACE::renderRayPackets( const SFVEC3F* bgColorY, const RAY* aRayPkt, void RENDER_3D_RAYTRACE::renderRayPackets( const SFVEC4F* bgColorY, const RAY* aRayPkt,
HITINFO_PACKET* aHitPacket, bool is_testShadow, HITINFO_PACKET* aHitPacket, bool is_testShadow,
SFVEC3F* aOutHitColor ) SFVEC4F* aOutHitColor )
{ {
for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y ) for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
{ {
@ -497,10 +516,10 @@ void RENDER_3D_RAYTRACE::renderRayPackets( const SFVEC3F* bgColorY, const RAY* a
} }
void RENDER_3D_RAYTRACE::renderAntiAliasPackets( const SFVEC3F* aBgColorY, void RENDER_3D_RAYTRACE::renderAntiAliasPackets( const SFVEC4F* aBgColorY,
const HITINFO_PACKET* aHitPck_X0Y0, const HITINFO_PACKET* aHitPck_X0Y0,
const HITINFO_PACKET* aHitPck_AA_X1Y1, const HITINFO_PACKET* aHitPck_AA_X1Y1,
const RAY* aRayPck, SFVEC3F* aOutHitColor ) const RAY* aRayPck, SFVEC4F* aOutHitColor )
{ {
const bool is_testShadow = m_boardAdapter.m_Cfg->m_Render.raytrace_shadows; const bool is_testShadow = m_boardAdapter.m_Cfg->m_Render.raytrace_shadows;
@ -636,14 +655,14 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
HITINFO_PACKET_init( hitPacket_X0Y0 ); HITINFO_PACKET_init( hitPacket_X0Y0 );
// Calculate background gradient color // Calculate background gradient color
SFVEC3F bgColor[RAYPACKET_DIM];// Store a vertical gradient color SFVEC4F bgColor[RAYPACKET_DIM];// Store a vertical gradient color
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
{ {
const float posYfactor = (float) ( blockPosI.y + y ) / (float) m_windowSize.y; const float posYfactor = (float) ( blockPosI.y + y ) / (float) m_windowSize.y;
bgColor[y] = m_backgroundColorTop * SFVEC3F(posYfactor) + bgColor[y] = m_backgroundColorTop * SFVEC4F(posYfactor) +
m_backgroundColorBottom * ( SFVEC3F(1.0f) - SFVEC3F(posYfactor) ); m_backgroundColorBottom * ( SFVEC4F(1.0f) - SFVEC4F(posYfactor) );
} }
// Intersect ray packets (calculate the intersection with rays and objects) // Intersect ray packets (calculate the intersection with rays and objects)
@ -654,7 +673,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
{ {
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
{ {
const SFVEC3F& outColor = bgColor[y]; const SFVEC4F& outColor = bgColor[y];
const unsigned int yBlockPos = blockPos.y + y; const unsigned int yBlockPos = blockPos.y + y;
@ -674,7 +693,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
{ {
const SFVEC3F& outColor = bgColor[y]; const SFVEC4F& outColor = bgColor[y];
const unsigned int yConst = blockPos.x + ( ( y + blockPos.y ) * m_realBufferSize.x ); const unsigned int yConst = blockPos.x + ( ( y + blockPos.y ) * m_realBufferSize.x );
@ -691,7 +710,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
return; return;
} }
SFVEC3F hitColor_X0Y0[RAYPACKET_RAYS_PER_PACKET]; SFVEC4F hitColor_X0Y0[RAYPACKET_RAYS_PER_PACKET];
// Shade original (0, 0) hits ("paint" the intersected objects) // Shade original (0, 0) hits ("paint" the intersected objects)
renderRayPackets( bgColor, blockPacket.m_ray, hitPacket_X0Y0, renderRayPackets( bgColor, blockPacket.m_ray, hitPacket_X0Y0,
@ -699,7 +718,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
if( m_boardAdapter.m_Cfg->m_Render.raytrace_anti_aliasing ) if( m_boardAdapter.m_Cfg->m_Render.raytrace_anti_aliasing )
{ {
SFVEC3F hitColor_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET]; SFVEC4F hitColor_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
// Intersect one blockPosI + (0.5, 0.5) used for anti aliasing calculation // Intersect one blockPosI + (0.5, 0.5) used for anti aliasing calculation
HITINFO_PACKET hitPacket_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET]; HITINFO_PACKET hitPacket_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
@ -713,7 +732,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
// Missed all the package // Missed all the package
for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y ) for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
{ {
const SFVEC3F& outColor = bgColor[y]; const SFVEC4F& outColor = bgColor[y];
for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i ) for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
hitColor_AA_X1Y1[i] = outColor; hitColor_AA_X1Y1[i] = outColor;
@ -725,13 +744,13 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
m_boardAdapter.m_Cfg->m_Render.raytrace_shadows, hitColor_AA_X1Y1 ); m_boardAdapter.m_Cfg->m_Render.raytrace_shadows, hitColor_AA_X1Y1 );
} }
SFVEC3F hitColor_AA_X1Y0[RAYPACKET_RAYS_PER_PACKET]; SFVEC4F hitColor_AA_X1Y0[RAYPACKET_RAYS_PER_PACKET];
SFVEC3F hitColor_AA_X0Y1[RAYPACKET_RAYS_PER_PACKET]; SFVEC4F hitColor_AA_X0Y1[RAYPACKET_RAYS_PER_PACKET];
SFVEC3F hitColor_AA_X0Y1_half[RAYPACKET_RAYS_PER_PACKET]; SFVEC4F hitColor_AA_X0Y1_half[RAYPACKET_RAYS_PER_PACKET];
for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i ) for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
{ {
SFVEC3F color_average = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] ) * SFVEC3F( 0.5f ); SFVEC4F color_average = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] ) * SFVEC4F( 0.5f );
hitColor_AA_X1Y0[i] = color_average; hitColor_AA_X1Y0[i] = color_average;
hitColor_AA_X0Y1[i] = color_average; hitColor_AA_X0Y1[i] = color_average;
@ -768,7 +787,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
{ {
hitColor_X0Y0[i] = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] + hitColor_AA_X1Y0[i] + hitColor_X0Y0[i] = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] + hitColor_AA_X1Y0[i] +
hitColor_AA_X0Y1[i] + hitColor_AA_X0Y1_half[i] ) * hitColor_AA_X0Y1[i] + hitColor_AA_X0Y1_half[i] ) *
SFVEC3F( 1.0f / 5.0f ); SFVEC4F( 1.0f / 5.0f );
} }
} }
@ -788,7 +807,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i ) for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
{ {
const SFVEC3F& hColor = hitColor_X0Y0[i]; const SFVEC4F& hColor = hitColor_X0Y0[i];
if( hitPacket_X0Y0[i].m_hitresult == true ) if( hitPacket_X0Y0[i].m_hitresult == true )
{ {
@ -908,13 +927,13 @@ void RENDER_3D_RAYTRACE::postProcessBlurFinish( GLubyte* ptrPBO, REPORTER* /* aS
const SFVEC3F bluredShadeColor = m_postShaderSsao.Blur( SFVEC2I( x, y ) ); const SFVEC3F bluredShadeColor = m_postShaderSsao.Blur( SFVEC2I( x, y ) );
#ifdef USE_SRGB_SPACE #ifdef USE_SRGB_SPACE
const SFVEC3F originColor = convertLinearToSRGB( const SFVEC4F originColor = convertLinearToSRGBA(
m_postShaderSsao.GetColorAtNotProtected( SFVEC2I( x, y ) ) ); m_postShaderSsao.GetColorAtNotProtected( SFVEC2I( x, y ) ) );
#else #else
const SFVEC3F originColor = const SFVEC4F originColor =
m_postShaderSsao.GetColorAtNotProtected( SFVEC2I( x, y ) ); m_postShaderSsao.GetColorAtNotProtected( SFVEC2I( x, y ) );
#endif #endif
const SFVEC3F shadedColor = m_postShaderSsao.ApplyShadeColor( const SFVEC4F shadedColor = m_postShaderSsao.ApplyShadeColor(
SFVEC2I( x, y ), originColor, bluredShadeColor ); SFVEC2I( x, y ), originColor, bluredShadeColor );
renderFinalColor( ptr, shadedColor, false ); renderFinalColor( ptr, shadedColor, false );
@ -979,45 +998,47 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
m_accelerator->Intersect( blockPacket, hitPacket ); m_accelerator->Intersect( blockPacket, hitPacket );
// Calculate background gradient color // Calculate background gradient color
SFVEC3F bgColor[RAYPACKET_DIM]; SFVEC4F bgColor[RAYPACKET_DIM];
SFVEC4F bgTopColor = premultiplyAlpha( m_boardAdapter.m_BgColorTop );
SFVEC4F bgBotColor = premultiplyAlpha( m_boardAdapter.m_BgColorBot );
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
{ {
const float posYfactor = const float posYfactor =
(float) ( windowsPos.y + y * 4.0f ) / (float) m_windowSize.y; (float) ( windowsPos.y + y * 4.0f ) / (float) m_windowSize.y;
bgColor[y] = (SFVEC3F) m_boardAdapter.m_BgColorTop * SFVEC3F( posYfactor ) bgColor[y] = bgTopColor * SFVEC4F( posYfactor )
+ (SFVEC3F) m_boardAdapter.m_BgColorBot + bgBotColor * ( SFVEC4F( 1.0f ) - SFVEC4F( posYfactor ) );
* ( SFVEC3F( 1.0f ) - SFVEC3F( posYfactor ) );
} }
COLOR_RGB hitColorShading[RAYPACKET_RAYS_PER_PACKET]; COLOR_RGBA hitColorShading[RAYPACKET_RAYS_PER_PACKET];
for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i ) for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
{ {
const SFVEC3F bhColorY = bgColor[i / RAYPACKET_DIM]; const SFVEC4F bhColorY = bgColor[i / RAYPACKET_DIM];
if( hitPacket[i].m_hitresult == true ) if( hitPacket[i].m_hitresult == true )
{ {
const SFVEC3F hitColor = shadeHit( bhColorY, blockPacket.m_ray[i], const SFVEC4F hitColor = shadeHit( bhColorY, blockPacket.m_ray[i],
hitPacket[i].m_HitInfo, false, hitPacket[i].m_HitInfo, false,
0, false ); 0, false );
hitColorShading[i] = COLOR_RGB( hitColor ); hitColorShading[i] = COLOR_RGBA( hitColor );
} }
else else
hitColorShading[i] = bhColorY; hitColorShading[i] = bhColorY;
} }
COLOR_RGB cLRB_old[(RAYPACKET_DIM - 1)]; COLOR_RGBA cLRB_old[(RAYPACKET_DIM - 1)];
for( unsigned int y = 0; y < (RAYPACKET_DIM - 1); ++y ) for( unsigned int y = 0; y < (RAYPACKET_DIM - 1); ++y )
{ {
const SFVEC3F bgColorY = bgColor[y]; const SFVEC4F bgColorY = bgColor[y];
const COLOR_RGB bgColorYRGB = COLOR_RGB( bgColorY ); const COLOR_RGBA bgColorYRGB = COLOR_RGBA( bgColorY );
// This stores cRTB from the last block to be reused next time in a cLTB pixel // This stores cRTB from the last block to be reused next time in a cLTB pixel
COLOR_RGB cRTB_old; COLOR_RGBA cRTB_old;
//RAY cRTB_ray; //RAY cRTB_ray;
//HITINFO cRTB_hitInfo; //HITINFO cRTB_hitInfo;
@ -1040,13 +1061,13 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
const unsigned int iRB = ( ( x + 1 ) + RAYPACKET_DIM * ( y + 1 ) ); const unsigned int iRB = ( ( x + 1 ) + RAYPACKET_DIM * ( y + 1 ) );
// !TODO: skip when there are no hits // !TODO: skip when there are no hits
const COLOR_RGB& cLT = hitColorShading[ iLT ]; const COLOR_RGBA& cLT = hitColorShading[ iLT ];
const COLOR_RGB& cRT = hitColorShading[ iRT ]; const COLOR_RGBA& cRT = hitColorShading[ iRT ];
const COLOR_RGB& cLB = hitColorShading[ iLB ]; const COLOR_RGBA& cLB = hitColorShading[ iLB ];
const COLOR_RGB& cRB = hitColorShading[ iRB ]; const COLOR_RGBA& cRB = hitColorShading[ iRB ];
// Trace and shade cC // Trace and shade cC
COLOR_RGB cC = bgColorYRGB; COLOR_RGBA cC = bgColorYRGB;
const SFVEC3F& oriLT = blockPacket.m_ray[ iLT ].m_Origin; const SFVEC3F& oriLT = blockPacket.m_ray[ iLT ].m_Origin;
const SFVEC3F& oriRB = blockPacket.m_ray[ iRB ].m_Origin; const SFVEC3F& oriRB = blockPacket.m_ray[ iRB ].m_Origin;
@ -1098,7 +1119,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
if( hittedC ) if( hittedC )
{ {
cC = COLOR_RGB( shadeHit( bgColorY, centerRay, centerHitInfo, cC = COLOR_RGBA( shadeHit( bgColorY, centerRay, centerHitInfo,
false, 0, false ) ); false, 0, false ) );
} }
else else
@ -1107,13 +1128,13 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
hittedC = m_accelerator->Intersect( centerRay, centerHitInfo ); hittedC = m_accelerator->Intersect( centerRay, centerHitInfo );
if( hittedC ) if( hittedC )
cC = COLOR_RGB( shadeHit( bgColorY, centerRay, centerHitInfo, cC = COLOR_RGBA( shadeHit( bgColorY, centerRay, centerHitInfo,
false, 0, false ) ); false, 0, false ) );
} }
} }
// Trace and shade cLRT // Trace and shade cLRT
COLOR_RGB cLRT = bgColorYRGB; COLOR_RGBA cLRT = bgColorYRGB;
const SFVEC3F& oriRT = blockPacket.m_ray[ iRT ].m_Origin; const SFVEC3F& oriRT = blockPacket.m_ray[ iRT ].m_Origin;
const SFVEC3F& dirRT = blockPacket.m_ray[ iRT ].m_Dir; const SFVEC3F& dirRT = blockPacket.m_ray[ iRT ].m_Dir;
@ -1139,7 +1160,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal + glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
hitPacket[ iRT ].m_HitInfo.m_HitNormal ) * 0.5f ); hitPacket[ iRT ].m_HitInfo.m_HitNormal ) * 0.5f );
cLRT = COLOR_RGB( shadeHit( bgColorY, rayLRT, hitInfoLRT, false, cLRT = COLOR_RGBA( shadeHit( bgColorY, rayLRT, hitInfoLRT, false,
0, false ) ); 0, false ) );
cLRT = BlendColor( cLRT, BlendColor( cLT, cRT ) ); cLRT = BlendColor( cLRT, BlendColor( cLT, cRT ) );
} }
@ -1164,14 +1185,14 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
nodeRT ); nodeRT );
if( hittedLRT ) if( hittedLRT )
cLRT = COLOR_RGB( shadeHit( bgColorY, rayLRT, hitInfoLRT, cLRT = COLOR_RGBA( shadeHit( bgColorY, rayLRT, hitInfoLRT,
false, 0, false ) ); false, 0, false ) );
else else
{ {
hitInfoLRT.m_tHit = std::numeric_limits<float>::infinity(); hitInfoLRT.m_tHit = std::numeric_limits<float>::infinity();
if( m_accelerator->Intersect( rayLRT,hitInfoLRT ) ) if( m_accelerator->Intersect( rayLRT,hitInfoLRT ) )
cLRT = COLOR_RGB( shadeHit( bgColorY, rayLRT, cLRT = COLOR_RGBA( shadeHit( bgColorY, rayLRT,
hitInfoLRT, false, hitInfoLRT, false,
0, false ) ); 0, false ) );
} }
@ -1184,7 +1205,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
} }
// Trace and shade cLTB // Trace and shade cLTB
COLOR_RGB cLTB = bgColorYRGB; COLOR_RGBA cLTB = bgColorYRGB;
if( x == 0 ) if( x == 0 )
{ {
@ -1209,7 +1230,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
hitInfoLTB.m_HitNormal = hitInfoLTB.m_HitNormal =
glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal + glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
hitPacket[ iLB ].m_HitInfo.m_HitNormal ) * 0.5f ); hitPacket[ iLB ].m_HitInfo.m_HitNormal ) * 0.5f );
cLTB = COLOR_RGB( shadeHit( bgColorY, rayLTB, hitInfoLTB, false, cLTB = COLOR_RGBA( shadeHit( bgColorY, rayLTB, hitInfoLTB, false,
0, false ) ); 0, false ) );
cLTB = BlendColor( cLTB, BlendColor( cLT, cLB) ); cLTB = BlendColor( cLTB, BlendColor( cLT, cLB) );
} }
@ -1234,14 +1255,14 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
nodeLB ); nodeLB );
if( hittedLTB ) if( hittedLTB )
cLTB = COLOR_RGB( shadeHit( bgColorY, rayLTB, hitInfoLTB, cLTB = COLOR_RGBA( shadeHit( bgColorY, rayLTB, hitInfoLTB,
false, 0, false ) ); false, 0, false ) );
else else
{ {
hitInfoLTB.m_tHit = std::numeric_limits<float>::infinity(); hitInfoLTB.m_tHit = std::numeric_limits<float>::infinity();
if( m_accelerator->Intersect( rayLTB, hitInfoLTB ) ) if( m_accelerator->Intersect( rayLTB, hitInfoLTB ) )
cLTB = COLOR_RGB( shadeHit( bgColorY, rayLTB, cLTB = COLOR_RGBA( shadeHit( bgColorY, rayLTB,
hitInfoLTB, false, hitInfoLTB, false,
0, false ) ); 0, false ) );
} }
@ -1254,7 +1275,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
} }
// Trace and shade cRTB // Trace and shade cRTB
COLOR_RGB cRTB = bgColorYRGB; COLOR_RGBA cRTB = bgColorYRGB;
// Trace the center ray // Trace the center ray
RAY rayRTB; RAY rayRTB;
@ -1277,7 +1298,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
glm::normalize( ( hitPacket[ iRT ].m_HitInfo.m_HitNormal + glm::normalize( ( hitPacket[ iRT ].m_HitInfo.m_HitNormal +
hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f ); hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f );
cRTB = COLOR_RGB( shadeHit( bgColorY, rayRTB, hitInfoRTB, false, 0, cRTB = COLOR_RGBA( shadeHit( bgColorY, rayRTB, hitInfoRTB, false, 0,
false ) ); false ) );
cRTB = BlendColor( cRTB, BlendColor( cRT, cRB ) ); cRTB = BlendColor( cRTB, BlendColor( cRT, cRB ) );
} }
@ -1303,7 +1324,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
if( hittedRTB ) if( hittedRTB )
{ {
cRTB = COLOR_RGB( shadeHit( bgColorY, rayRTB, hitInfoRTB, cRTB = COLOR_RGBA( shadeHit( bgColorY, rayRTB, hitInfoRTB,
false, 0, false) ); false, 0, false) );
} }
else else
@ -1311,7 +1332,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity(); hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity();
if( m_accelerator->Intersect( rayRTB, hitInfoRTB ) ) if( m_accelerator->Intersect( rayRTB, hitInfoRTB ) )
cRTB = COLOR_RGB( shadeHit( bgColorY, rayRTB, hitInfoRTB, cRTB = COLOR_RGBA( shadeHit( bgColorY, rayRTB, hitInfoRTB,
false, 0, false ) ); false, 0, false ) );
} }
} }
@ -1320,7 +1341,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
cRTB_old = cRTB; cRTB_old = cRTB;
// Trace and shade cLRB // Trace and shade cLRB
COLOR_RGB cLRB = bgColorYRGB; COLOR_RGBA cLRB = bgColorYRGB;
const SFVEC3F& oriLB = blockPacket.m_ray[ iLB ].m_Origin; const SFVEC3F& oriLB = blockPacket.m_ray[ iLB ].m_Origin;
const SFVEC3F& dirLB = blockPacket.m_ray[ iLB ].m_Dir; const SFVEC3F& dirLB = blockPacket.m_ray[ iLB ].m_Dir;
@ -1346,7 +1367,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
glm::normalize( ( hitPacket[ iLB ].m_HitInfo.m_HitNormal + glm::normalize( ( hitPacket[ iLB ].m_HitInfo.m_HitNormal +
hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f ); hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f );
cLRB = COLOR_RGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0, cLRB = COLOR_RGBA( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0,
false ) ); false ) );
cLRB = BlendColor( cLRB, BlendColor( cLB, cRB ) ); cLRB = BlendColor( cLRB, BlendColor( cLB, cRB ) );
} }
@ -1372,7 +1393,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
if( hittedLRB ) if( hittedLRB )
{ {
cLRB = COLOR_RGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, cLRB = COLOR_RGBA( shadeHit( bgColorY, rayLRB, hitInfoLRB,
false, 0, false ) ); false, 0, false ) );
} }
else else
@ -1380,7 +1401,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity(); hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity();
if( m_accelerator->Intersect( rayLRB, hitInfoLRB ) ) if( m_accelerator->Intersect( rayLRB, hitInfoLRB ) )
cLRB = COLOR_RGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, cLRB = COLOR_RGBA( shadeHit( bgColorY, rayLRB, hitInfoLRB,
false, 0, false ) ); false, 0, false ) );
} }
} }
@ -1389,7 +1410,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
cLRB_old[x] = cLRB; cLRB_old[x] = cLRB;
// Trace and shade cLTC // Trace and shade cLTC
COLOR_RGB cLTC = BlendColor( cLT , cC ); COLOR_RGBA cLTC = BlendColor( cLT , cC );
if( hitPacket[ iLT ].m_hitresult || hittedC ) if( hitPacket[ iLT ].m_hitresult || hittedC )
{ {
@ -1411,12 +1432,12 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
hitInfoLTC ); hitInfoLTC );
if( hitted ) if( hitted )
cLTC = COLOR_RGB( shadeHit( bgColorY, rayLTC, hitInfoLTC, false, cLTC = COLOR_RGBA( shadeHit( bgColorY, rayLTC, hitInfoLTC, false,
0, false ) ); 0, false ) );
} }
// Trace and shade cRTC // Trace and shade cRTC
COLOR_RGB cRTC = BlendColor( cRT , cC ); COLOR_RGBA cRTC = BlendColor( cRT , cC );
if( hitPacket[ iRT ].m_hitresult || hittedC ) if( hitPacket[ iRT ].m_hitresult || hittedC )
{ {
@ -1437,12 +1458,12 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
hitInfoRTC ); hitInfoRTC );
if( hitted ) if( hitted )
cRTC = COLOR_RGB( shadeHit( bgColorY, rayRTC, hitInfoRTC, false, cRTC = COLOR_RGBA( shadeHit( bgColorY, rayRTC, hitInfoRTC, false,
0, false ) ); 0, false ) );
} }
// Trace and shade cLBC // Trace and shade cLBC
COLOR_RGB cLBC = BlendColor( cLB , cC ); COLOR_RGBA cLBC = BlendColor( cLB , cC );
if( hitPacket[ iLB ].m_hitresult || hittedC ) if( hitPacket[ iLB ].m_hitresult || hittedC )
{ {
@ -1463,12 +1484,12 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
hitInfoLBC ); hitInfoLBC );
if( hitted ) if( hitted )
cLBC = COLOR_RGB( shadeHit( bgColorY, rayLBC, hitInfoLBC, false, cLBC = COLOR_RGBA( shadeHit( bgColorY, rayLBC, hitInfoLBC, false,
0, false ) ); 0, false ) );
} }
// Trace and shade cRBC // Trace and shade cRBC
COLOR_RGB cRBC = BlendColor( cRB , cC ); COLOR_RGBA cRBC = BlendColor( cRB , cC );
if( hitPacket[ iRB ].m_hitresult || hittedC ) if( hitPacket[ iRB ].m_hitresult || hittedC )
{ {
@ -1489,7 +1510,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
hitInfoRBC ); hitInfoRBC );
if( hitted ) if( hitted )
cRBC = COLOR_RGB( shadeHit( bgColorY, rayRBC, hitInfoRBC, false, cRBC = COLOR_RGBA( shadeHit( bgColorY, rayRBC, hitInfoRBC, false,
0, false ) ); 0, false ) );
} }
@ -1537,14 +1558,15 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
#define USE_EXPERIMENTAL_SOFT_SHADOWS 1 #define USE_EXPERIMENTAL_SOFT_SHADOWS 1
SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay, HITINFO& aHitInfo, SFVEC4F RENDER_3D_RAYTRACE::shadeHit( const SFVEC4F& aBgColor, const RAY& aRay, HITINFO& aHitInfo,
bool aIsInsideObject, unsigned int aRecursiveLevel, bool aIsInsideObject, unsigned int aRecursiveLevel,
bool is_testShadow ) const bool is_testShadow ) const
{ {
const MATERIAL* objMaterial = aHitInfo.pHitObject->GetMaterial(); const MATERIAL* objMaterial = aHitInfo.pHitObject->GetMaterial();
wxASSERT( objMaterial != nullptr ); wxASSERT( objMaterial != nullptr );
SFVEC3F outColor = objMaterial->GetEmissiveColor() + objMaterial->GetAmbientColor(); SFVEC4F outColor =
SFVEC4F( objMaterial->GetEmissiveColor() + objMaterial->GetAmbientColor(), 1.0f );
if( aRecursiveLevel > 7 ) if( aRecursiveLevel > 7 )
return outColor; return outColor;
@ -1553,7 +1575,8 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
hitPoint += aHitInfo.m_HitNormal * m_boardAdapter.GetNonCopperLayerThickness() * 0.6f; hitPoint += aHitInfo.m_HitNormal * m_boardAdapter.GetNonCopperLayerThickness() * 0.6f;
const SFVEC3F diffuseColorObj = aHitInfo.pHitObject->GetDiffuseColor( aHitInfo ); const SFVEC4F diffuseColorObj =
SFVEC4F( aHitInfo.pHitObject->GetDiffuseColor( aHitInfo ), 1.0f );
#if USE_EXPERIMENTAL_SOFT_SHADOWS #if USE_EXPERIMENTAL_SOFT_SHADOWS
bool is_aa_enabled = m_boardAdapter.m_Cfg->m_Render.raytrace_anti_aliasing && !m_isPreview; bool is_aa_enabled = m_boardAdapter.m_Cfg->m_Render.raytrace_anti_aliasing && !m_isPreview;
@ -1637,8 +1660,10 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
shadow_att_factor_sum += shadow_att_factor_light; shadow_att_factor_sum += shadow_att_factor_light;
} }
outColor += objMaterial->Shade( aRay, aHitInfo, NdotL, diffuseColorObj, vectorToLight, outColor += SFVEC4F( objMaterial->Shade( aRay, aHitInfo, NdotL, diffuseColorObj,
colorOfLight, shadow_att_factor_light ); vectorToLight, colorOfLight,
shadow_att_factor_light ),
1.0 );
} }
// Only use the headlight for preview // Only use the headlight for preview
@ -1658,7 +1683,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
} }
// Clamp color to not be brighter than 1.0f // Clamp color to not be brighter than 1.0f
outColor = glm::min( outColor, SFVEC3F( 1.0f ) ); outColor = glm::min( outColor, SFVEC4F( 1.0f ) );
if( !m_isPreview ) if( !m_isPreview )
{ {
@ -1670,7 +1695,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
const unsigned int reflection_number_of_samples = const unsigned int reflection_number_of_samples =
objMaterial->GetReflectionRayCount(); objMaterial->GetReflectionRayCount();
SFVEC3F sum_color = SFVEC3F( 0.0f ); SFVEC4F sum_color = SFVEC4F( 0.0f );
const SFVEC3F reflectVector = aRay.m_Dir - 2.0f * const SFVEC3F reflectVector = aRay.m_Dir - 2.0f *
glm::dot( aRay.m_Dir, aHitInfo.m_HitNormal ) * aHitInfo.m_HitNormal; glm::dot( aRay.m_Dir, aHitInfo.m_HitNormal ) * aHitInfo.m_HitNormal;
@ -1699,17 +1724,19 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
if( m_accelerator->Intersect( reflectedRay, reflectedHit ) ) if( m_accelerator->Intersect( reflectedRay, reflectedHit ) )
{ {
sum_color += ( diffuseColorObj + objMaterial->GetSpecularColor() ) * SFVEC4F add = ( diffuseColorObj + SFVEC4F( objMaterial->GetSpecularColor(), 1.0f ) ) *
shadeHit( aBgColor, reflectedRay, reflectedHit, false, shadeHit( aBgColor, reflectedRay, reflectedHit, false,
aRecursiveLevel + 1, is_testShadow ) * aRecursiveLevel + 1, is_testShadow ) *
SFVEC3F( objMaterial->GetReflection() * SFVEC4F( objMaterial->GetReflection() *
// Falloff factor // Falloff factor
(1.0f / ( 1.0f + 0.75f * reflectedHit.m_tHit * (1.0f / ( 1.0f + 0.75f * reflectedHit.m_tHit *
reflectedHit.m_tHit) ) ); reflectedHit.m_tHit) ) );
sum_color += add;
} }
} }
outColor += (sum_color / SFVEC3F( (float)reflection_number_of_samples) ); outColor += (sum_color / SFVEC4F( (float)reflection_number_of_samples) );
} }
// Refraction // Refraction
@ -1738,7 +1765,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
const unsigned int refractions_number_of_samples = const unsigned int refractions_number_of_samples =
objMaterial->GetRefractionRayCount(); objMaterial->GetRefractionRayCount();
SFVEC3F sum_color = SFVEC3F(0.0f); SFVEC4F sum_color = SFVEC4F( 0.0f );
for( unsigned int i = 0; i < refractions_number_of_samples; ++i ) for( unsigned int i = 0; i < refractions_number_of_samples; ++i )
{ {
@ -1762,19 +1789,19 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
HITINFO refractedHit; HITINFO refractedHit;
refractedHit.m_tHit = std::numeric_limits<float>::infinity(); refractedHit.m_tHit = std::numeric_limits<float>::infinity();
SFVEC3F refractedColor = aBgColor; SFVEC4F refractedColor = aBgColor;
if( m_accelerator->Intersect( refractedRay, refractedHit ) ) if( m_accelerator->Intersect( refractedRay, refractedHit ) )
{ {
refractedColor = shadeHit( aBgColor, refractedRay, refractedHit, refractedColor = shadeHit( aBgColor, refractedRay, refractedHit,
!aIsInsideObject, aRecursiveLevel + 1, false ); !aIsInsideObject, aRecursiveLevel + 1, false );
const SFVEC3F absorbance = ( SFVEC3F(1.0f) - diffuseColorObj ) * const SFVEC4F absorbance = ( SFVEC4F(1.0f) - diffuseColorObj ) *
(1.0f - objTransparency ) * (1.0f - objTransparency ) *
objMaterial->GetAbsorvance() * objMaterial->GetAbsorvance() *
refractedHit.m_tHit; refractedHit.m_tHit;
const SFVEC3F transparency = 1.0f / ( absorbance + 1.0f ); const SFVEC4F transparency = 1.0f / ( absorbance + 1.0f );
sum_color += refractedColor * transparency; sum_color += refractedColor * transparency;
} }
@ -1785,7 +1812,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
} }
outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * sum_color outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * sum_color
/ SFVEC3F( (float) refractions_number_of_samples ); / SFVEC4F( (float) refractions_number_of_samples );
} }
else else
{ {

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -87,20 +87,20 @@ private:
void postProcessShading( GLubyte* ptrPBO, REPORTER* aStatusReporter ); void postProcessShading( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void postProcessBlurFinish( GLubyte* ptrPBO, REPORTER* aStatusReporter ); void postProcessBlurFinish( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void renderBlockTracing( GLubyte* ptrPBO , signed int iBlock ); void renderBlockTracing( GLubyte* ptrPBO , signed int iBlock );
void renderFinalColor( GLubyte* ptrPBO, const SFVEC3F& rgbColor, void renderFinalColor( GLubyte* ptrPBO, const SFVEC4F& rgbColor,
bool applyColorSpaceConversion ); bool applyColorSpaceConversion );
void renderRayPackets( const SFVEC3F* bgColorY, const RAY* aRayPkt, HITINFO_PACKET* aHitPacket, void renderRayPackets( const SFVEC4F* bgColorY, const RAY* aRayPkt, HITINFO_PACKET* aHitPacket,
bool is_testShadow, SFVEC3F* aOutHitColor ); bool is_testShadow, SFVEC4F* aOutHitColor );
void renderAntiAliasPackets( const SFVEC3F* aBgColorY, const HITINFO_PACKET* aHitPck_X0Y0, void renderAntiAliasPackets( const SFVEC4F* aBgColorY, const HITINFO_PACKET* aHitPck_X0Y0,
const HITINFO_PACKET* aHitPck_AA_X1Y1, const RAY* aRayPck, const HITINFO_PACKET* aHitPck_AA_X1Y1, const RAY* aRayPck,
SFVEC3F* aOutHitColor ); SFVEC4F* aOutHitColor );
// Materials // Materials
void setupMaterials(); void setupMaterials();
SFVEC3F shadeHit( const SFVEC3F& aBgColor, const RAY& aRay, HITINFO& aHitInfo, SFVEC4F shadeHit( const SFVEC4F& aBgColor, const RAY& aRay, HITINFO& aHitInfo,
bool aIsInsideObject, unsigned int aRecursiveLevel, bool aIsInsideObject, unsigned int aRecursiveLevel,
bool is_testShadow ) const; bool is_testShadow ) const;
@ -180,8 +180,8 @@ private:
ACCELERATOR_3D* m_accelerator; ACCELERATOR_3D* m_accelerator;
SFVEC3F m_backgroundColorTop; SFVEC4F m_backgroundColorTop;
SFVEC3F m_backgroundColorBottom; SFVEC4F m_backgroundColorBottom;
///< Used to see if the windows size changed. ///< Used to see if the windows size changed.
wxSize m_oldWindowsSize; wxSize m_oldWindowsSize;
@ -218,8 +218,10 @@ private:
#ifdef USE_SRGB_SPACE #ifdef USE_SRGB_SPACE
extern SFVEC3F ConvertSRGBToLinear( const SFVEC3F& aSRGBcolor ); extern SFVEC3F ConvertSRGBToLinear( const SFVEC3F& aSRGBcolor );
extern SFVEC4F ConvertSRGBAToLinear( const SFVEC4F& aSRGBAcolor );
#else #else
#define ConvertSRGBToLinear( v ) ( v ) #define ConvertSRGBToLinear( v ) ( v )
#define ConvertSRGBAToLinear( v ) ( v )
#endif #endif
#endif // RENDER_3D_RAYTRACE_H #endif // RENDER_3D_RAYTRACE_H

View File

@ -71,7 +71,7 @@ set(3D-VIEWER_SRCS
${DIR_RAY_3D}/triangle_3d.cpp ${DIR_RAY_3D}/triangle_3d.cpp
3d_rendering/buffers_debug.cpp 3d_rendering/buffers_debug.cpp
3d_rendering/render_3d_base.cpp 3d_rendering/render_3d_base.cpp
3d_rendering/color_rgb.cpp 3d_rendering/color_rgba.cpp
3d_rendering/image.cpp 3d_rendering/image.cpp
3d_rendering/post_shader.cpp 3d_rendering/post_shader.cpp
3d_rendering/post_shader_ssao.cpp 3d_rendering/post_shader_ssao.cpp