From 40d5746df680b42404b1bc012403a9e94372e364 Mon Sep 17 00:00:00 2001 From: Mario Luzeiro Date: Tue, 25 Aug 2020 21:33:51 +0100 Subject: [PATCH] 3D-Viewer: Parameterize body board transparency Fix/workarround raytracing render issues related with refraction --- 3d-viewer/3d_canvas/board_adapter.cpp | 7 -- .../c3d_render_ogl_legacy.cpp | 80 ++++++++++--------- .../c3d_render_ogl_legacy.h | 2 + .../c3d_render_createscene.cpp | 7 +- .../c3d_render_raytracing.cpp | 44 +++++----- .../shapes3D/clayeritem.cpp | 14 +++- 3d-viewer/3d_viewer/eda_3d_viewer.cpp | 24 +++--- common/settings/color_settings.cpp | 2 +- 8 files changed, 98 insertions(+), 82 deletions(-) diff --git a/3d-viewer/3d_canvas/board_adapter.cpp b/3d-viewer/3d_canvas/board_adapter.cpp index fb5f502c45..43a7f49270 100644 --- a/3d-viewer/3d_canvas/board_adapter.cpp +++ b/3d-viewer/3d_canvas/board_adapter.cpp @@ -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 ); } diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp index 314b211d76..0c1398d622 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp @@ -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 // ///////////////////////////////////////////////////////////////////////// diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h index a169fdb78f..f49ad51117 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h @@ -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; diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp index 7d292c98e5..c52d92557a 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp @@ -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 ) { diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp index bd8b600b0e..1cad056fbc 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp @@ -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::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; } } } diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/clayeritem.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/clayeritem.cpp index 5fa025822b..f26b94799f 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/clayeritem.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/clayeritem.cpp @@ -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; } diff --git a/3d-viewer/3d_viewer/eda_3d_viewer.cpp b/3d-viewer/3d_viewer/eda_3d_viewer.cpp index a9e47ed37d..1ea0ab5aa3 100644 --- a/3d-viewer/3d_viewer/eda_3d_viewer.cpp +++ b/3d-viewer/3d_viewer/eda_3d_viewer.cpp @@ -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; } diff --git a/common/settings/color_settings.cpp b/common/settings/color_settings.cpp index b98e1e12a6..b402238d04 100644 --- a/common/settings/color_settings.cpp +++ b/common/settings/color_settings.cpp @@ -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 ) );