3D-Viewer: implements plated copper texture

improves copper and board textures.
Related to https://gitlab.com/kicad/code/kicad/-/issues/2058
Use only one PerlinNoise class.
This commit is contained in:
Mario Luzeiro 2020-09-08 01:32:00 +01:00 committed by Jon Evans
parent f0edbd088c
commit d52c475b27
4 changed files with 106 additions and 69 deletions

View File

@ -84,11 +84,13 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
{
m_board_normal_perturbator = CBOARDNORMAL( 0.5f * mmTo3Dunits );
m_board_normal_perturbator = CBOARDNORMAL( 0.40f * mmTo3Dunits );
m_copper_normal_perturbator = CCOPPERNORMAL( 4.0f * mmTo3Dunits,
&m_board_normal_perturbator );
m_platedcopper_normal_perturbator = CPLATEDCOPPERNORMAL( 0.5f * mmTo3Dunits );
m_solder_mask_normal_perturbator = CSOLDERMASKNORMAL( &m_board_normal_perturbator );
m_plastic_normal_perturbator = CPLASTICNORMAL( 0.15f * mmTo3Dunits );
@ -101,23 +103,26 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
// http://devernay.free.fr/cours/opengl/materials.html
// Copper
m_materials.m_Copper = CBLINN_PHONG_MATERIAL(
ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_CopperColor ) *
(SFVEC3F)(0.18f), // ambient
SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
glm::clamp( ((SFVEC3F)(1.0f) -
ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_CopperColor ) ),
const SFVEC3F copperSpecularLinear = ConvertSRGBToLinear(
glm::clamp( (SFVEC3F)m_boardAdapter.m_CopperColor * 0.5f + 0.25f,
SFVEC3F( 0.0f ),
SFVEC3F( 0.35f ) ), // specular
SFVEC3F( 1.0f ) ) );
m_materials.m_Copper = CBLINN_PHONG_MATERIAL( ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_CopperColor * 0.3f ), // ambient
SFVEC3F( 0.0f ), // emissive
copperSpecularLinear, // specular
0.4f * 128.0f, // shiness
0.0f, // transparency
0.0f );
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
m_materials.m_Copper.SetNormalPerturbator( &m_platedcopper_normal_perturbator );
m_materials.m_NonPlatedCopper = CBLINN_PHONG_MATERIAL(
ConvertSRGBToLinear( SFVEC3F( 0.191f, 0.073f, 0.022f ) ),// ambient
SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
SFVEC3F( 0.256f, 0.137f, 0.086f ), // specular
0.1f * 128.0f, // shiness
0.15f * 128.0f, // shiness
0.0f, // transparency
0.0f );
@ -157,11 +162,7 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
m_materials.m_SolderMask = CBLINN_PHONG_MATERIAL(
ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_SolderMaskColorTop ) * 0.10f, // ambient
SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
glm::clamp(
( ( SFVEC3F )( 1.0f )
- ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_SolderMaskColorTop ) ),
SFVEC3F( 0.0f ),
SFVEC3F( solderMask_gray * 2.0f ) ), // specular
SFVEC3F( glm::clamp( solderMask_gray * 2.0f, 0.25f, 1.0f ) ), // specular
0.85f * 128.0f, // shiness
solderMask_transparency, // transparency
0.16f ); // reflection

View File

@ -116,6 +116,7 @@ private:
CBOARDNORMAL m_board_normal_perturbator;
CCOPPERNORMAL m_copper_normal_perturbator;
CPLATEDCOPPERNORMAL m_platedcopper_normal_perturbator;
CSOLDERMASKNORMAL m_solder_mask_normal_perturbator;
CPLASTICNORMAL m_plastic_normal_perturbator;
CPLASTICSHINENORMAL m_plastic_shine_normal_perturbator;

View File

