3D-Viewer: improvements on reflections and on plastic normal texture

+ make the number of samples for reflection and refraction
parameterizable.
+ add some fuziness to reflection.
+ improvements on plastic normal texture
This commit is contained in:
Mario Luzeiro 2017-01-21 23:17:12 +01:00 committed by Chris Pavlina
parent aac13e7ae1
commit 840bcb5189
5 changed files with 102 additions and 69 deletions

View File

@ -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 );

View File

@ -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<float>::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<float>::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<float>::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) );
}
}
}

View File

@ -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;

View File

@ -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;
};

View File

@ -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;