3D-Viewer: Parameterize body board transparency

Fix/workarround raytracing render issues related with refraction
This commit is contained in:
Mario Luzeiro 2020-08-25 21:33:51 +01:00 committed by Jon Evans
parent 0302fe5570
commit 40d5746df6
8 changed files with 98 additions and 82 deletions

View File

@ -195,13 +195,6 @@ bool BOARD_ADAPTER::Is3DLayerEnabled( PCB_LAYER_ID aLayer ) const
default:
// the layer is an internal copper layer, used the visibility
if( GetFlag( FL_SHOW_BOARD_BODY ) && ( m_render_engine == RENDER_ENGINE::OPENGL_LEGACY ) )
{
// Do not render internal layers if it is overlap with the board
// (on OpenGL render)
return false;
}
return m_board->IsLayerVisible( aLayer );
}

View File

@ -256,8 +256,6 @@ void C3D_RENDER_OGL_LEGACY::setupMaterials()
97.0f / 255.0f,
47.0f / 255.0f );
m_materials.m_EpoxyBoard.m_Diffuse = m_boardAdapter.m_BoardBodyColor;
m_materials.m_EpoxyBoard.m_Specular = SFVEC3F( 18.0f / 255.0f,
3.0f / 255.0f,
20.0f / 255.0f );
@ -303,7 +301,6 @@ void C3D_RENDER_OGL_LEGACY::setupMaterials()
// Epoxy material
m_materials.m_EpoxyBoard.m_Ambient = matAmbientColor;
m_materials.m_EpoxyBoard.m_Diffuse = m_boardAdapter.m_BoardBodyColor;
m_materials.m_EpoxyBoard.m_Specular = matSpecularColor;
m_materials.m_EpoxyBoard.m_Shininess = matShininess;
m_materials.m_EpoxyBoard.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f );
@ -500,6 +497,38 @@ void init_lights(void)
}
void C3D_RENDER_OGL_LEGACY::render_board_body( bool aSkipRenderHoles )
{
if( m_ogl_disp_list_board )
{
m_ogl_disp_list_board->ApplyScalePosition( -m_boardAdapter.GetEpoxyThickness3DU() / 2.0f,
m_boardAdapter.GetEpoxyThickness3DU() );
m_materials.m_EpoxyBoard.m_Diffuse = m_boardAdapter.m_BoardBodyColor;
m_materials.m_EpoxyBoard.m_Transparency = m_boardAdapter.m_BoardBodyColor.a;
OGL_SetMaterial( m_materials.m_EpoxyBoard, 1.0f );
m_ogl_disp_list_board->SetItIsTransparent( true );
if( (m_ogl_disp_list_through_holes_outer_with_npth) && (!aSkipRenderHoles) )
{
m_ogl_disp_list_through_holes_outer_with_npth->ApplyScalePosition(
-m_boardAdapter.GetEpoxyThickness3DU() / 2.0f,
m_boardAdapter.GetEpoxyThickness3DU() );
m_ogl_disp_list_board->DrawAllCameraCulledSubtractLayer(
m_ogl_disp_list_through_holes_outer_with_npth,
NULL );
}
else
{
m_ogl_disp_list_board->DrawAll();
}
}
}
bool C3D_RENDER_OGL_LEGACY::Redraw(
bool aIsMoving, REPORTER* aStatusReporter, REPORTER* aWarningReporter )
{
@ -625,37 +654,6 @@ bool C3D_RENDER_OGL_LEGACY::Redraw(
const bool skipRenderVias = aIsMoving &&
m_boardAdapter.GetFlag( FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE );
// Display board body
// /////////////////////////////////////////////////////////////////////////
if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) )
{
if( m_ogl_disp_list_board )
{
m_ogl_disp_list_board->ApplyScalePosition( -m_boardAdapter.GetEpoxyThickness3DU() / 2.0f,
m_boardAdapter.GetEpoxyThickness3DU() );
OGL_SetMaterial( m_materials.m_EpoxyBoard, 1.0f );
m_ogl_disp_list_board->SetItIsTransparent( false );
if( (m_ogl_disp_list_through_holes_outer_with_npth) && (!skipRenderHoles) )
{
m_ogl_disp_list_through_holes_outer_with_npth->ApplyScalePosition(
-m_boardAdapter.GetEpoxyThickness3DU() / 2.0f,
m_boardAdapter.GetEpoxyThickness3DU() );
m_ogl_disp_list_board->DrawAllCameraCulledSubtractLayer(
m_ogl_disp_list_through_holes_outer_with_npth,
NULL );
}
else
{
m_ogl_disp_list_board->DrawAll();
}
}
}
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
{
// Draw vias and pad holes with copper material
@ -683,15 +681,16 @@ bool C3D_RENDER_OGL_LEGACY::Redraw(
ii != m_ogl_disp_lists_layers.end();
++ii )
{
const PCB_LAYER_ID layer_id = (PCB_LAYER_ID)(ii->first);
// Mask kayers are not processed here because they are a special case
// Mask layers are not processed here because they are a special case
if( (layer_id == B_Mask) || (layer_id == F_Mask) )
continue;
// Do not show inner layers when it is displaying the board
if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) )
// and board body is full opaque
if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) &&
( m_boardAdapter.m_BoardBodyColor.a < 0.01f ) )
{
if( (layer_id > F_Cu) && (layer_id < B_Cu) )
continue;
@ -802,12 +801,17 @@ bool C3D_RENDER_OGL_LEGACY::Redraw(
glPopMatrix();
}
// Render 3D Models (Non-transparent)
// /////////////////////////////////////////////////////////////////////////
render_3D_models( false, false );
render_3D_models( true, false );
// Display board body
// /////////////////////////////////////////////////////////////////////////
if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) )
{
render_board_body( skipRenderHoles );
}
// Display transparent mask layers
// /////////////////////////////////////////////////////////////////////////

