Improvements on 3DViewer raytracing render

+ Implement sRGB to Linear and Linear to sRGB conversions.
+ Fix an issue in the AntiAliasing adaptive logic.
+ Improves the ambient color use on the shader.
+ Improves post-shader calculation. Fixes the saturated dark regions.
+ Improves the transparency of soldermak material.
This commit is contained in:
Mario Luzeiro 2016-11-26 15:38:51 +01:00 committed by Wayne Stambaugh
parent 2972f6fbc7
commit ad2458056a
8 changed files with 321 additions and 289 deletions

View File

@ -75,10 +75,11 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
// Copper // Copper
m_materials.m_Copper = CBLINN_PHONG_MATERIAL( m_materials.m_Copper = CBLINN_PHONG_MATERIAL(
(SFVEC3F)m_settings.m_CopperColor * (SFVEC3F)(0.18f), // ambient ConvertSRGBToLinear( (SFVEC3F)m_settings.m_CopperColor ) *
(SFVEC3F)(0.18f), // ambient
SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
glm::clamp( ((SFVEC3F)(1.0f) - glm::clamp( ((SFVEC3F)(1.0f) -
(SFVEC3F)m_settings.m_CopperColor), ConvertSRGBToLinear( (SFVEC3F)m_settings.m_CopperColor ) ),
SFVEC3F( 0.0f ), SFVEC3F( 0.0f ),
SFVEC3F( 0.35f ) ), // specular SFVEC3F( 0.35f ) ), // specular
0.4f * 128.0f, // shiness 0.4f * 128.0f, // shiness
@ -88,39 +89,43 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
if( m_settings.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) ) if( m_settings.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
m_materials.m_Copper.SetNormalPerturbator( &m_copper_normal_perturbator ); m_materials.m_Copper.SetNormalPerturbator( &m_copper_normal_perturbator );
m_materials.m_Paste = CBLINN_PHONG_MATERIAL( m_materials.m_Paste = CBLINN_PHONG_MATERIAL(
(SFVEC3F)m_settings.m_SolderPasteColor * ConvertSRGBToLinear( (SFVEC3F)m_settings.m_SolderPasteColor ) *
(SFVEC3F)m_settings.m_SolderPasteColor, // ambient ConvertSRGBToLinear( (SFVEC3F)m_settings.m_SolderPasteColor ), // ambient
SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
(SFVEC3F)m_settings.m_SolderPasteColor * ConvertSRGBToLinear( (SFVEC3F)m_settings.m_SolderPasteColor ) *
(SFVEC3F)m_settings.m_SolderPasteColor, // specular ConvertSRGBToLinear( (SFVEC3F)m_settings.m_SolderPasteColor ), // specular
0.10f * 128.0f, // shiness 0.10f * 128.0f, // shiness
0.0f, // transparency 0.0f, // transparency
0.0f ); 0.0f );
m_materials.m_SilkS = CBLINN_PHONG_MATERIAL( m_materials.m_SilkS = CBLINN_PHONG_MATERIAL(
SFVEC3F( 0.11f ), // ambient ConvertSRGBToLinear( SFVEC3F( 0.11f ) ),// ambient
SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
glm::clamp( ((SFVEC3F)(1.0f) - glm::clamp( ((SFVEC3F)(1.0f) -
(SFVEC3F)m_settings.m_SilkScreenColor), ConvertSRGBToLinear( (SFVEC3F)m_settings.m_SilkScreenColor) ),
SFVEC3F( 0.0f ), SFVEC3F( 0.0f ),
SFVEC3F( 0.10f ) ), // specular SFVEC3F( 0.10f ) ), // specular
0.078125f * 128.0f, // shiness 0.078125f * 128.0f, // shiness
0.0f, // transparency 0.0f, // transparency
0.0f ); 0.0f );
const float solderMask_gray = ( m_settings.m_SolderMaskColor.r +
m_settings.m_SolderMaskColor.g +
m_settings.m_SolderMaskColor.b ) / 3.0f;
const float solderMask_transparency = solderMask_gray * 0.40f + 0.005f;
m_materials.m_SolderMask = CBLINN_PHONG_MATERIAL( m_materials.m_SolderMask = CBLINN_PHONG_MATERIAL(
(SFVEC3F)m_settings.m_SolderMaskColor * ConvertSRGBToLinear( (SFVEC3F)m_settings.m_SolderMaskColor ) *
0.10f, // ambient 0.10f, // ambient
SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
glm::clamp( ( (SFVEC3F)( 1.0f ) - glm::clamp( ( (SFVEC3F)( 1.0f ) -
(SFVEC3F)m_settings.m_SolderMaskColor ), ConvertSRGBToLinear( (SFVEC3F)m_settings.m_SolderMaskColor ) ),
SFVEC3F( 0.0f ), SFVEC3F( 0.0f ),
SFVEC3F( 0.35f ) ), // specular SFVEC3F( solderMask_gray * 2.0f ) ), // specular
0.95f * 128.0f, // shiness 0.85f * 128.0f, // shiness
0.12f, // transparency solderMask_transparency, // transparency
0.16f ); // reflection 0.16f ); // reflection
m_materials.m_SolderMask.SetCastShadows( true ); m_materials.m_SolderMask.SetCastShadows( true );
@ -129,21 +134,21 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
m_materials.m_SolderMask.SetNormalPerturbator( &m_solder_mask_normal_perturbator ); m_materials.m_SolderMask.SetNormalPerturbator( &m_solder_mask_normal_perturbator );
m_materials.m_EpoxyBoard = CBLINN_PHONG_MATERIAL( m_materials.m_EpoxyBoard = CBLINN_PHONG_MATERIAL(
SFVEC3F( 16.0f / 255.0f, ConvertSRGBToLinear( SFVEC3F( 16.0f / 255.0f,
14.0f / 255.0f, 14.0f / 255.0f,
10.0f / 255.0f ), // ambient 10.0f / 255.0f ) ), // ambient
SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
SFVEC3F( 10.0f / 255.0f, ConvertSRGBToLinear( SFVEC3F( 10.0f / 255.0f,
8.0f / 255.0f, 8.0f / 255.0f,
10.0f / 255.0f ), // specular 10.0f / 255.0f ) ), // specular
0.1f * 128.0f, // shiness 0.1f * 128.0f, // shiness
0.10f, // transparency 0.10f, // transparency
0.0f ); // reflection 0.0f ); // reflection
if( m_settings.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) ) if( m_settings.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
m_materials.m_EpoxyBoard.SetNormalPerturbator( &m_board_normal_perturbator ); m_materials.m_EpoxyBoard.SetNormalPerturbator( &m_board_normal_perturbator );
SFVEC3F bgTop = (SFVEC3F)m_settings.m_BgColorTop; SFVEC3F bgTop = ConvertSRGBToLinear( (SFVEC3F)m_settings.m_BgColorTop );
//SFVEC3F bgBot = (SFVEC3F)m_settings.m_BgColorBot; //SFVEC3F bgBot = (SFVEC3F)m_settings.m_BgColorBot;
m_materials.m_Floor = CBLINN_PHONG_MATERIAL( m_materials.m_Floor = CBLINN_PHONG_MATERIAL(
@ -185,7 +190,7 @@ void C3D_RENDER_RAYTRACING::create_3d_object_from( CCONTAINER &aDstContainer,
aObject2D->GetBBox().Max().y, aObject2D->GetBBox().Max().y,
aZMin ) ) ); aZMin ) ) );
objPtr->SetMaterial( aMaterial ); objPtr->SetMaterial( aMaterial );
objPtr->SetColor( aObjColor ); objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
aDstContainer.Add( objPtr ); aDstContainer.Add( objPtr );
objPtr = new CXYPLANE( CBBOX ( SFVEC3F( aObject2D->GetBBox().Min().x, objPtr = new CXYPLANE( CBBOX ( SFVEC3F( aObject2D->GetBBox().Min().x,
@ -195,7 +200,7 @@ void C3D_RENDER_RAYTRACING::create_3d_object_from( CCONTAINER &aDstContainer,
aObject2D->GetBBox().Max().y, aObject2D->GetBBox().Max().y,
aZMax ) ) ); aZMax ) ) );
objPtr->SetMaterial( aMaterial ); objPtr->SetMaterial( aMaterial );
objPtr->SetColor( aObjColor ); objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
aDstContainer.Add( objPtr ); aDstContainer.Add( objPtr );
#else #else
objPtr = new CDUMMYBLOCK( CBBOX ( SFVEC3F( aObject2D->GetBBox().Min().x, objPtr = new CDUMMYBLOCK( CBBOX ( SFVEC3F( aObject2D->GetBBox().Min().x,
@ -217,7 +222,7 @@ void C3D_RENDER_RAYTRACING::create_3d_object_from( CCONTAINER &aDstContainer,
const CROUNDSEGMENT2D *aRoundSeg2D = static_cast<const CROUNDSEGMENT2D *>( aObject2D ); const CROUNDSEGMENT2D *aRoundSeg2D = static_cast<const CROUNDSEGMENT2D *>( aObject2D );
CROUNDSEG *objPtr = new CROUNDSEG( *aRoundSeg2D, aZMin, aZMax ); CROUNDSEG *objPtr = new CROUNDSEG( *aRoundSeg2D, aZMin, aZMax );
objPtr->SetMaterial( aMaterial ); objPtr->SetMaterial( aMaterial );
objPtr->SetColor( aObjColor ); objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
aDstContainer.Add( objPtr ); aDstContainer.Add( objPtr );
} }
break; break;
@ -227,7 +232,7 @@ void C3D_RENDER_RAYTRACING::create_3d_object_from( CCONTAINER &aDstContainer,
{ {
CLAYERITEM *objPtr = new CLAYERITEM( aObject2D, aZMin, aZMax ); CLAYERITEM *objPtr = new CLAYERITEM( aObject2D, aZMin, aZMax );
objPtr->SetMaterial( aMaterial ); objPtr->SetMaterial( aMaterial );
objPtr->SetColor( aObjColor ); objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
aDstContainer.Add( objPtr ); aDstContainer.Add( objPtr );
} }
break; break;
@ -351,7 +356,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
m_settings.GetLayerBottomZpos3DU( B_Cu ) ); m_settings.GetLayerBottomZpos3DU( B_Cu ) );
objPtr->SetMaterial( &m_materials.m_EpoxyBoard ); objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
objPtr->SetColor( (SFVEC3F)m_settings.m_BoardBodyColor ); objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_settings.m_BoardBodyColor ) );
m_object_container.Add( objPtr ); m_object_container.Add( objPtr );
#endif #endif
} }
@ -370,7 +375,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
m_settings.GetLayerBottomZpos3DU( B_Cu ) ); m_settings.GetLayerBottomZpos3DU( B_Cu ) );
objPtr->SetMaterial( &m_materials.m_EpoxyBoard ); objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
objPtr->SetColor( (SFVEC3F)m_settings.m_BoardBodyColor ); objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_settings.m_BoardBodyColor ) );
m_object_container.Add( objPtr ); m_object_container.Add( objPtr );
} }
} }
@ -405,7 +410,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
radius ); radius );
objPtr->SetMaterial( &m_materials.m_EpoxyBoard ); objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
objPtr->SetColor( (SFVEC3F)m_settings.m_BoardBodyColor ); objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_settings.m_BoardBodyColor ) );
m_object_container.Add( objPtr ); m_object_container.Add( objPtr );
} }
@ -590,7 +595,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
m_settings.GetLayerBottomZpos3DU( layer_id ), m_settings.GetLayerBottomZpos3DU( layer_id ),
m_settings.GetLayerTopZpos3DU( layer_id ) ); m_settings.GetLayerTopZpos3DU( layer_id ) );
objPtr->SetMaterial( materialLayer ); objPtr->SetMaterial( materialLayer );
objPtr->SetColor( layerColor ); objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
m_object_container.Add( objPtr ); m_object_container.Add( objPtr );
#endif #endif
} }
@ -608,7 +613,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
m_settings.GetLayerTopZpos3DU( layer_id ) ); m_settings.GetLayerTopZpos3DU( layer_id ) );
objPtr->SetMaterial( materialLayer ); objPtr->SetMaterial( materialLayer );
objPtr->SetColor( layerColor ); objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
m_object_container.Add( objPtr ); m_object_container.Add( objPtr );
#endif #endif
@ -732,7 +737,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
zLayerMax ); zLayerMax );
objPtr->SetMaterial( materialLayer ); objPtr->SetMaterial( materialLayer );
objPtr->SetColor( layerColor ); objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
m_object_container.Add( objPtr ); m_object_container.Add( objPtr );
#endif #endif
@ -750,7 +755,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
zLayerMin, zLayerMin,
zLayerMax ); zLayerMax );
objPtr->SetMaterial( materialLayer ); objPtr->SetMaterial( materialLayer );
objPtr->SetColor( layerColor ); objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
m_object_container.Add( objPtr ); m_object_container.Add( objPtr );
} }
@ -820,8 +825,8 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
newTriangle1->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor ); newTriangle1->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
newTriangle2->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor ); newTriangle2->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
newTriangle1->SetColor( (SFVEC3F)m_settings.m_BgColorTop ); newTriangle1->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_settings.m_BgColorTop ) );
newTriangle2->SetColor( (SFVEC3F)m_settings.m_BgColorTop ); newTriangle2->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_settings.m_BgColorTop ) );
} }
} }
} }
@ -832,8 +837,8 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
m_lights.Clear(); m_lights.Clear();
// This will work as the front camera light. // This will work as the front camera light.
const float light_camera_intensity = 0.15; const float light_camera_intensity = 0.20;
const float light_top_bottom = 0.70; const float light_top_bottom = 0.25;
const float light_directional_intensity = ( 1.0f - ( light_camera_intensity + const float light_directional_intensity = ( 1.0f - ( light_camera_intensity +
light_top_bottom * 0.5f ) ) / 4.0f; light_top_bottom * 0.5f ) ) / 4.0f;
@ -988,9 +993,9 @@ void C3D_RENDER_RAYTRACING::insert3DViaHole( const VIA* aVia )
objPtr->SetMaterial( &m_materials.m_Copper ); objPtr->SetMaterial( &m_materials.m_Copper );
if( m_settings.GetFlag( FL_USE_REALISTIC_MODE ) ) if( m_settings.GetFlag( FL_USE_REALISTIC_MODE ) )
objPtr->SetColor( (SFVEC3F)m_settings.m_CopperColor ); objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_settings.m_CopperColor ) );
else else
objPtr->SetColor( m_settings.GetItemColor( VIAS_VISIBLE + aVia->GetViaType() ) ); objPtr->SetColor( ConvertSRGBToLinear( m_settings.GetItemColor( VIAS_VISIBLE + aVia->GetViaType() ) ) );
m_object_container.Add( objPtr ); m_object_container.Add( objPtr );
} }
@ -1132,7 +1137,7 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const D_PAD* aPad )
CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, topZ, botZ ); CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, topZ, botZ );
objPtr->SetMaterial( &m_materials.m_Copper ); objPtr->SetMaterial( &m_materials.m_Copper );
objPtr->SetColor( objColor ); objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
m_object_container.Add( objPtr ); m_object_container.Add( objPtr );
} }
else else
@ -1147,7 +1152,7 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const D_PAD* aPad )
CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, topZ, botZ ); CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, topZ, botZ );
objPtr->SetMaterial( &m_materials.m_Copper ); objPtr->SetMaterial( &m_materials.m_Copper );
objPtr->SetColor( objColor ); objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
m_object_container.Add( objPtr ); m_object_container.Add( objPtr );
} }
@ -1345,10 +1350,32 @@ void C3D_RENDER_RAYTRACING::add_3D_models( const S3DMODEL *a3DModel,
CBLINN_PHONG_MATERIAL &blinnMaterial = (*materialVector)[imat]; CBLINN_PHONG_MATERIAL &blinnMaterial = (*materialVector)[imat];
SFVEC3F ambient;
if( m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
{
// apply a gain to the (dark) ambient colors
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMi4wMCkpLTAuMzUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjI0OTUwNTMzOTIyMzYyIiwiMS42Nzc4MzQ0MTg1NjcxODQzIiwiLTAuNDM1NTA0NjQyODEwOTMwMjYiLCIxLjM2NTkzNTIwODEzNzI1OCJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
// ambient = glm::max( (glm::pow((material.m_Ambient + 0.20f), SFVEC3F(1.0f / 2.00f)) - SFVEC3F(0.35f)), material.m_Ambient );
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMS41OCkpLTAuMzUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjI0OTUwNTMzOTIyMzYyIiwiMS42Nzc4MzQ0MTg1NjcxODQzIiwiLTAuNDM1NTA0NjQyODEwOTMwMjYiLCIxLjM2NTkzNTIwODEzNzI1OCJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
//ambient = glm::max( (glm::pow((material.m_Ambient + 0.20f), SFVEC3F(1.0f / 1.58f)) - SFVEC3F(0.35f)), material.m_Ambient );
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMS41NCkpLTAuMzQiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0yLjcyMTA5NTg0MjA1MDYwNSIsIjEuODUyODcyNTI5NDk3NTIyMyIsIi0xLjQyMTM3NjAxOTkyOTA4MDYiLCIxLjM5MzM3Mzc0NzE3NzQ2MTIiXSwic2l6ZSI6WzY0OSwzOTldfV0-
ambient = ConvertSRGBToLinear(
glm::pow((material.m_Ambient + 0.30f), SFVEC3F(1.0f / 1.54f)) - SFVEC3F(0.34f) );
}
else
{
ambient = ConvertSRGBToLinear( material.m_Ambient );
}
blinnMaterial = CBLINN_PHONG_MATERIAL( blinnMaterial = CBLINN_PHONG_MATERIAL(
material.m_Ambient, ambient,
material.m_Emissive, ConvertSRGBToLinear( material.m_Emissive ),
material.m_Specular, ConvertSRGBToLinear( material.m_Specular ),
material.m_Shininess * 180.0f, material.m_Shininess * 180.0f,
material.m_Transparency, material.m_Transparency,
reflectionFactor ); reflectionFactor );
@ -1485,21 +1512,20 @@ void C3D_RENDER_RAYTRACING::add_3D_models( const S3DMODEL *a3DModel,
a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse; a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse;
if( m_settings.MaterialModeGet() == MATERIAL_MODE_CAD_MODE ) if( m_settings.MaterialModeGet() == MATERIAL_MODE_CAD_MODE )
newTriangle->SetColor( MaterialDiffuseToColorCAD( diffuseColor ) ); newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( diffuseColor ) ) );
else else
newTriangle->SetColor( diffuseColor ); newTriangle->SetColor( ConvertSRGBToLinear( diffuseColor ) );
} }
else else
{ {
if( m_settings.MaterialModeGet() == MATERIAL_MODE_CAD_MODE ) if( m_settings.MaterialModeGet() == MATERIAL_MODE_CAD_MODE )
newTriangle->SetColor( newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx0] ) ),
MaterialDiffuseToColorCAD( mesh.m_Color[idx0] ), ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx1] ) ),
MaterialDiffuseToColorCAD( mesh.m_Color[idx1] ), ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx2] ) ) );
MaterialDiffuseToColorCAD( mesh.m_Color[idx2] ) );
else else
newTriangle->SetColor( mesh.m_Color[idx0], newTriangle->SetColor( ConvertSRGBToLinear( mesh.m_Color[idx0] ),
mesh.m_Color[idx1], ConvertSRGBToLinear( mesh.m_Color[idx1] ),
mesh.m_Color[idx2] ); ConvertSRGBToLinear( mesh.m_Color[idx2] ) );
} }
} }
} }