@ -154,6 +154,9 @@ CPROCEDURALGENERATOR::CPROCEDURALGENERATOR()
}
static PerlinNoise s_perlinNoise = PerlinNoise( 0 );
CBOARDNORMAL::CBOARDNORMAL( float aScale ) : CPROCEDURALGENERATOR()
{
m_scale = (2.0f * glm::pi<float>()) / aScale;
@ -162,24 +165,27 @@ CBOARDNORMAL::CBOARDNORMAL( float aScale ) : CPROCEDURALGENERATOR()
SFVEC3F CBOARDNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{
const SFVEC3F &hitPos = aHitInfo.m_HitPoint;
const SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJzaW4oc2luKHNpbih4KSoxLjkpKjEuNSkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC45NjIxMDU3MDgwNzg1MjYyIiwiNy45NzE0MjYyNjc2MDE0MyIsIi0yLjUxNzYyMDM1MTQ4MjQ0OSIsIjIuOTc5OTM3Nzg3Mzk3NTMwMyJdLCJzaXplIjpbNjQ2LDM5Nl19XQ--
// Implement a texture as the "measling crazing blistering" method of FR4
const float x = (glm::sin(glm::sin( glm::sin( hitPos.x * m_scale ) * 1.9f ) * 1.5f ) + 0.0f) * 0.10f;
const float y = (glm::sin(glm::sin( glm::sin( hitPos.y * m_scale ) * 1.9f ) * 1.5f ) + 0.0f) * 0.10f;
const float z = glm::sin( 2.0f * hitPos.z * m_scale + Fast_RandFloat() * 1.0f ) * 0.2f;
const float x = glm::sin( glm::sin( hitPos.x ) * 1.5f ) * 0.06f;
const float y = glm::sin( glm::sin( hitPos.y ) * 1.5f ) * 0.03f;
const float z = -(x + y) + glm::sin( hitPos.z ) * 0.06f;
return SFVEC3F( x, y, z );
const float noise1 = s_perlinNoise.noise( hitPos.x * 1.0f, hitPos.y * 0.7f ) - 0.5f;
const float noise2 = s_perlinNoise.noise( hitPos.x * 0.7f, hitPos.y * 1.0f ) - 0.5f;
const float noise3 = s_perlinNoise.noise( hitPos.x * 0.3f, hitPos.y * 0.3f ) - 0.5f;
return ( SFVEC3F( noise1, noise2, -( noise3 ) ) * 0.3f + SFVEC3F( x, y, z ) );
}
CCOPPERNORMAL::CCOPPERNORMAL( float aScale, const CPROCEDURALGENERATOR *aBoardNormalGenerator )
{
m_board_normal_generator = aBoardNormalGenerator;
m_copper_perlin = PerlinNoise( 0 );
m_scale = 1.0f / aScale;
}
@ -192,17 +198,15 @@ SFVEC3F CCOPPERNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) cons
SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
const float noise = (m_copper_perlin.noise( hitPos.x + Fast_RandFloat() * 0.1f,
hitPos.y ) - 0.5f) * 2.0f;
const float noise = (s_perlinNoise.noise( hitPos.x + boardNormal.y + aRay.m_Origin.x * 0.2f,
hitPos.y + boardNormal.x ) - 0.5f) * 2.0f;
float scratchPattern = (m_copper_perlin.noise( hitPos.x / 100.0f, hitPos.y * 20.0f ) - 0.5f);
float scratchPattern = (s_perlinNoise.noise( noise + hitPos.x / 100.0f, hitPos.y * 100.0f ) - 0.5f);
scratchPattern = glm::clamp( scratchPattern * 5.0f, -1.0f, 1.0f );
const float x = scratchPattern * 0.14f;
const float y = (noise + noise * scratchPattern) * 0.14f;
const float x = glm::clamp( (noise + scratchPattern) * 0.04f, -0.10f, 0.10f );
const float y = glm::clamp( (noise + (noise * scratchPattern)) * 0.04f, -0.10f, 0.10f );
return SFVEC3F( x, y, 0.0f ) + boardNormal * 0.85f;
return SFVEC3F( x, y, - ( x + y ) ) + boardNormal * 0.25f;
}
else
return SFVEC3F(0.0f);
@ -221,13 +225,24 @@ SFVEC3F CSOLDERMASKNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo )
{
const SFVEC3F copperNormal = m_copper_normal_generator->Generate( aRay, aHitInfo );
return copperNormal * SFVEC3F(0.10f);
return copperNormal * 0.05f;
}
else
return SFVEC3F(0.0f);
}
SFVEC3F CPLATEDCOPPERNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{
SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
const float noise1 = ( s_perlinNoise.noise( hitPos.x, hitPos.y ) - 0.5f );
const float noise2 = ( s_perlinNoise.noise( hitPos.y, hitPos.x ) - 0.5f );
return SFVEC3F( noise1, noise2, -( noise1 + noise2 ) ) * 0.02f;
}
CPLASTICNORMAL::CPLASTICNORMAL( float aScale )
{
m_scale = 1.0f / aScale;
@ -238,15 +253,15 @@ SFVEC3F CPLASTICNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) con
{
const SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
const float noise1 = m_perlin.noise( hitPos.x * 1.0f,
const float noise1 = s_perlinNoise.noise( hitPos.x * 1.0f,
hitPos.y * 1.0f,
hitPos.z * 1.0f ) - 0.5f;
const float noise2 = m_perlin.noise( hitPos.x * 1.5f,
const float noise2 = s_perlinNoise.noise( hitPos.x * 1.5f,
hitPos.y * 1.5f,
hitPos.z * 2.0f ) - 0.5f;
const float noise3 = m_perlin.noise( hitPos.x * 2.0f,
const float noise3 = s_perlinNoise.noise( hitPos.x * 2.0f,
hitPos.y * 2.0f,
hitPos.z * 2.0f ) - 0.5f;
@ -266,15 +281,15 @@ SFVEC3F CPLASTICSHINENORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo
{
const SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
const float noise1 = m_perlin.noise( hitPos.x * 0.05f,
const float noise1 = s_perlinNoise.noise( hitPos.x * 0.05f,
hitPos.y * 0.05f,
hitPos.z * 0.05f ) - 0.5f;
const float noise2 = m_perlin.noise( hitPos.x * 0.2f,
const float noise2 = s_perlinNoise.noise( hitPos.x * 0.2f,
hitPos.y * 0.2f,
hitPos.z * 0.2f ) - 0.5f;
const float noise3 = m_perlin.noise( hitPos.x * 0.5f,
const float noise3 = s_perlinNoise.noise( hitPos.x * 0.5f,
hitPos.y * 0.5f,
hitPos.z * 0.5f ) - 0.5f;
@ -294,23 +309,23 @@ SFVEC3F CMETALBRUSHEDNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo
const SFVEC3F hitPosRelative = hitPos - glm::floor( hitPos );
const float noiseX = (m_perlin.noise( hitPos.x * (60.0f),
const float noiseX = (s_perlinNoise.noise( hitPos.x * (60.0f),
hitPos.y * 1.0f,
hitPos.z * 1.0f ) - 0.5f);
const float noiseY = (m_perlin.noise( hitPos.x * 1.0f,
const float noiseY = (s_perlinNoise.noise( hitPos.x * 1.0f,
hitPos.y * (60.0f),
hitPos.z * 1.0f ) - 0.5f);
const float noise2 = (m_perlin.noise( hitPos.x * 1.0f,
const float noise2 = (s_perlinNoise.noise( hitPos.x * 1.0f,
hitPos.y * 1.0f,
hitPos.z * 1.0f ) - 0.5f);
const float noise3X = (m_perlin.noise( hitPos.x * (80.0f + noise2 * 0.5f),
const float noise3X = (s_perlinNoise.noise( hitPos.x * (80.0f + noise2 * 0.5f),
hitPos.y * 0.5f,
hitPos.z * 0.5f ) - 0.5f );
const float noise3Y = (m_perlin.noise( hitPos.x * 0.5f,
const float noise3Y = (s_perlinNoise.noise( hitPos.x * 0.5f,
hitPos.y * (80.0f + noise2 * 0.5f),
hitPos.z * 0.5f ) - 0.5f );

View File

@ -98,7 +98,30 @@ public:
const HITINFO &aHitInfo ) const override;
private:
const CPROCEDURALGENERATOR *m_board_normal_generator;
PerlinNoise m_copper_perlin;
float m_scale;
};
class CPLATEDCOPPERNORMAL : public CPROCEDURALGENERATOR
{
public:
CPLATEDCOPPERNORMAL() : CPROCEDURALGENERATOR()
{
m_scale = 1.0f;
}
CPLATEDCOPPERNORMAL( float aScale )
{
m_scale = 1.0f / aScale;
}
virtual ~CPLATEDCOPPERNORMAL()
{
}
// Imported from CPROCEDURALGENERATOR
SFVEC3F Generate( const RAY &aRay,
const HITINFO &aHitInfo ) const override;
private:
float m_scale;
};
@ -140,7 +163,6 @@ public:
SFVEC3F Generate( const RAY &aRay,
const HITINFO &aHitInfo ) const override;
private:
PerlinNoise m_perlin;
float m_scale;
};
@ -164,7 +186,6 @@ public:
SFVEC3F Generate( const RAY &aRay,
const HITINFO &aHitInfo ) const override;
private:
PerlinNoise m_perlin;
float m_scale;
};
@ -187,7 +208,6 @@ public:
SFVEC3F Generate( const RAY &aRay,
const HITINFO &aHitInfo ) const override;
private:
PerlinNoise m_perlin;
float m_scale;
};