Raytracing: implement brushed metal perturbator

This commit is contained in:
Mario Luzeiro 2016-10-02 13:16:40 +01:00 committed by Wayne Stambaugh
parent 995fde8d9c
commit ae8c62843e
5 changed files with 115 additions and 20 deletions

View File

@ -67,6 +67,8 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
m_plastic_normal_perturbator = CPLASTICNORMAL( 0.15f * IU_PER_MM * m_settings.BiuTo3Dunits() );
m_plastic_shine_normal_perturbator = CPLASTICSHINENORMAL( 1.0f * IU_PER_MM * m_settings.BiuTo3Dunits() );
m_brushed_metal_normal_perturbator = CMETALBRUSHEDNORMAL( 1.0f * IU_PER_MM * m_settings.BiuTo3Dunits() );
}
// http://devernay.free.fr/cours/opengl/materials.html
@ -86,6 +88,8 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
if( m_settings.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
m_materials.m_Copper.SetNormalPerturbator( &m_copper_normal_perturbator );
m_materials.m_Paste = CBLINN_PHONG_MATERIAL(
(SFVEC3F)m_settings.m_SolderPasteColor *
(SFVEC3F)m_settings.m_SolderPasteColor, // ambient
@ -1312,10 +1316,17 @@ void C3D_RENDER_RAYTRACING::add_3D_models( const S3DMODEL *a3DModel,
{
const SMATERIAL &material = a3DModel->m_Materials[imat];
const float reflectionFactor = glm::clamp( material.m_Shininess *
0.75f - 0.125f,
0.0f,
1.0f );
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtaW4oc3FydCh4LTAuMzUpKjAuNDAtMC4wNSwxLjApIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMC4wNzA3NzM2NzMyMzY1OTAxMiIsIjEuNTY5NTcxNjI5MjI1NDY5OCIsIi0wLjI3NDYzNTMyMTc1OTkyOTMiLCIwLjY0NzcwMTg4MTkyNTUzNjIiXSwic2l6ZSI6WzY0NCwzOTRdfV0-
float reflectionFactor = 0.0f;
if( (material.m_Shininess - 0.35f) > FLT_EPSILON )
{
reflectionFactor = glm::clamp( glm::sqrt( (material.m_Shininess - 0.35f) ) *
0.40f - 0.05f,
0.0f,
0.5f );
}
CBLINN_PHONG_MATERIAL &blinnMaterial = (*materialVector)[imat];
@ -1354,7 +1365,21 @@ void C3D_RENDER_RAYTRACING::add_3D_models( const S3DMODEL *a3DModel,
(glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) > 0.25f) ||
(glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) > 0.25f) ) )
{
blinnMaterial.SetNormalPerturbator( &m_plastic_shine_normal_perturbator );
// This may be a color plastic ...
blinnMaterial.SetNormalPerturbator( &m_plastic_shine_normal_perturbator );
}
else
{
if( ( RGBtoGray(material.m_Diffuse) > 0.6f ) &&
( material.m_Shininess > 0.35f ) &&
( material.m_Transparency == 0.0f ) &&
( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.40f) &&
(glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.40f) &&
(glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.40f) ) )
{
// This may be a brushed metal
blinnMaterial.SetNormalPerturbator( &m_brushed_metal_normal_perturbator );
}
}
}
}

View File