View File

@ -150,6 +150,8 @@ private:
bool aDrawMiddleSegments,
bool aSkipRenderHoles );
void render_board_body( bool aSkipRenderHoles );
void get_layer_z_pos( PCB_LAYER_ID aLayerID,
float &aOutZtop,
float &aOutZbot ) const;

View File

@ -168,7 +168,7 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
8.0f / 255.0f,
10.0f / 255.0f ) ), // specular
0.1f * 128.0f, // shiness
0.10f, // transparency
m_boardAdapter.m_BoardBodyColor.a, // transparency
0.0f ); // reflection
m_materials.m_EpoxyBoard.SetAbsorvance( 10.0f );
@ -364,6 +364,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
&m_materials.m_EpoxyBoard,
g_epoxyColor );
#else
CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ),
m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) );
@ -375,6 +376,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
}
else
{
CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D(
object2d_A,
object2d_B,
@ -390,6 +392,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_BoardBodyColor ) );
m_object_container.Add( objPtr );
}
}
@ -974,7 +977,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
}
m_accelerator = 0;
m_accelerator = new CBVH_PBRT( m_object_container );
m_accelerator = new CBVH_PBRT( m_object_container, 8, SPLITMETHOD::MIDDLE );
if( aStatusReporter )
{

View File

@ -1658,21 +1658,20 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
unsigned int aRecursiveLevel,
bool is_testShadow ) const
{
if( aRecursiveLevel > 2 )
return SFVEC3F( 0.0f );
SFVEC3F hitPoint = aHitInfo.m_HitPoint;
if( !m_isPreview )
hitPoint += aHitInfo.m_HitNormal * m_boardAdapter.GetNonCopperLayerThickness3DU() * 0.6f;
const CMATERIAL *objMaterial = aHitInfo.pHitObject->GetMaterial();
wxASSERT( objMaterial != NULL );
const SFVEC3F diffuseColorObj = aHitInfo.pHitObject->GetDiffuseColor( aHitInfo );
SFVEC3F outColor = objMaterial->GetEmissiveColor() + objMaterial->GetAmbientColor();
if( aRecursiveLevel > 5 )
return outColor;
SFVEC3F hitPoint = aHitInfo.m_HitPoint;
hitPoint += aHitInfo.m_HitNormal * m_boardAdapter.GetNonCopperLayerThickness3DU() * 0.6f;
const SFVEC3F diffuseColorObj = aHitInfo.pHitObject->GetDiffuseColor( aHitInfo );
const LIST_LIGHT &lightList = m_lights.GetList();
#if USE_EXPERIMENTAL_SOFT_SHADOWS
@ -1874,9 +1873,7 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
{
// This increase the start point by a "fixed" factor so it will work the
// same for all distances
const SFVEC3F startPoint = aRay.at( NextFloatUp(
NextFloatUp(
NextFloatUp( aHitInfo.m_tHit ) ) ) );
const SFVEC3F startPoint = aRay.at( aHitInfo.m_tHit + m_boardAdapter.GetNonCopperLayerThickness3DU() * 0.25f );
const unsigned int refractions_number_of_samples = objMaterial->GetNrRefractionsSamples();
@ -1904,36 +1901,39 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
HITINFO refractedHit;
refractedHit.m_tHit = std::numeric_limits<float>::infinity();
SFVEC3F refractedColor = objMaterial->GetAmbientColor();
SFVEC3F refractedColor = aBgColor;
if( m_accelerator->Intersect( refractedRay, refractedHit ) )
{
refractedColor = shadeHit( aBgColor,
refractedRay,
refractedHit,
true,
!aIsInsideObject,
aRecursiveLevel + 1,
false );
const SFVEC3F absorbance = ( SFVEC3F(1.0f) - diffuseColorObj ) *
(1.0f - objTransparency ) *
objMaterial->GetAbsorvance() * // Adjust falloff factor
-refractedHit.m_tHit;
refractedHit.m_tHit;
const SFVEC3F transparency = SFVEC3F( expf( absorbance.r ),
expf( absorbance.g ),
expf( absorbance.b ) );
const SFVEC3F transparency = 1.0f / ( absorbance + 1.0f );
sum_color += refractedColor * transparency * objTransparency;
sum_color += refractedColor * transparency;
}
else
{
sum_color += refractedColor * objTransparency;
sum_color += refractedColor;
}
}
outColor = outColor * (1.0f - objTransparency) +
(sum_color / SFVEC3F( (float)refractions_number_of_samples) );
objTransparency * sum_color / SFVEC3F( (float)refractions_number_of_samples);
}
else
{
outColor = outColor * (1.0f - objTransparency) + objTransparency * aBgColor;
}
}
}