View File

@ -319,6 +319,9 @@ void C3D_RENDER_RAYTRACING::render( GLubyte *ptrPBO , REPORTER *aStatusTextRepor
tmp_ptrPBO += 4; // PBO is RGBA tmp_ptrPBO += 4; // PBO is RGBA
} }
} }
m_BgColorTop_LinearRGB = ConvertSRGBToLinear( (SFVEC3F)m_settings.m_BgColorTop );
m_BgColorBot_LinearRGB = ConvertSRGBToLinear( (SFVEC3F)m_settings.m_BgColorBot );
} }
switch( m_rt_render_state ) switch( m_rt_render_state )
@ -422,17 +425,18 @@ void C3D_RENDER_RAYTRACING::rt_render_tracing( GLubyte *ptrPBO ,
} }
} }
#define USE_SRGB_SPACE
#ifdef USE_SRGB_SPACE #ifdef USE_SRGB_SPACE
// This should be removed in future when the KiCad support a greater version of // This should be removed in future when the KiCad support a greater version of
// glm lib. // glm lib.
#define SRGB_GAMA 2.4f
// This function implements the conversion from linear RGB to sRGB // This function implements the conversion from linear RGB to sRGB
// https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L12 // https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L12
static SFVEC3F convertLinearToSRGB( const SFVEC3F &aRGBcolor ) static SFVEC3F convertLinearToSRGB( const SFVEC3F &aRGBcolor )
{ {
const float gammaCorrection = 1.0f / 1.3f; const float gammaCorrection = 1.0f / SRGB_GAMA;
const SFVEC3F clampedColor = glm::clamp( aRGBcolor, SFVEC3F(0.0f), SFVEC3F(1.0f) ); const SFVEC3F clampedColor = glm::clamp( aRGBcolor, SFVEC3F(0.0f), SFVEC3F(1.0f) );
return glm::mix( return glm::mix(
@ -440,6 +444,20 @@ static SFVEC3F convertLinearToSRGB( const SFVEC3F &aRGBcolor )
clampedColor * 12.92f, clampedColor * 12.92f,
glm::lessThan( clampedColor, SFVEC3F(0.0031308f) ) ); glm::lessThan( clampedColor, SFVEC3F(0.0031308f) ) );
} }
// 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) ) );
}
#endif #endif
void C3D_RENDER_RAYTRACING::rt_final_color( GLubyte *ptrPBO, void C3D_RENDER_RAYTRACING::rt_final_color( GLubyte *ptrPBO,
@ -515,10 +533,7 @@ void C3D_RENDER_RAYTRACING::rt_trace_AA_packet( const SFVEC3F *aBgColorY,
const RAY *aRayPck, const RAY *aRayPck,
SFVEC3F *aOutHitColor ) SFVEC3F *aOutHitColor )
{ {
// If post processing is using, do not calculate shadows as they will not be const bool is_testShadow = m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS );
// used for futher post processing.
const bool is_testShadow = m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ) &&
!m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING );
for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y ) for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
{ {
@ -556,9 +571,9 @@ void C3D_RENDER_RAYTRACING::rt_trace_AA_packet( const SFVEC3F *aBgColorY,
nodex1y1 = aHitPck_X0Y0[ idx1y1 ].m_HitInfo.m_acc_node_info; nodex1y1 = aHitPck_X0Y0[ idx1y1 ].m_HitInfo.m_acc_node_info;
if( (nodex0y0 == nodex1y0) && // If all notes are equal we assume there was no change on the object hits if( ((nodex0y0 == nodex1y0) || (nodex1y0 == 0)) && // If all notes are equal we assume there was no change on the object hits
(nodex0y0 == nodex0y1) && ((nodex0y0 == nodex0y1) || (nodex0y1 == 0)) &&
(nodex0y0 == nodex1y1) && ((nodex0y0 == nodex1y1) || (nodex1y1 == 0)) &&
(nodex0y0 == node_AA_x0y0) ) (nodex0y0 == node_AA_x0y0) )
{ {
// Option 1 // Option 1
@ -583,6 +598,9 @@ void C3D_RENDER_RAYTRACING::rt_trace_AA_packet( const SFVEC3F *aBgColorY,
//if( m_accelerator->Intersect( rayAA, hitAA, nodex0y0 ) ) //if( m_accelerator->Intersect( rayAA, hitAA, nodex0y0 ) )
// aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 ); // aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 );
// Option 3
// Use same color
} }
else else
{ {
@ -662,8 +680,8 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
{ {
const float posYfactor = (float)(blockPosI.y + y) / (float)m_windowSize.y; const float posYfactor = (float)(blockPosI.y + y) / (float)m_windowSize.y;
bgColor[y] = (SFVEC3F)m_settings.m_BgColorTop * SFVEC3F(posYfactor) + bgColor[y] = m_BgColorTop_LinearRGB * SFVEC3F(posYfactor) +
(SFVEC3F)m_settings.m_BgColorBot * ( SFVEC3F(1.0f) - SFVEC3F(posYfactor) ); m_BgColorBot_LinearRGB * ( SFVEC3F(1.0f) - SFVEC3F(posYfactor) );
} }
// Intersect ray packets (calculate the intersection with rays and objects) // Intersect ray packets (calculate the intersection with rays and objects)
@ -764,8 +782,7 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
rt_shades_packet( bgColor, rt_shades_packet( bgColor,
blockPacket_AA_X1Y1.m_ray, blockPacket_AA_X1Y1.m_ray,
hitPacket_AA_X1Y1, hitPacket_AA_X1Y1,
m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ) && m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ),
(!m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING )),
hitColor_AA_X1Y1 hitColor_AA_X1Y1
); );
} }
@ -1033,32 +1050,13 @@ void C3D_RENDER_RAYTRACING::rt_render_post_process_blur_finish( GLubyte *ptrPBO,
ptrShaderY3-= 3; ptrShaderY3-= 3;
ptrShaderY4-= 3; ptrShaderY4-= 3;
const float grayBluredColor = ( bluredShadeColor.r + #ifdef USE_SRGB_SPACE
bluredShadeColor.g + const SFVEC3F originColor = convertLinearToSRGB( m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x,y ) ) );
bluredShadeColor.b ) / 3.0f; #else
const SFVEC3F originColor = m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x,y ) );
#endif
const SFVEC3F &originalColor = m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x, y ) ); const SFVEC3F shadedColor = m_postshader_ssao.ApplyShadeColor( SFVEC2I( x,y ), originColor, bluredShadeColor );
float luminanceColor = (originalColor.r * 0.2126f +
originalColor.g * 0.7152f +
originalColor.b * 0.0722f);
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoeCoxLjMtMC4xNSkqKC14KjEuMysyLjE1KSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjQ5MjM4OTg5MzY5NjAyNCIsIjIuMTY2Nzg0ODAzNTQyNDk4IiwiLTAuNjYzNzYwNzIzNzUyMjA5NSIsIjEuNTg4MDM5MDg5OTMzMDM0NiJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
// luminanceColor = (+luminanceColor * 1.3f - 0.15f) *
// (-luminanceColor * 1.3f + 2.15f);
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoeC0wLjEpKjkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC45OTI5NjA0NzE5OTg5Njk1IiwiMS45MzQzNzkyODU3OTE4NDYzIiwiLTAuNDE1MTAzMzMwNzkyMzc5NyIsIjEuMzg2MzM2NTIwMTU1ODE0MiJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
luminanceColor = (luminanceColor - 0.10f) * 9.0f;
luminanceColor = glm::clamp( luminanceColor, 0.0f, 1.0f );
const SFVEC3F shadedColor = ( originalColor *
( SFVEC3F(1.0f) - 2.0f * bluredShadeColor * luminanceColor ) ) -
( bluredShadeColor - (grayBluredColor * 0.65f) );
// Debug code
//const SFVEC3F shadedColor = bluredShadeColor;
//const SFVEC3F shadedColor = SFVEC3F(grayOriginalColorFactor);
#else #else
// Debug code // Debug code
//const SFVEC3F shadedColor = SFVEC3F( 1.0f ) - //const SFVEC3F shadedColor = SFVEC3F( 1.0f ) -
@ -1066,7 +1064,7 @@ void C3D_RENDER_RAYTRACING::rt_render_post_process_blur_finish( GLubyte *ptrPBO,
const SFVEC3F shadedColor = m_shaderBuffer[ y * m_realBufferSize.x + x ]; const SFVEC3F shadedColor = m_shaderBuffer[ y * m_realBufferSize.x + x ];
#endif #endif
rt_final_color( ptr, shadedColor, true ); rt_final_color( ptr, shadedColor, false );
ptr += 4; ptr += 4;
} }
@ -1714,9 +1712,7 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
SFVEC3F hitPoint = aHitInfo.m_HitPoint; SFVEC3F hitPoint = aHitInfo.m_HitPoint;
if( !m_isPreview ) if( !m_isPreview )
hitPoint += aHitInfo.m_HitNormal * ( 0.5f * m_settings.GetNonCopperLayerThickness3DU() * hitPoint += aHitInfo.m_HitNormal * m_settings.GetNonCopperLayerThickness3DU() * 1.0f;
glm::abs(Fast_RandFloat()) +
0.5f * m_settings.GetNonCopperLayerThickness3DU() );
const CMATERIAL *objMaterial = aHitInfo.pHitObject->GetMaterial(); const CMATERIAL *objMaterial = aHitInfo.pHitObject->GetMaterial();
wxASSERT( objMaterial != NULL ); wxASSERT( objMaterial != NULL );
@ -1765,7 +1761,7 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
// otherwise it is in the shadow // otherwise it is in the shadow
if( NdotL >= FLT_EPSILON ) if( NdotL >= FLT_EPSILON )
{ {
float shadow_att_factor_light = 1.0f; float shadow_att_factor_light = 1.0f;
if( is_testShadow && light->GetCastShadows() ) if( is_testShadow && light->GetCastShadows() )
{ {
@ -1796,10 +1792,10 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
else else
{ {
const unsigned int shadow_number_of_samples = 2; const unsigned int shadow_number_of_samples = 3;
const float shadow_inc_factor = 1.0f / (float)(shadow_number_of_samples); const float shadow_inc_factor = 1.0f / (float)(shadow_number_of_samples);
for( unsigned int i=0; i < shadow_number_of_samples; ++i ) for( unsigned int i = 0; i < shadow_number_of_samples; ++i )
{ {
const SFVEC3F unifVector = UniformRandomHemisphereDirection(); const SFVEC3F unifVector = UniformRandomHemisphereDirection();
const SFVEC3F disturbed_vector_to_light = glm::normalize( vectorToLight + const SFVEC3F disturbed_vector_to_light = glm::normalize( vectorToLight +
@ -1835,8 +1831,8 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
} }
else else
{ {
// This is a render hack in order to compensate for the lake of // This is a render hack in order to compensate for the lack of
// ambient and too much darkness when using post process shadeer // ambient and too much darkness when using post process shader
// It will calculate as it was not in shadow // It will calculate as it was not in shadow
outColor += objMaterial->Shade( aRay, outColor += objMaterial->Shade( aRay,
aHitInfo, aHitInfo,
@ -1844,19 +1840,16 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
diffuseColorObj, diffuseColorObj,
vectorToLight, vectorToLight,
colorOfLight, colorOfLight,
1.0f ); // The sampled point will be darkshaded by the post
// processing, so here it compensates to not shadow
// so much
glm::min( shadow_att_factor_light + (3.0f / 6.0f), 1.0f )
);
} }
} }
// Improvement: this is not taking in account the lightcolor
if( nr_lights_that_can_cast_shadows > 0 )
{
aHitInfo.m_ShadowFactor = shadow_att_factor_sum /
(float)(nr_lights_that_can_cast_shadows * 1.0f);
}
else else
{ {
aHitInfo.m_ShadowFactor = 1.0f; outColor += objMaterial->GetAmbientColor();
} }
// Only use the headlight for preview // Only use the headlight for preview
@ -1864,6 +1857,17 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
break; break;
} }
// Improvement: this is not taking in account the lightcolor
if( nr_lights_that_can_cast_shadows > 0 )
{
aHitInfo.m_ShadowFactor = shadow_att_factor_sum /
(float)(nr_lights_that_can_cast_shadows * 1.0f);
}
else
{
aHitInfo.m_ShadowFactor = 1.0f;
}
// 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, SFVEC3F( 1.0f ) );

View File

@ -153,6 +153,8 @@ private:
CGENERICACCELERATOR *m_accelerator; CGENERICACCELERATOR *m_accelerator;
SFVEC3F m_BgColorTop_LinearRGB;
SFVEC3F m_BgColorBot_LinearRGB;
// Morton codes // Morton codes
@ -205,4 +207,12 @@ private:
void render_preview( GLubyte *ptrPBO ); void render_preview( GLubyte *ptrPBO );
}; };
#define USE_SRGB_SPACE
#ifdef USE_SRGB_SPACE
extern SFVEC3F ConvertSRGBToLinear( const SFVEC3F &aSRGBcolor );
#else
#define ConvertSRGBToLinear(v) (v)
#endif
#endif // C3D_RENDER_RAYTRACING_H #endif // C3D_RENDER_RAYTRACING_H

View File

@ -31,6 +31,10 @@
#include <3d_math.h> #include <3d_math.h>
#include <wx/debug.h> #include <wx/debug.h>
// This may be a good value if based on nr of lights
// that contribute to the illumination of that point
#define AMBIENT_FACTOR (1.0f / 6.0f)
#define SPECULAR_FACTOR 1.0f
CMATERIAL::CMATERIAL() CMATERIAL::CMATERIAL()
{ {
@ -62,7 +66,8 @@ CMATERIAL::CMATERIAL( const SFVEC3F &aAmbient,
wxASSERT( aShinness >= 0.0f ); wxASSERT( aShinness >= 0.0f );
wxASSERT( aShinness <= 180.0f ); wxASSERT( aShinness <= 180.0f );
m_ambientColor = aAmbient; m_ambientColor = aAmbient * SFVEC3F(AMBIENT_FACTOR);
m_emissiveColor = aEmissive; m_emissiveColor = aEmissive;
m_specularColor = aSpecular; m_specularColor = aSpecular;
m_shinness = aShinness; m_shinness = aShinness;
@ -85,10 +90,6 @@ void CMATERIAL::PerturbeNormal( SFVEC3F &aNormal,
} }
} }
// This may be a good value if based on nr of lights
// that contribute to the illumination of that point
#define AMBIENT_FACTOR (1.0f / 6.0f)
#define SPECULAR_FACTOR 1.0f
// https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model // https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model
SFVEC3F CBLINN_PHONG_MATERIAL::Shade( const RAY &aRay, SFVEC3F CBLINN_PHONG_MATERIAL::Shade( const RAY &aRay,
@ -101,8 +102,6 @@ SFVEC3F CBLINN_PHONG_MATERIAL::Shade( const RAY &aRay,
{ {
wxASSERT( NdotL >= FLT_EPSILON ); wxASSERT( NdotL >= FLT_EPSILON );
const float ambientFactor = AMBIENT_FACTOR;
// This is a hack to get some kind of fake ambient illumination // This is a hack to get some kind of fake ambient illumination
// There is no logic behind this, just pure artistic experimentation // There is no logic behind this, just pure artistic experimentation
//const float ambientFactor = glm::max( ( (1.0f - NdotL) /** (1.0f - NdotL)*/ ) * //const float ambientFactor = glm::max( ( (1.0f - NdotL) /** (1.0f - NdotL)*/ ) *
@ -123,7 +122,7 @@ SFVEC3F CBLINN_PHONG_MATERIAL::Shade( const RAY &aRay,
const float intensitySpecular = glm::pow( glm::max( NdotH, 0.0f ), const float intensitySpecular = glm::pow( glm::max( NdotH, 0.0f ),
m_shinness ); m_shinness );
return m_ambientColor * ambientFactor + return m_ambientColor +
aShadowAttenuationFactor * ( diffuse * aDiffuseObjColor + aShadowAttenuationFactor * ( diffuse * aDiffuseObjColor +
SPECULAR_FACTOR * SPECULAR_FACTOR *
aLightColor * aLightColor *
@ -131,7 +130,7 @@ SFVEC3F CBLINN_PHONG_MATERIAL::Shade( const RAY &aRay,
m_specularColor ); m_specularColor );
} }
return m_ambientColor * ambientFactor; return m_ambientColor;
} }
@ -222,21 +221,21 @@ CPLASTICNORMAL::CPLASTICNORMAL( float aScale )
SFVEC3F CPLASTICNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const SFVEC3F CPLASTICNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{ {
SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale; const SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
const float noise1 = (m_perlin.noise( hitPos.x, const float noise1 = (m_perlin.noise( hitPos.x * 0.1f,
hitPos.y, hitPos.y * 0.1f,
hitPos.z ) - 0.5f); hitPos.z * 0.1f) - 0.5f);
const float noise2 = (m_perlin.noise( hitPos.x * 5.0f, const float noise2 = (m_perlin.noise( hitPos.x * 4.0f,
hitPos.y * 5.0f, hitPos.y * 4.0f,
hitPos.z * 5.0f ) - 0.5f); hitPos.z * 4.0f ) - 0.5f);
const float noise3 = (m_perlin.noise( hitPos.x * 10.0f + Fast_RandFloat() * 0.10f, const float noise3 = (m_perlin.noise( hitPos.x * 8.0f + Fast_RandFloat() * 0.10f,
hitPos.y * 10.0f + Fast_RandFloat() * 0.10f, hitPos.y * 8.0f + Fast_RandFloat() * 0.10f,
hitPos.z * 10.0f + Fast_RandFloat() * 0.10f ) - 0.5f); hitPos.z * 8.0f + Fast_RandFloat() * 0.10f ) - 0.5f);
return SFVEC3F( noise1 * 0.08f + noise2 * 0.10f + noise3 * 0.30f ); return SFVEC3F( noise1 * 0.30f + noise2 * 0.50f + noise3 * 0.80f );
} }
@ -248,17 +247,17 @@ CPLASTICSHINENORMAL::CPLASTICSHINENORMAL( float aScale )
SFVEC3F CPLASTICSHINENORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const SFVEC3F CPLASTICSHINENORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{ {
SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale; const SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
const float noise1 = (m_perlin.noise( hitPos.x, const float noise1 = (m_perlin.noise( hitPos.x * 0.15f,
hitPos.y, hitPos.y * 0.15f,
hitPos.z ) - 0.5f); hitPos.z * 0.15f ) - 0.5f);
const float noise2 = (m_perlin.noise( hitPos.x * 3.0f, const float noise2 = (m_perlin.noise( hitPos.x * 0.5f,
hitPos.y * 3.0f, hitPos.y * 0.5f,
hitPos.z * 3.0f ) - 0.5f); hitPos.z * 0.5f ) - 0.5f);
return SFVEC3F( noise1 * 0.09f + noise2 * 0.08f ); return SFVEC3F( noise1 * 1.0f, noise2 * 1.0f, noise1 * noise2 );
} }
@ -303,10 +302,10 @@ SFVEC3F CMETALBRUSHEDNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo
float sawY = (hitPosRelative.y + glm::sin(10.0f * hitPos.y + 5.0f * noise2 + Fast_RandFloat() ) ); float sawY = (hitPosRelative.y + glm::sin(10.0f * hitPos.y + 5.0f * noise2 + Fast_RandFloat() ) );
sawY = sawY * sawY * sawY; sawY = sawY * sawY * sawY;
float xOut = sawX * noise3X * 0.07f + noiseX * 0.25f + noise3X * 0.07f; float xOut = sawX * noise3X * 0.17f + noiseX * 0.25f + noise3X * 0.57f;
float yOut = sawY * noise3Y * 0.07f + noiseY * 0.25f + noise3Y * 0.07f; float yOut = sawY * noise3Y * 0.17f + noiseY * 0.25f + noise3Y * 0.57f;
const float outLowFreqNoise = noise2 * 0.005f; const float outLowFreqNoise = noise2 * 0.05f;
return SFVEC3F( xOut + outLowFreqNoise, return SFVEC3F( xOut + outLowFreqNoise,
yOut + outLowFreqNoise, yOut + outLowFreqNoise,

View File

@ -40,6 +40,13 @@ public:
virtual SFVEC3F Shade( const SFVEC2I &aShaderPos ) const = 0; virtual SFVEC3F Shade( const SFVEC2I &aShaderPos ) const = 0;
/**
* @brief ApplyShadeColor - apply the final color process using a previous stage color
* @param aShadeColor - The result of the shader
* @return the result of the shade process
*/
virtual SFVEC3F ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, const SFVEC3F &aShadeColor ) const = 0;
void UpdateSize( const SFVEC2UI &aSize ); void UpdateSize( const SFVEC2UI &aSize );
void UpdateSize( unsigned int xSize, unsigned int ySize ); void UpdateSize( unsigned int xSize, unsigned int ySize );

View File

@ -35,121 +35,100 @@ CPOSTSHADER_SSAO::CPOSTSHADER_SSAO( const CCAMERA &aCamera ) : CPOSTSHADER( aCam
{ {
} }
//https://github.com/OniDaito/CoffeeGL/blob/master/misc/ssao.frag
// By martinsh // There are differente sources for this shader on the web
//https://github.com/scanberg/hbao/blob/master/resources/shaders/ssao_frag.glsl
//http://www.gamedev.net/topic/556187-the-best-ssao-ive-seen/
//http://www.gamedev.net/topic/556187-the-best-ssao-ive-seen/?view=findpost&p=4632208 //http://www.gamedev.net/topic/556187-the-best-ssao-ive-seen/?view=findpost&p=4632208
float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos, float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos,
const SFVEC3F &ddiff, const SFVEC3F &ddiff,
const SFVEC3F &cnorm, const SFVEC3F &cnorm,
int c1, int c1,
int c2, int c2 ) const
float aAttShadowFactor ) const
{ {
float return_value = -1.0f; const float shadowGain = 0.5f;
const float aoGain = 1.0f;
const float outGain = 0.80f;
float return_value = 0.0f;
const float rd = glm::length( ddiff ); const float rd = glm::length( ddiff );
const float shadow_factor_at_shade_pos = aAttShadowFactor * 1.00f; // This limits the zero of the function (see below)
if( rd < 1.0f )
float shadow_factor = shadow_factor_at_shade_pos;
const SFVEC2I vr = aShaderPos + SFVEC2I( c1, c2 );
// Calculate a blured shadow based on hit-light test calculation
// /////////////////////////////////////////////////////////////////////////
// This limit to the zero of the function (see below)
if( (rd > FLT_EPSILON) && (rd < 1.0f) )
{ {
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLSh4Lyh4LzIrMC41KSkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC41OTk1NTEyNjc1Njk4MjUiLCIxLjI3Mzk0NjE3NzQxNjI5ODgiLCItMC4xMTQzMjE1NjkyMTMwMTAwOCIsIjEuMDM4NTk5OTM1MzkzODM1MyJdfV0- const SFVEC2I vr = aShaderPos + SFVEC2I( c1, c2 );
// zero: 1.0
const float attDistFactor = 1.0f - (rd / (rd / 2.0f + 0.5f));
const float shadow_factor_at_sample = GetShadowFactorAt( vr ); const float shadow_factor_at_sample = ( 1.0f - GetShadowFactorAt( vr ) ) * shadowGain;
shadow_factor = shadow_factor_at_sample * attDistFactor + if( rd > FLT_EPSILON )
(1.0f - attDistFactor) * shadow_factor_at_shade_pos; {
const SFVEC3F vv = glm::normalize( ddiff );
// Calculate an attenuation distance factor, this was get the best
// results by experimentation
// Changing this factor will change how much shadow in relation to the
// distance of the hit it will be in shadow
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIwLjYteCowLjQ1IiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjowLCJlcSI6IiIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjIxNTcyODA1NTg4MzI1ODYiLCIyLjEyNjE0Mzc1MDM0OTM4ODciLCItMC4wOTM1NDA0NzY0MjczNjAzIiwiMS4zNDc2MTE0MDQzMzExOTIyIl0sInNpemUiOls2NDksMzk5XX1d
// zero: 1.0
const float attDistFactor = 0.6f - rd * 0.6f;
// Original:
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMS0xL3NxcnQoMS8oeCp4KSsxKSkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC42ODY3NDc3NDcxMDg0MTQyIiwiMy44ODcyMjA2MjQ0Mzk3MzM0IiwiLTAuOTA5NTYyNzcyOTMyNDk2IiwiMS45MDUxODY5OTQxNzQwNTczIl19XQ--
// zero: inf
//const float attDistFactor = (1.0f - 1.0f / sqrt( 1.0f / ( rd * rd) + 1.0f) );
//const float attDistFactor = 1.0f;
// Tool for visualize dot product:
// http://www.falstad.com/dotproduct/
// This is a dot product threshold factor.
// it defines after wich angle we consider that the point starts to occlude.
// if the value is high, it will distart low angles point
const float aDotThreshold = 0.15f;
// This is the normal factor using the normal at the sampled point (of the shader)
// agaisnt the vector from the center to the position at sampled point
const float sampledNormalFactor = glm::dot( GetNormalAt( vr ), -vv );
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIobWF4KHgsMC4zKS0wLjMpLygxLTAuMykiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC42ODY3NDc3NDcxMDg0MTQyIiwiMy44ODcyMjA2MjQ0Mzk3MzM0IiwiLTAuOTA5NTYyNzcyOTMyNDk2IiwiMS45MDUxODY5OTQxNzQwNTczIl19XQ--
const float sampledNormalFactorWithThreshold = (glm::max( sampledNormalFactor, aDotThreshold ) - aDotThreshold) /
(1.0f - aDotThreshold);
// This is the dot product between the center pixel (the one that is being shaded)
// and the vector from the center to the sampled point
const float localNormalFactor = glm::dot( cnorm, vv );
const float localNormalFactorWithThreshold = (glm::max( localNormalFactor, aDotThreshold ) - aDotThreshold) /
(1.0f - aDotThreshold);
const float aoFactor = (1.0f - sampledNormalFactorWithThreshold) *
localNormalFactorWithThreshold *
aoGain;
return_value = ( ( aoFactor + shadow_factor_at_sample ) * attDistFactor );
// Test / Debug code
//return_value = glm::max( aaFactor, shadow_factor );
//return_value = aaFactor;
//return_value = shadow_factor;
//return_value = glm::clamp( aaFactor, 0.0f, 1.0f );
}
else
{
return_value = shadow_factor_at_sample;
}
} }
//shadow_factor = (1.0f - shadow_factor) / 8.0f; return return_value * outGain;
//shadow_factor = (0.66f - ( 1.0f - 1.0f / ( shadow_factor * 2.00f + 1.0f ) )) / 12.0f;
//shadow_factor = 0.50f - ( 1.0f - 1.0f / ( shadow_factor * 1.00f + 1.0f ) ); // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIwLjUtKDEuMC0xLjAvKHgqMS4wKzEuMCkpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuNTk5NTUxMjY3NTY5ODI1IiwiMS4yNzM5NDYxNzc0MTYyOTg4IiwiLTAuMTE0MzIxNTY5MjEzMDEwMDgiLCIxLjAzODU5OTkzNTM5MzgzNTMiXX1d
//shadow_factor = 0.40f - ( 1.0f - 1.0f / ( shadow_factor * 0.67f + 1.0f ) ); // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIwLjQtKDEuMC0xLjAvKHgqMC42NysxLjApKSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjU5OTU1MTI2NzU2OTgyNSIsIjEuMjczOTQ2MTc3NDE2Mjk4OCIsIi0wLjExNDMyMTU2OTIxMzAxMDA4IiwiMS4wMzg1OTk5MzUzOTM4MzUzIl19XQ--
//shadow_factor = 0.20f - ( 1.0f - 1.0f / ( shadow_factor * 0.25f + 1.0f ) ); // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIwLjItKDEuMC0xLjAvKHgqMC4yNSsxLjApKSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjU5OTU1MTI2NzU2OTgyNSIsIjEuMjczOTQ2MTc3NDE2Mjk4OCIsIi0wLjExNDMyMTU2OTIxMzAxMDA4IiwiMS4wMzg1OTk5MzUzOTM4MzUzIl19XQ--
//shadow_factor = 1.0f / ( shadow_factor * 15.0f + 3.0f ) - 0.05f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAvKHgqMTUuMCszLjApLTAuMDUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC41OTk1NTEyNjc1Njk4MjUiLCIxLjI3Mzk0NjE3NzQxNjI5ODgiLCItMC4xMTQzMjE1NjkyMTMwMTAwOCIsIjEuMDM4NTk5OTM1MzkzODM1MyJdfV0-
//shadow_factor = 1.0f / ( shadow_factor * 10.0f + 2.0f ) - 0.08f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAvKHgqMTAuMCsyLjApLTAuMDgiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC41OTk1NTEyNjc1Njk4MjUiLCIxLjI3Mzk0NjE3NzQxNjI5ODgiLCItMC4xMTQzMjE1NjkyMTMwMTAwOCIsIjEuMDM4NTk5OTM1MzkzODM1MyJdfV0-
//shadow_factor = (1.0f / ( shadow_factor * 3.0f + 1.5f ))- 0.22f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAvKHgqMy4wKzEuNSktMC4yMiIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjU5OTU1MTI2NzU2OTgyNSIsIjEuMjczOTQ2MTc3NDE2Mjk4OCIsIi0wLjExNDMyMTU2OTIxMzAxMDA4IiwiMS4wMzg1OTk5MzUzOTM4MzUzIl19XQ--
//shadow_factor = (1.0f / ( shadow_factor * 1.7f + 1.9f ))- 0.28f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMS4wLyh4KjEuNysxLjkpKS0wLjI4IiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuNTk5NTUxMjY3NTY5ODI1IiwiMS4yNzM5NDYxNzc0MTYyOTg4IiwiLTAuMTE0MzIxNTY5MjEzMDEwMDgiLCIxLjAzODU5OTkzNTM5MzgzNTMiXX1d
//shadow_factor = (shadow_factor - 0.1);
//shadow_factor = (1.0f / ( shadow_factor * shadow_factor * 1.7f + 1.1f ))- 0.58f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMS4wLygoeC0wLjEpKih4LTAuMSkqMS43KzEuMSkpLTAuNTgiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC41OTk1NTEyNjc1Njk4MjUiLCIxLjI3Mzk0NjE3NzQxNjI5ODgiLCItMC4xMTQzMjE1NjkyMTMwMTAwOCIsIjEuMDM4NTk5OTM1MzkzODM1MyJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
//shadow_factor = -shadow_factor * shadow_factor * 0.1f + 0.10f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoLXgqMC4xMCswLjEwKSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjU5OTU1MTI2NzU2OTgyNSIsIjEuMjczOTQ2MTc3NDE2Mjk4OCIsIi0wLjExNDMyMTU2OTIxMzAxMDA4IiwiMS4wMzg1OTk5MzUzOTM4MzUzIl0sInNpemUiOls2NDksMzk5XX1d
shadow_factor = -shadow_factor * shadow_factor * 0.2f + 0.15f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoLXgqMC4yKzAuMTUpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuNTk5NTUxMjY3NTY5ODI1IiwiMS4yNzM5NDYxNzc0MTYyOTg4IiwiLTAuMTE0MzIxNTY5MjEzMDEwMDgiLCIxLjAzODU5OTkzNTM5MzgzNTMiXSwic2l6ZSI6WzY0OSwzOTldfV0-
//shadow_factor = -shadow_factor * shadow_factor * 0.3f + 0.25f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoLXgqMC4zKzAuMjUpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuNTk5NTUxMjY3NTY5ODI1IiwiMS4yNzM5NDYxNzc0MTYyOTg4IiwiLTAuMTE0MzIxNTY5MjEzMDEwMDgiLCIxLjAzODU5OTkzNTM5MzgzNTMiXSwic2l6ZSI6WzY0OSwzOTldfV0-
//shadow_factor = -shadow_factor * shadow_factor * 0.4f + 0.40f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoLXgqMC40MCswLjM1KSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjU5OTU1MTI2NzU2OTgyNSIsIjEuMjczOTQ2MTc3NDE2Mjk4OCIsIi0wLjExNDMyMTU2OTIxMzAxMDA4IiwiMS4wMzg1OTk5MzUzOTM4MzUzIl0sInNpemUiOls2NDksMzk5XX1d
shadow_factor = glm::max( shadow_factor, 0.00f );
// Calculate the edges ambient oclusion
// /////////////////////////////////////////////////////////////////////////
//if( (rd > FLT_EPSILON) && (rd < 0.2f) ) // This limit to the zero of the function (see below)
//if( rd > FLT_EPSILON )
if( (rd > FLT_EPSILON) && (rd < 1.0f) )
{
const SFVEC3F vv = glm::normalize( ddiff );
// Calculate an attenuation distance factor, this was get the best
// results by experimentation
// Changing this factor will change how much shadow in relation to the
// distance of the hit it will be in shadow
float attDistFactor = 0.0f;
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLSh4Lyh4LzIrMC4wMTUpKSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjAzMTM1ODM0NTk2MDIzOTAyIiwiMC4wNDUzODAxMDkzODYzOTI2MyIsIi0wLjAyMjM1MDcxNDk0NzUxMjk0IiwiMC4wMjQ4NzI5NDk4ODExODM0ODIiXX1d
// zero: 0.03
//attDistFactor = 1.0f - (rd / (rd/2.0f + 0.015f));
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLSh4Lyh4LzIrMC4xMCkpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuOTI4NjMzODAzMTQ3MTcyOSIsIjAuOTQ0ODYzNjQxODM4OTQ5NyIsIi0wLjE1MjA2MTc2MjkxMzQxMjI4IiwiMS4wMDA4NTk3NDE2OTM0MzI4Il19XQ--
// zero: 0.2
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIwLjgtKHgvKHgvMiswLjE1KSkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoiLXgqMC4wNSswLjI1IiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuMjE1NzI4MDU1ODgzMjU4NjYiLCIyLjEyNjE0Mzc1MDM0OTM4ODciLCItMC4wOTM1NDA0NzY0MjczNjA0MiIsIjEuMzQ3NjExNDA0MzMxMTkyNCJdfV0-
// zero: 0.2
// attDistFactor = 0.8f - (rd / (rd / 2.0f + 0.15f));
// attDistFactor = glm::max( attDistFactor, -rd * 0.05f + 0.25f );
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIwLjgtKHgvKHgvMC45MCswLjEzKSkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoiKC14KjAuMiswLjE1KSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjIxNTcyODA1NTg4MzI1ODY2IiwiMi4xMjYxNDM3NTAzNDkzODg3IiwiLTAuMDkzNTQwNDc2NDI3MzYwNDIiLCIxLjM0NzYxMTQwNDMzMTE5MjQiXSwic2l6ZSI6WzY0OSwzOTldfV0-
// zero: 1.0
attDistFactor = 0.8f - (rd / (rd / 0.90f + 0.13f));
// Original:
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMS0xL3NxcnQoMS8oeCp4KSsxKSkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC42ODY3NDc3NDcxMDg0MTQyIiwiMy44ODcyMjA2MjQ0Mzk3MzM0IiwiLTAuOTA5NTYyNzcyOTMyNDk2IiwiMS45MDUxODY5OTQxNzQwNTczIl19XQ--
// zero: inf
//const float attDistFactor = (1.0f - 1.0f / sqrt( 1.0f / ( rd * rd) + 1.0f) );
//float attDistFactor = 1.0f;
const float aaFactor = (1.0f - glm::clamp( glm::dot( GetNormalAt( vr ), -vv ), 0.0f, 1.0f) ) *
glm::clamp( glm::dot( cnorm, vv ), 0.0f, 1.0f ) * attDistFactor;
return_value = (aaFactor * 1.0f + shadow_factor ) * 1.00f;
// Test / Debug code
//return_value = glm::max( aaFactor, shadow_factor );
//return_value = aaFactor;
//return_value = shadow_factor;
}
else
{
return_value = ( 0.0f + shadow_factor ) * 1.00f;
// Test / Debug code
//return_value = 0.0f;
}
return glm::clamp( return_value, 0.0f, 1.0f );
} }
@ -191,62 +170,53 @@ SFVEC3F CPOSTSHADER_SSAO::Shade( const SFVEC2I &aShaderPos ) const
if( cdepth > FLT_EPSILON ) if( cdepth > FLT_EPSILON )
{ {
float cNormalizedDepth = GetDepthNormalizedAt( aShaderPos ); //const float cNormalizedDepth = GetDepthNormalizedAt( aShaderPos );
//wxASSERT( cNormalizedDepth <= 1.0f );
//wxASSERT( cNormalizedDepth >= 0.0f );
wxASSERT( cNormalizedDepth <= 1.0f ); cdepth = (10.0f / (cdepth + 1.0f) );
wxASSERT( cNormalizedDepth >= 0.0f );
cdepth = ( (1.50f - cNormalizedDepth) +
( 1.0f - (1.0f / (cdepth + 1.0f) ) ) * 2.5f );
// Test source code
//cdepth = ( (1.75f - cNormalizedDepth) + (1.0f / cdepth) * 2.0f );
//cdepth = 1.5f - cNormalizedDepth;
//cdepth = (1.0f / cdepth) * 2.0f;
// read current normal,position and color. // read current normal,position and color.
const SFVEC3F n = GetNormalAt( aShaderPos ); const SFVEC3F n = GetNormalAt( aShaderPos );
const SFVEC3F p = GetPositionAt( aShaderPos ); const SFVEC3F p = GetPositionAt( aShaderPos );
//const SFVEC3F col = GetColorAt( aShaderPos ); //const SFVEC3F col = GetColorAt( aShaderPos );
const float shadowFactor = GetShadowFactorAt( aShaderPos );
// initialize variables: // initialize variables:
float ao = 0.0f; float ao = 0.0f;
SFVEC3F gi = SFVEC3F(0.0f); SFVEC3F gi = SFVEC3F(0.0f);
// This calculated the "window range" of the shader. So it will get // This calculated the "window range" of the shader. So it will get
// more or less sparsed samples // more or less sparsed samples
const int incx = 3; const int incx = 2;
const int incy = 3; const int incy = 2;
//3 rounds of 8 samples each. //3 rounds of 8 samples each.
for( unsigned int i = 0; i < 3; ++i ) for( unsigned int i = 0; i < 3; ++i )
{ {
static const int mask[3] = { 0x01, 0x03, 0x03 }; static const int mask[3] = { 0x01, 0x03, 0x03 };
const int pw = 1 + (Fast_rand() & mask[i]); const int pw = 0 + (Fast_rand() & mask[i]);
const int ph = 1 + (Fast_rand() & mask[i]); const int ph = 0 + (Fast_rand() & mask[i]);
const int npw = (int)((pw + incx * i) * cdepth ); const int npw = (int)((pw + incx * i) * cdepth ) + (i + 1);
const int nph = (int)((ph + incy * i) * cdepth ); const int nph = (int)((ph + incy * i) * cdepth ) + (i + 1);
const SFVEC3F ddiff = GetPositionAt( aShaderPos + SFVEC2I( npw, nph ) ) - p; const SFVEC3F ddiff = GetPositionAt( aShaderPos + SFVEC2I( npw, nph ) ) - p;
const SFVEC3F ddiff2 = GetPositionAt( aShaderPos + SFVEC2I( npw,-nph ) ) - p; const SFVEC3F ddiff2 = GetPositionAt( aShaderPos + SFVEC2I( npw,-nph ) ) - p;
const SFVEC3F ddiff3 = GetPositionAt( aShaderPos + SFVEC2I(-npw, nph ) ) - p; const SFVEC3F ddiff3 = GetPositionAt( aShaderPos + SFVEC2I(-npw, nph ) ) - p;
const SFVEC3F ddiff4 = GetPositionAt( aShaderPos + SFVEC2I(-npw,-nph ) ) - p; const SFVEC3F ddiff4 = GetPositionAt( aShaderPos + SFVEC2I(-npw,-nph ) ) - p;
const SFVEC3F ddiff5 = GetPositionAt( aShaderPos + SFVEC2I( 0, nph ) ) - p; const SFVEC3F ddiff5 = GetPositionAt( aShaderPos + SFVEC2I( pw, nph ) ) - p;
const SFVEC3F ddiff6 = GetPositionAt( aShaderPos + SFVEC2I( 0,-nph ) ) - p; const SFVEC3F ddiff6 = GetPositionAt( aShaderPos + SFVEC2I( pw,-nph ) ) - p;
const SFVEC3F ddiff7 = GetPositionAt( aShaderPos + SFVEC2I( npw, 0 ) ) - p; const SFVEC3F ddiff7 = GetPositionAt( aShaderPos + SFVEC2I( npw, ph ) ) - p;
const SFVEC3F ddiff8 = GetPositionAt( aShaderPos + SFVEC2I(-npw, 0 ) ) - p; const SFVEC3F ddiff8 = GetPositionAt( aShaderPos + SFVEC2I(-npw, ph ) ) - p;
ao+= aoFF( aShaderPos, ddiff , n, npw, nph, shadowFactor ); ao+= aoFF( aShaderPos, ddiff , n, npw, nph );
ao+= aoFF( aShaderPos, ddiff2, n, npw,-nph, shadowFactor ); ao+= aoFF( aShaderPos, ddiff2, n, npw,-nph );
ao+= aoFF( aShaderPos, ddiff3, n, -npw, nph, shadowFactor ); ao+= aoFF( aShaderPos, ddiff3, n, -npw, nph );
ao+= aoFF( aShaderPos, ddiff4, n, -npw,-nph, shadowFactor ); ao+= aoFF( aShaderPos, ddiff4, n, -npw,-nph );
ao+= aoFF( aShaderPos, ddiff5, n, 0, nph, shadowFactor ); ao+= aoFF( aShaderPos, ddiff5, n, pw, nph );
ao+= aoFF( aShaderPos, ddiff6, n, 0,-nph, shadowFactor ); ao+= aoFF( aShaderPos, ddiff6, n, pw,-nph );
ao+= aoFF( aShaderPos, ddiff7, n, npw, 0, shadowFactor ); ao+= aoFF( aShaderPos, ddiff7, n, npw, ph );
ao+= aoFF( aShaderPos, ddiff8, n, -npw, 0, shadowFactor ); ao+= aoFF( aShaderPos, ddiff8, n, -npw, ph );
gi+= giFF( aShaderPos, ddiff , n, npw, nph) * gi+= giFF( aShaderPos, ddiff , n, npw, nph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( npw, nph ) ) ); giColorCurve( GetColorAt( aShaderPos + SFVEC2I( npw, nph ) ) );
@ -256,26 +226,27 @@ SFVEC3F CPOSTSHADER_SSAO::Shade( const SFVEC2I &aShaderPos ) const
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, nph ) ) ); giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, nph ) ) );
gi+= giFF( aShaderPos, ddiff4, n,-npw, -nph) * gi+= giFF( aShaderPos, ddiff4, n,-npw, -nph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw,-nph ) ) ); giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw,-nph ) ) );
gi+= giFF( aShaderPos, ddiff5, n, 0.0f, nph) * gi+= giFF( aShaderPos, ddiff5, n, pw, nph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( 0, nph ) ) ); giColorCurve( GetColorAt( aShaderPos + SFVEC2I( pw, nph ) ) );
gi+= giFF( aShaderPos, ddiff6, n, 0.0f,-nph) * gi+= giFF( aShaderPos, ddiff6, n, pw,-nph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( 0,-nph ) ) ); giColorCurve( GetColorAt( aShaderPos + SFVEC2I( pw,-nph ) ) );
gi+= giFF( aShaderPos, ddiff7, n, npw, 0.0f) * gi+= giFF( aShaderPos, ddiff7, n, npw, ph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( npw, 0) ) ); giColorCurve( GetColorAt( aShaderPos + SFVEC2I( npw, ph ) ) );
gi+= giFF( aShaderPos, ddiff8, n,-npw, 0.0f) * gi+= giFF( aShaderPos, ddiff8, n,-npw, ph) *
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, 0) ) ); giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, ph ) ) );
} }
ao = (ao / 24.0f) + 0.0f; // Apply a bias for the ambient oclusion ao = (ao / 24.0f) + 0.0f; // Apply a bias for the ambient oclusion
gi = (gi * 5.0f / 24.0f); // Apply a bias for the global illumination gi = (gi * 5.0f / 24.0f); // Apply a bias for the global illumination
//return SFVEC3F(ao); //return SFVEC3F(ao);
return SFVEC3F( SFVEC3F(ao) - gi); return SFVEC3F(ao) - gi;
// Test source code // Test source code
//return SFVEC3F( col ); //return SFVEC3F( col );
//return SFVEC3F( col - SFVEC3F(ao) + gi * 5.0f ); //return SFVEC3F( col - SFVEC3F(ao) + gi * 5.0f );
//return SFVEC3F( SFVEC3F(1.0f) - SFVEC3F(ao) + gi * 5.0f ); //return SFVEC3F( SFVEC3F(1.0f) - SFVEC3F(ao) + gi * 5.0f );
//return SFVEC3F(cdepth); //return SFVEC3F(cdepth);
//return SFVEC3F(cNormalizedDepth);
//return 1.0f - SFVEC3F(ao); //return 1.0f - SFVEC3F(ao);
//return SFVEC3F(ao); //return SFVEC3F(ao);
} }
@ -285,15 +256,30 @@ SFVEC3F CPOSTSHADER_SSAO::Shade( const SFVEC2I &aShaderPos ) const
} }
SFVEC3F CPOSTSHADER_SSAO::ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, const SFVEC3F &aShadeColor ) const
{
// This is the final stage of the shader and make the last calculation how to apply the shader
const SFVEC3F shadedColor = aInputColor - ( -aShadeColor * (aShadeColor * SFVEC3F(0.1f) - SFVEC3F(1.0f) ) );
return shadedColor;
}
SFVEC3F CPOSTSHADER_SSAO::giColorCurve( const SFVEC3F &aColor ) const SFVEC3F CPOSTSHADER_SSAO::giColorCurve( const SFVEC3F &aColor ) const
{ {
const SFVEC3F vec1 = SFVEC3F(1.0f); const SFVEC3F vec1 = SFVEC3F(1.0f);
// http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEvKHgqMS4wKzEuMCkpK3gqMC4xIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuMDYyMTg0NjE1Mzg0NjE1NTA1IiwiMS4xNDI5ODQ2MTUzODQ2MTQ2IiwiLTAuMTI3MDk5OTk5OTk5OTk5NzciLCIxLjEzMjYiXX1d // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEvKHgqMS4wKzEuMCkpK3gqMC4xIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuMDYyMTg0NjE1Mzg0NjE1NTA1IiwiMS4xNDI5ODQ2MTUzODQ2MTQ2IiwiLTAuMTI3MDk5OTk5OTk5OTk5NzciLCIxLjEzMjYiXX1d
return vec1 - ( vec1 / (aColor + vec1) ) + aColor * SFVEC3F(0.10f); //return vec1 - ( vec1 / (aColor + vec1) ) + aColor * SFVEC3F(0.10f);
// http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEuMC8oeCoyLjArMS4wKSkreCowLjEiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC4wNjIxODQ2MTUzODQ2MTU1MDUiLCIxLjE0Mjk4NDYxNTM4NDYxNDYiLCItMC4xMjcwOTk5OTk5OTk5OTk3NyIsIjEuMTMyNiJdfV0- // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEuMC8oeCoyLjArMS4wKSkreCowLjEiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC4wNjIxODQ2MTUzODQ2MTU1MDUiLCIxLjE0Mjk4NDYxNTM4NDYxNDYiLCItMC4xMjcwOTk5OTk5OTk5OTk3NyIsIjEuMTMyNiJdfV0-
//return vec1 - ( vec1 / (aColor * SFVEC3F(2.0f) + vec1) ) + aColor * SFVEC3F(0.10f); //return vec1 - ( vec1 / (aColor * SFVEC3F(2.0f) + vec1) ) + aColor * SFVEC3F(0.10f);
//return aColor; // This option actually apply a gama since we are using linear color space
// and the result shader will be applied after convert back to sRGB
// http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEuMC8oeCo5LjArMS4wKSkreCowLjEiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC4wNjIxODQ2MTUzODQ2MTU1MDUiLCIxLjE0Mjk4NDYxNTM4NDYxNDYiLCItMC4xMjcwOTk5OTk5OTk5OTk3NyIsIjEuMTMyNiJdfV0-
return vec1 - ( vec1 / (aColor * SFVEC3F(9.0f) + vec1) ) + aColor * SFVEC3F(0.10f);
// return aColor;
} }