@ -2167,13 +2167,13 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
for( unsigned int i = 0; i < reflection_number_of_samples; ++i )
{
// If we want to apply some randomize to the reflected vector
const SFVEC3F random_reflectVector =
glm::normalize( reflectVector +
UniformRandomHemisphereDirection() *
0.02f );
// const SFVEC3F random_reflectVector =
// glm::normalize( reflectVector +
// UniformRandomHemisphereDirection() *
// 0.02f );
RAY reflectedRay;
reflectedRay.Init( hitPoint, random_reflectVector );
reflectedRay.Init( hitPoint, reflectVector );
HITINFO reflectedHit;
reflectedHit.m_tHit = std::numeric_limits<float>::infinity();

View File

@ -101,6 +101,7 @@ private:
CSOLDERMASKNORMAL m_solder_mask_normal_perturbator;
CPLASTICNORMAL m_plastic_normal_perturbator;
CPLASTICSHINENORMAL m_plastic_shine_normal_perturbator;
CMETALBRUSHEDNORMAL m_brushed_metal_normal_perturbator;
bool m_isPreview;

View File

@ -204,7 +204,7 @@ SFVEC3F CSOLDERMASKNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo )
{
const SFVEC3F copperNormal = m_copper_normal_generator->Generate( aRay, aHitInfo );
return copperNormal * SFVEC3F(0.20f);
return copperNormal * SFVEC3F(0.10f);
}
else
return SFVEC3F(0.0f);
@ -245,15 +245,66 @@ CPLASTICSHINENORMAL::CPLASTICSHINENORMAL( float aScale )
SFVEC3F CPLASTICSHINENORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{
SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
const float noise1 = (m_perlin.noise( hitPos.x,
hitPos.y,
hitPos.z ) - 0.5f);
const float noise1 = (m_perlin.noise( hitPos.x,
hitPos.y,
hitPos.z ) - 0.5f);
const float noise2 = (m_perlin.noise( hitPos.x * 3.0f,
hitPos.y * 3.0f,
hitPos.z * 3.0f ) - 0.5f);
const float noise2 = (m_perlin.noise( hitPos.x * 3.0f,
hitPos.y * 3.0f,
hitPos.z * 3.0f ) - 0.5f);
return SFVEC3F( noise1 * 0.09f + noise2 * 0.05f );
return SFVEC3F( noise1 * 0.09f + noise2 * 0.05f );
}
CMETALBRUSHEDNORMAL::CMETALBRUSHEDNORMAL( float aScale )
{
m_scale = 1.0f / aScale;
}
SFVEC3F CMETALBRUSHEDNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{
SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
SFVEC3F hitPosRelative = hitPos - glm::floor( hitPos );
const float noiseX = (m_perlin.noise( hitPos.x * 20.0f,
hitPos.y * 0.1f,
hitPos.z * 0.1f ) - 0.5f);
const float noiseY = (m_perlin.noise( hitPos.x * 0.1f,
hitPos.y * 20.0f,
hitPos.z * 0.1f ) - 0.5f);
const float noise2 = (m_perlin.noise( hitPos.x * 1.0f,
hitPos.y * 0.1f,
hitPos.z * 0.1f ) - 0.5f);
const float noise3X = (m_perlin.noise( hitPos.x * 100.0f + Fast_RandFloat() * 0.1f,
hitPos.y * 0.05f,
hitPos.z * 0.05f ) - 0.5f);
const float noise3Y = (m_perlin.noise( hitPos.x * 0.05f,
hitPos.y * 100.0f + Fast_RandFloat() * 0.1f,
hitPos.z * 0.05f ) - 0.5f);
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgtZmxvb3IoeCkpK3Npbih4KSleMyIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi02LjcxNDAwMDAxOTAzMDA3NyIsIjcuMjQ0NjQzNjkyOTY5NzM5IiwiLTMuMTU1NTUyNjAxNDUyNTg4IiwiNS40MzQzODE5OTA1NDczMDY1Il0sInNpemUiOls2NDQsMzk0XX1d
// ((x - floor(x))+sin(x))^3
float sawX = (hitPosRelative.x + glm::sin(10.0f * hitPos.x + 5.0f * noise2) );
sawX = sawX * sawX * sawX;
float sawY = (hitPosRelative.y + glm::sin(10.0f * hitPos.y + 5.0f * noise2) );
sawY = sawY * sawY * sawY;
float xOut = sawX * noiseX * 0.02f + noiseX * 0.02f + noise3X * 0.15f;
float yOut = sawY * noiseY * 0.02f + noiseY * 0.02f + noise3Y * 0.15f;
xOut = glm::clamp( xOut * 1.0f, -0.20f, 0.20f );
yOut = glm::clamp( yOut * 1.0f, -0.20f, 0.20f );
return SFVEC3F( xOut, yOut, noise2 * 0.01f );
}

View File

@ -125,7 +125,7 @@ private:
};
// Procedural generation of the shining plastic normals
// Procedural generation of the shiny plastic normals
class CPLASTICSHINENORMAL : public CPROCEDURALGENERATOR
{
public:
@ -144,6 +144,24 @@ private:
float m_scale;
};
// Procedural generation of the shiny brushed metal
class CMETALBRUSHEDNORMAL : public CPROCEDURALGENERATOR
{
public:
CMETALBRUSHEDNORMAL() : CPROCEDURALGENERATOR()
{
m_scale = 1.0f;
}
CMETALBRUSHEDNORMAL( float aScale );
// Imported from CPROCEDURALGENERATOR
SFVEC3F Generate( const RAY &aRay,
const HITINFO &aHitInfo ) const override;
private:
PerlinNoise m_perlin;
float m_scale;
};
/// A base material class that can be used to derive a material implementation
class CMATERIAL