View File

@ -45,6 +45,8 @@ CLAYERITEM::CLAYERITEM( const COBJECT2D* aObject2D, float aZMin, float aZMax )
m_bbox.Set( SFVEC3F( bbox2d.Min().x, bbox2d.Min().y, aZMin ),
SFVEC3F( bbox2d.Max().x, bbox2d.Max().y, aZMax ) );
m_bbox.ScaleNextUp();
m_bbox.Scale( 1.0001f );
m_centroid = SFVEC3F( aObject2D->GetCentroid().x,
aObject2D->GetCentroid().y,
(aZMax + aZMin) * 0.5f );
@ -221,6 +223,11 @@ bool CLAYERITEM::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
if( m_object2d->Intersect( raySeg, &tOut, &outNormal ) )
{
if( tOut > 0.99f ) // Workarround for refraction artifacts on board sides
{
return false;
}
// The hitT is a hit value for the segment length 'start' - 'end',
// so it ranges from 0.0 - 1.0. We now convert it to a 3D hit position
// and calculate the real hitT of the ray.
@ -256,8 +263,11 @@ bool CLAYERITEM::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
}
else
{
// Started inside
// Disabled due to refraction artifacts
// this will mostly happen inside the board body
#if 0
// Started inside
const SFVEC3F boxHitPointStart = aRay.at( tBBoxStart );
const SFVEC3F boxHitPointEnd = aRay.at( tBBoxEnd );
@ -317,8 +327,8 @@ bool CLAYERITEM::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
}
}
}
#endif
}
return false;
}