View File

@ -42,6 +42,7 @@ public:
// Imported from CPOSTSHADER // Imported from CPOSTSHADER
SFVEC3F Shade(const SFVEC2I &aShaderPos ) const override; SFVEC3F Shade(const SFVEC2I &aShaderPos ) const override;
SFVEC3F ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, const SFVEC3F &aShadeColor ) const override;
private: private:
SFVEC3F posFromDepth( const SFVEC2F &coord ) const; SFVEC3F posFromDepth( const SFVEC2F &coord ) const;
@ -52,8 +53,7 @@ private:
const SFVEC3F &ddiff, const SFVEC3F &ddiff,
const SFVEC3F &cnorm, const SFVEC3F &cnorm,
int c1, int c1,
int c2, int c2 ) const;
float aAttShadowFactor ) const;
float giFF( const SFVEC2I &aShaderPos, float giFF( const SFVEC2I &aShaderPos,
const SFVEC3F &ddiff, const SFVEC3F &ddiff,

View File

@ -447,7 +447,7 @@ void EDA_3D_VIEWER::Process_Special_Functions( wxCommandEvent &event )
case ID_MENU3D_FL_RAYTRACING_POST_PROCESSING: case ID_MENU3D_FL_RAYTRACING_POST_PROCESSING:
m_settings.SetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING, isChecked ); m_settings.SetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING, isChecked );
m_canvas->Request_refresh(); ReloadRequest( );
return; return;
case ID_MENU3D_FL_RAYTRACING_ANTI_ALIASING: case ID_MENU3D_FL_RAYTRACING_ANTI_ALIASING: