From ae8c62843ea0844df8e442802f152e2142e1d72b Mon Sep 17 00:00:00 2001 From: Mario Luzeiro Date: Sun, 2 Oct 2016 13:16:40 +0100 Subject: [PATCH] Raytracing: implement brushed metal perturbator --- .../c3d_render_createscene.cpp | 35 ++++++++-- .../c3d_render_raytracing.cpp | 10 +-- .../c3d_render_raytracing.h | 1 + .../3d_render_raytracing/cmaterial.cpp | 69 ++++++++++++++++--- .../3d_render_raytracing/cmaterial.h | 20 +++++- 5 files changed, 115 insertions(+), 20 deletions(-) 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 584f165299..4235a26d99 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 @@ -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 ); + } } } } 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 8e3aab4824..89cccb5967 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 @@ -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::infinity(); diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h index e2b1dc28da..e3493bdd7c 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h @@ -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; diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp index 7f53d77ce3..84facb31af 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp @@ -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 ); } diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h index 5303d76d99..2b70939d51 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h @@ -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