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 5e42cd1fca..c9968ff1f9 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 @@ -130,6 +130,8 @@ void C3D_RENDER_RAYTRACING::setupMaterials() 0.16f ); // reflection m_materials.m_SolderMask.SetCastShadows( true ); + m_materials.m_SolderMask.SetNrRefractionsSamples( 1 ); + m_materials.m_SolderMask.SetNrReflectionsSamples( 2 ); if( m_settings.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) ) m_materials.m_SolderMask.SetNormalPerturbator( &m_solder_mask_normal_perturbator ); @@ -147,6 +149,7 @@ void C3D_RENDER_RAYTRACING::setupMaterials() 0.0f ); // reflection m_materials.m_EpoxyBoard.SetAbsorvance( 10.0f ); + m_materials.m_EpoxyBoard.SetNrRefractionsSamples( 3 ); if( m_settings.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) ) m_materials.m_EpoxyBoard.SetNormalPerturbator( &m_board_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 eb216e03d9..ef1024f42f 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 @@ -1881,7 +1881,7 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, (objMaterial->GetReflection() > 0.0f) && m_settings.GetFlag( FL_RENDER_RAYTRACING_REFLECTIONS ) ) { - const unsigned int reflection_number_of_samples = 3; + const unsigned int reflection_number_of_samples = objMaterial->GetNrReflectionsSamples(); SFVEC3F sum_color = SFVEC3F(0.0f); @@ -1891,14 +1891,14 @@ 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 ); + // Apply some randomize to the reflected vector + const SFVEC3F random_reflectVector = + glm::normalize( reflectVector + + UniformRandomHemisphereDirection() * + 0.025f ); RAY reflectedRay; - reflectedRay.Init( hitPoint, reflectVector ); + reflectedRay.Init( hitPoint, random_reflectVector ); HITINFO reflectedHit; reflectedHit.m_tHit = std::numeric_limits::infinity(); @@ -1934,7 +1934,7 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, const float air_over_glass = airIndex / glassIndex; const float glass_over_air = glassIndex / airIndex; - float refractionRatio = aIsInsideObject?glass_over_air:air_over_glass; + const float refractionRatio = aIsInsideObject?glass_over_air:air_over_glass; SFVEC3F refractedVector; @@ -1945,50 +1945,68 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, { const float objTransparency = objMaterial->GetTransparency(); - // apply some randomize to the refracted vector - refractedVector = refractedVector + UniformRandomHemisphereDirection() * 0.2f * (1.0f - objTransparency); - refractedVector = glm::normalize( refractedVector ); - // 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 ) ) ) ); - RAY refractedRay; - refractedRay.Init( startPoint, refractedVector ); + const unsigned int refractions_number_of_samples = objMaterial->GetNrRefractionsSamples(); - HITINFO refractedHit; - refractedHit.m_tHit = std::numeric_limits::infinity(); + SFVEC3F sum_color = SFVEC3F(0.0f); - SFVEC3F refractedColor = objMaterial->GetAmbientColor(); - - if( m_accelerator->Intersect( refractedRay, refractedHit ) ) + for( unsigned int i = 0; i < refractions_number_of_samples; ++i ) { - refractedColor = shadeHit( aBgColor, - refractedRay, - refractedHit, - true, - aRecursiveLevel + 1, - is_testShadow ); + RAY refractedRay; - const SFVEC3F absorbance = ( SFVEC3F(1.0f) - diffuseColorObj ) * - (1.0f - objTransparency ) * - objMaterial->GetAbsorvance() * // Adjust falloff factor - -refractedHit.m_tHit; + if( refractions_number_of_samples > 1 ) + { + // apply some randomize to the refracted vector + const SFVEC3F randomizeRefractedVector = glm::normalize( refractedVector + + UniformRandomHemisphereDirection() * + 0.15f * + (1.0f - objTransparency) ); - const SFVEC3F transparency = SFVEC3F( expf( absorbance.r ), - expf( absorbance.g ), - expf( absorbance.b ) ); + refractedRay.Init( startPoint, randomizeRefractedVector ); + } + else + { + refractedRay.Init( startPoint, refractedVector ); + } - outColor = outColor * (1.0f - objTransparency) + - refractedColor * transparency * objTransparency; - } - else - { - outColor = outColor * (1.0f - objTransparency) + - refractedColor * objTransparency; + HITINFO refractedHit; + refractedHit.m_tHit = std::numeric_limits::infinity(); + + SFVEC3F refractedColor = objMaterial->GetAmbientColor(); + + if( m_accelerator->Intersect( refractedRay, refractedHit ) ) + { + refractedColor = shadeHit( aBgColor, + refractedRay, + refractedHit, + true, + aRecursiveLevel + 1, + false ); + + const SFVEC3F absorbance = ( SFVEC3F(1.0f) - diffuseColorObj ) * + (1.0f - objTransparency ) * + objMaterial->GetAbsorvance() * // Adjust falloff factor + -refractedHit.m_tHit; + + const SFVEC3F transparency = SFVEC3F( expf( absorbance.r ), + expf( absorbance.g ), + expf( absorbance.b ) ); + + sum_color += refractedColor * transparency * objTransparency; + } + else + { + sum_color += refractedColor * objTransparency; + } } + + outColor = outColor * (1.0f - objTransparency) + + (sum_color / SFVEC3F( (float)refractions_number_of_samples) ); } } } diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp index 6a6bca9010..540633d7b8 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp @@ -46,6 +46,8 @@ CMATERIAL::CMATERIAL() m_cast_shadows = true; m_reflection = 0.0f; m_absorbance = 1.0f; + m_refraction_nr_samples = 4; + m_reflections_nr_samples = 3; m_normal_perturbator = NULL; } @@ -76,6 +78,8 @@ CMATERIAL::CMATERIAL( const SFVEC3F &aAmbient, m_absorbance = 1.0f; m_reflection = aReflection; m_cast_shadows = true; + m_refraction_nr_samples = 4; + m_reflections_nr_samples = 3; m_normal_perturbator = NULL; } @@ -225,19 +229,21 @@ 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 * 0.1f, - hitPos.y * 0.1f, - hitPos.z * 0.1f) - 0.5f); + const float noise1 = m_perlin.noise( hitPos.x * 1.0f, + hitPos.y * 1.0f, + hitPos.z * 1.0f ) - 0.5f; - const float noise2 = (m_perlin.noise( hitPos.x * 4.0f, - hitPos.y * 4.0f, - hitPos.z * 4.0f ) - 0.5f); + const float noise2 = m_perlin.noise( hitPos.x * 1.5f, + hitPos.y * 1.5f, + hitPos.z * 2.0f ) - 0.5f; - const float noise3 = (m_perlin.noise( hitPos.x * 8.0f + Fast_RandFloat() * 0.10f, - hitPos.y * 8.0f + Fast_RandFloat() * 0.10f, - hitPos.z * 8.0f + Fast_RandFloat() * 0.10f ) - 0.5f); + const float noise3 = m_perlin.noise( hitPos.x * 2.0f, + hitPos.y * 2.0f, + hitPos.z * 2.0f ) - 0.5f; - return SFVEC3F( noise1 * 0.10f + noise2 * 0.20f + noise3 * 0.50f ); + return SFVEC3F( noise1 * noise2 * noise3 * 4.00f, + noise1 * expf(noise2) * noise3 * 4.00f, + noise3 * noise3 * 1.00f ); } @@ -251,17 +257,17 @@ 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, - hitPos.y * 0.05f, - hitPos.z * 0.05f ) - 0.5f); + const float noise1 = m_perlin.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, - hitPos.y * 0.2f, - hitPos.z * 0.2f ) - 0.5f); + const float noise2 = m_perlin.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, - hitPos.y * 0.5f, - hitPos.z * 0.5f ) - 0.5f); + const float noise3 = m_perlin.noise( hitPos.x * 0.5f, + hitPos.y * 0.5f, + hitPos.z * 0.5f ) - 0.5f; return SFVEC3F( noise1 * 0.5f, noise2 * 0.5f, noise3 * 0.5f ); } @@ -275,9 +281,9 @@ CMETALBRUSHEDNORMAL::CMETALBRUSHEDNORMAL( float aScale ) SFVEC3F CMETALBRUSHEDNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const { - SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale; + const SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale; - SFVEC3F hitPosRelative = hitPos - glm::floor( hitPos ); + const SFVEC3F hitPosRelative = hitPos - glm::floor( hitPos ); const float noiseX = (m_perlin.noise( hitPos.x * (60.0f), hitPos.y * 1.0f, @@ -292,20 +298,20 @@ SFVEC3F CMETALBRUSHEDNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo hitPos.z * 1.0f ) - 0.5f); const float noise3X = (m_perlin.noise( hitPos.x * (80.0f + noise2 * 0.5f), - hitPos.y * 0.5f + Fast_RandFloat() * 0.05f, + hitPos.y * 0.5f, hitPos.z * 0.5f ) - 0.5f ); - const float noise3Y = (m_perlin.noise( hitPos.x * 0.5f + Fast_RandFloat() * 0.05f, + const float noise3Y = (m_perlin.noise( hitPos.x * 0.5f, hitPos.y * (80.0f + noise2 * 0.5f), hitPos.z * 0.5f ) - 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 + Fast_RandFloat() ) ); + float sawX = (hitPosRelative.x + glm::sin( 10.0f * hitPos.x + 5.0f * noise2 + Fast_RandFloat() ) ); sawX = sawX * sawX * sawX; - 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; float xOut = sawX * noise3X * 0.17f + noiseX * 0.25f + noise3X * 0.57f; diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h index e605013323..3f7f907bec 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h @@ -183,8 +183,12 @@ public: float GetTransparency() const { return m_transparency; } float GetReflection() const { return m_reflection; } float GetAbsorvance() const { return m_absorbance; } + unsigned int GetNrRefractionsSamples() const { return m_refraction_nr_samples; } + unsigned int GetNrReflectionsSamples() const { return m_reflections_nr_samples; } void SetAbsorvance( float aAbsorvanceFactor ) { m_absorbance = aAbsorvanceFactor; } + void SetNrRefractionsSamples( unsigned int aNrRefractions ) { m_refraction_nr_samples = aNrRefractions; } + void SetNrReflectionsSamples( unsigned int aNrReflections ) { m_reflections_nr_samples = aNrReflections; } /** * @brief SetCastShadows - Set if the material can receive shadows @@ -228,10 +232,12 @@ protected: SFVEC3F m_emissiveColor; SFVEC3F m_specularColor; float m_shinness; - float m_transparency; ///< 1.0 is completely transparent, 0.0 completely opaque - float m_absorbance; ///< absorvance factor for the transparent material - float m_reflection; ///< 1.0 completely reflective, 0.0 no reflective - bool m_cast_shadows; ///< true if this object will block the light + float m_transparency; ///< 1.0 is completely transparent, 0.0 completely opaque + float m_absorbance; ///< absorvance factor for the transparent material + float m_reflection; ///< 1.0 completely reflective, 0.0 no reflective + bool m_cast_shadows; ///< true if this object will block the light + unsigned int m_refraction_nr_samples; ///< nr of rays that will be interpolated for this material if it is a transparent + unsigned int m_reflections_nr_samples; ///< nr of rays that will be interpolated for this material if it is reflective const CPROCEDURALGENERATOR *m_normal_perturbator; }; 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 905be5e163..ee51d44483 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/clayeritem.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/clayeritem.cpp @@ -324,7 +324,7 @@ bool CLAYERITEM::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const } -bool CLAYERITEM::IntersectP(const RAY &aRay , float aMaxDistance ) const +bool CLAYERITEM::IntersectP( const RAY &aRay , float aMaxDistance ) const { float tBBoxStart; float tBBoxEnd;