View File

@ -940,18 +940,22 @@ bool EDA_3D_VIEWER::Set3DBoardBodyColorFromUser()
{
CUSTOM_COLORS_LIST colors;
colors.push_back( CUSTOM_COLOR_ITEM( 51/255.0, 43/255.0, 22/255.0, "FR4 natural, dark" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 109/255.0, 116/255.0, 75/255.0, "FR4 natural" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 78/255.0, 14/255.0, 5/255.0, "brown/red" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 146/255.0, 99/255.0, 47/255.0, "brown 1" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 160/255.0, 123/255.0, 54/255.0, "brown 2" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 146/255.0, 99/255.0, 47/255.0, "brown 3" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 63/255.0, 126/255.0, 71/255.0, "green 1" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 117/255.0, 122/255.0, 90/255.0, "green 2" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 51/255.0, 43/255.0, 22/255.0, 1.0 - 0.1, "FR4 natural, dark" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 109/255.0, 116/255.0, 75/255.0, 1.0 - 0.1, "FR4 natural" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 78/255.0, 14/255.0, 5/255.0, 1.0 - 0.1, "brown/red" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 146/255.0, 99/255.0, 47/255.0, 1.0 - 0.1, "brown 1" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 160/255.0, 123/255.0, 54/255.0, 1.0 - 0.1, "brown 2" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 146/255.0, 99/255.0, 47/255.0, 1.0 - 0.1, "brown 3" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 63/255.0, 126/255.0, 71/255.0, 1.0 - 0.1, "green 1" ) );
colors.push_back( CUSTOM_COLOR_ITEM( 117/255.0, 122/255.0, 90/255.0, 1.0 - 0.1, "green 2" ) );
if( Set3DColorFromUser( m_boardAdapter.m_BoardBodyColor, _( "Board Body Color" ), &colors ) )
if( Set3DColorFromUser( m_boardAdapter.m_BoardBodyColor, _( "Board Body Color" ), &colors, true ) )
{
NewDisplay( true );
if( m_boardAdapter.RenderEngineGet() == RENDER_ENGINE::OPENGL_LEGACY )
m_canvas->Request_refresh();
else
NewDisplay( true );
return true;
}

View File

@ -201,7 +201,7 @@ COLOR_SETTINGS::COLOR_SETTINGS( wxString aFilename ) :
// Colors for 3D viewer, which are used as defaults unless overridden by the board
CLR( "3d_viewer.background_bottom", LAYER_3D_BACKGROUND_BOTTOM, COLOR4D( 0.4, 0.4, 0.5, 1.0 ) );
CLR( "3d_viewer.background_top", LAYER_3D_BACKGROUND_TOP, COLOR4D( 0.8, 0.8, 0.9, 1.0 ) );
CLR( "3d_viewer.board", LAYER_3D_BOARD, COLOR4D( 0.2, 0.17, 0.09, 1.0 ) );
CLR( "3d_viewer.board", LAYER_3D_BOARD, COLOR4D( 0.2, 0.17, 0.09, 0.1 ) );
CLR( "3d_viewer.copper", LAYER_3D_COPPER, COLOR4D( 0.7, 0.61, 0.0, 1.0 ) );
CLR( "3d_viewer.silkscreen_bottom", LAYER_3D_SILKSCREEN_BOTTOM, COLOR4D( 0.9, 0.9, 0.9, 1.0 ) );
CLR( "3d_viewer.silkscreen_top", LAYER_3D_SILKSCREEN_TOP, COLOR4D( 0.9, 0.9, 0.9, 1.0 ) );