diff --git a/Shaders/Materials/Lambertian/Lambertian.frag.glsl b/Shaders/Materials/Lambertian/Lambertian.frag.glsl index 6611334bfad..302f2a05597 100644 --- a/Shaders/Materials/Lambertian/Lambertian.frag.glsl +++ b/Shaders/Materials/Lambertian/Lambertian.frag.glsl @@ -7,11 +7,21 @@ layout( location = 6 ) in vec3 in_lightVector; out vec4 out_color; void main() { - vec4 bc = getBaseColor( material, getPerVertexTexCoord() ); - vec3 normal = getWorldSpaceNormal(); + vec4 bc = getDiffuseColor( material, getPerVertexTexCoord() ); + vec3 normalWorld = getWorldSpaceNormal(); + vec3 tangentWorld = getWorldSpaceTangent(); // normalized tangent + vec3 binormalWorld = getWorldSpaceBiTangent(); // normalized bitangent + // Computing attributes using dfdx or dfdy must be done before discarding fragments if ( toDiscard( material, bc ) ) discard; + vec3 lightDir = normalize( in_lightVector ); // incident direction + normalWorld = getNormal( material, + getPerVertexTexCoord(), + normalWorld, + tangentWorld, + binormalWorld ); // normalized bump-mapped normal + vec3 le = lightContributionFrom( light, getWorldSpacePosition().xyz ); - out_color = vec4( bc.rgb * dot( normal, normalize( in_lightVector ) ) * le, 1 ); + out_color = vec4( (bc.rgb / Pi) * dot( normalWorld, lightDir ) * le, 1 ); } diff --git a/Shaders/Materials/Lambertian/Lambertian.glsl b/Shaders/Materials/Lambertian/Lambertian.glsl index bb1f8df94d4..812db5b091e 100644 --- a/Shaders/Materials/Lambertian/Lambertian.glsl +++ b/Shaders/Materials/Lambertian/Lambertian.glsl @@ -4,9 +4,11 @@ struct LambertianTextures { int hasColor; int hasMask; + int hasNormal; sampler2D color; sampler2D mask; + sampler2D normal; }; struct Material { @@ -17,8 +19,6 @@ struct Material { //------------------- VertexAttrib interface --------------------- vec4 getPerVertexBaseColor(); -vec3 getWorldSpaceNormal(); -#define DONT_USE_INPUT_TANGENT //---------------------------------------------------------------- const float Pi = 3.141592653589793; @@ -51,10 +51,18 @@ vec3 getSpecularColor( Material material, vec3 texCoord ) { return vec3( 0 ); } -// Return the world-space normal computed according to the microgeometry definition` -// As no normal map is defined, return N +// Return the world-space normal computed according to the microgeometry definition vec3 getNormal( Material material, vec3 texCoord, vec3 N, vec3 T, vec3 B ) { - return N; + if ( material.tex.hasNormal == 1 ) { + vec3 normalLocal = normalize( vec3( texture( material.tex.normal, texCoord.xy ) ) * 2 - 1 ); + mat3 tbn; + tbn[0] = T; + tbn[1] = B; + tbn[2] = N; + return normalize( tbn * normalLocal ); + } else { + return N; + } } // return true if the fragment must be condidered as transparent (either fully or partially) diff --git a/Shaders/Materials/Lambertian/Lambertian.vert.glsl b/Shaders/Materials/Lambertian/Lambertian.vert.glsl index bb0b82d5314..1139523c0a0 100644 --- a/Shaders/Materials/Lambertian/Lambertian.vert.glsl +++ b/Shaders/Materials/Lambertian/Lambertian.vert.glsl @@ -5,6 +5,7 @@ // declare expected attributes layout( location = 0 ) in vec3 in_position; layout( location = 1 ) in vec3 in_normal; +layout( location = 2 ) in vec3 in_tangent; layout( location = 4 ) in vec3 in_texcoord; layout( location = 5 ) in vec4 in_color; @@ -17,6 +18,7 @@ layout( location = 0 ) out vec3 out_position; layout( location = 1 ) out vec3 out_normal; layout( location = 2 ) out vec3 out_texcoord; layout( location = 3 ) out vec3 out_vertexcolor; +layout( location = 4 ) out vec3 out_tangent; layout( location = 6 ) out vec3 out_lightVector; // Main function for vertex shader @@ -46,5 +48,8 @@ void main() { vec3 normal = mat3( transform.worldNormal ) * in_normal; out_normal = normal; + vec3 tangent = mat3( transform.model ) * in_tangent; + out_tangent = tangent; + out_lightVector = getLightDirection( light, out_position ); } diff --git a/examples/DrawPrimitives/AllPrimitivesComponent.cpp b/examples/DrawPrimitives/AllPrimitivesComponent.cpp index 3437251299c..80abc24a2a0 100644 --- a/examples/DrawPrimitives/AllPrimitivesComponent.cpp +++ b/examples/DrawPrimitives/AllPrimitivesComponent.cpp @@ -693,35 +693,34 @@ void AllPrimitivesComponent::initialize() { data = l.loadFile( filename ); #endif if ( data != nullptr ) { - auto geomData = data->getGeometryData(); + const auto& geomData = data->getGeometryData(); for ( const auto& gd : geomData ) { std::shared_ptr mesh { nullptr }; switch ( gd->getType() ) { case Ra::Core::Asset::GeometryData::TRI_MESH: mesh = std::shared_ptr { - createMeshFromGeometryData( "logo", gd ) }; + createMeshFromGeometryData( "logo", gd.get() ) }; break; case Ra::Core::Asset::GeometryData::QUAD_MESH: mesh = std::shared_ptr { - createMeshFromGeometryData( "logo", gd ) }; + createMeshFromGeometryData( "logo", gd.get() ) }; break; case Ra::Core::Asset::GeometryData::POLY_MESH: mesh = std::shared_ptr { - createMeshFromGeometryData( "logo", gd ) }; + createMeshFromGeometryData( "logo", gd.get() ) }; break; default: break; } std::shared_ptr roMaterial; - const Core::Asset::MaterialData* md = - gd->hasMaterial() ? &( gd->getMaterial() ) : nullptr; + auto mm = gd->hasMaterial() ? gd->getMaterial().getMaterialModel() : nullptr; // First extract the material from asset or create a default one - if ( md != nullptr ) { + if ( mm != nullptr ) { auto converter = - Data::EngineMaterialConverters::getMaterialConverter( md->getType() ); - auto mat = converter.second( md ); + Data::EngineMaterialConverters::getMaterialConverter( mm->getType() ); + auto mat = converter.second( mm.get() ); roMaterial.reset( mat ); } else { diff --git a/examples/RawShaderMaterial/main.cpp b/examples/RawShaderMaterial/main.cpp index f6be9e9401a..e5fe772fdb8 100644 --- a/examples/RawShaderMaterial/main.cpp +++ b/examples/RawShaderMaterial/main.cpp @@ -102,11 +102,11 @@ std::shared_ptr initQuad( Ra::Gui::BaseAppl paramProvider->setOrComputeTheParameterValues(); //! [Create the shader material] - Ra::Core::Asset::RawShaderMaterialData mat { "Quad Material", _config1, paramProvider }; + auto mat = std::make_shared( + "Quad Material", _config1, paramProvider ); //! [Create a geometry component using the custom material] - auto c = - new Ra::Engine::Scene::TriangleMeshComponent( "Quad Mesh", e, std::move( quad ), &mat ); + auto c = new Ra::Engine::Scene::TriangleMeshComponent( "Quad Mesh", e, std::move( quad ), mat ); //! [Register the entity/component association to the geometry system ] auto system = app.m_engine->getSystem( "GeometrySystem" ); diff --git a/examples/SimpleAnimation/main.cpp b/examples/SimpleAnimation/main.cpp index a8e019e8e2d..d22d9ef2199 100644 --- a/examples/SimpleAnimation/main.cpp +++ b/examples/SimpleAnimation/main.cpp @@ -3,8 +3,8 @@ #include // include the core geometry/appearance interface -#include #include +#include // include the Engine/entity/component/system/animation interface #include @@ -49,10 +49,11 @@ class KeyFramedGeometryComponent : public Ra::Engine::Scene::TriangleMeshCompone inline KeyFramedGeometryComponent( const std::string& name, Ra::Engine::Scene::Entity* entity, Ra::Core::Geometry::TriangleMesh&& mesh ) : - Ra::Engine::Scene::TriangleMeshComponent( name, - entity, - std::move( mesh ), - new Ra::Core::Asset::BlinnPhongMaterialData {} ), + Ra::Engine::Scene::TriangleMeshComponent( + name, + entity, + std::move( mesh ), + std::make_shared( name + "Material" ) ), m_transform( 0_ra, Ra::Core::Transform::Identity() ) { //! [Creating the transform KeyFrames] Ra::Core::Transform T = Ra::Core::Transform::Identity(); diff --git a/examples/TexturedQuad/main.cpp b/examples/TexturedQuad/main.cpp index 7cc38dabe7a..d8f8d589e39 100644 --- a/examples/TexturedQuad/main.cpp +++ b/examples/TexturedQuad/main.cpp @@ -3,8 +3,8 @@ #include // include the Engine/entity/component interface -#include #include +#include #include #include #include @@ -43,17 +43,18 @@ int main( int argc, char* argv[] ) { //! [Create an entity and component to draw or data] auto e = app.m_engine->getEntityManager()->createEntity( "Textured quad" ); - Ra::Core::Asset::BlinnPhongMaterialData matData( "myMaterialData" ); + auto matData = + std::make_shared( "myMaterialData" ); // remove glossy highlight - matData.m_specular = Ra::Core::Utils::Color::Black(); - matData.m_hasSpecular = true; + matData->m_ks = Ra::Core::Utils::Color::Black(); + matData->m_hasSpecular = true; - matData.m_hasTexDiffuse = true; + matData->m_hasTexDiffuse = true; // this name has to be the same as texManager added texture name - matData.m_texDiffuse = "myTexture"; + matData->m_texDiffuse = "myTexture"; // the entity get's this new component ownership. a bit wired since hidden in ctor. - new Ra::Engine::Scene::TriangleMeshComponent( "Quad Mesh", e, std::move( quad ), &matData ); + new Ra::Engine::Scene::TriangleMeshComponent( "Quad Mesh", e, std::move( quad ), matData ); //! [Create an entity and component to draw or data] //! [Tell the window that something is to be displayed] diff --git a/examples/TexturedQuadDynamic/main.cpp b/examples/TexturedQuadDynamic/main.cpp index 4ddc602f6cd..673a47e98c0 100644 --- a/examples/TexturedQuadDynamic/main.cpp +++ b/examples/TexturedQuadDynamic/main.cpp @@ -5,8 +5,8 @@ #include // include the Engine/entity/component interface -#include #include +#include #include #include #include @@ -48,17 +48,18 @@ int main( int argc, char* argv[] ) { //! [Create an entity and component to draw or data] auto e = app.m_engine->getEntityManager()->createEntity( "Textured quad" ); - Ra::Core::Asset::BlinnPhongMaterialData matData( "myMaterialData" ); + auto matData = + std::make_shared( "myMaterialData" ); // remove glossy highlight - matData.m_specular = Ra::Core::Utils::Color::Black(); - matData.m_hasSpecular = true; + matData->m_ks = Ra::Core::Utils::Color::Black(); + matData->m_hasSpecular = true; - matData.m_hasTexDiffuse = true; + matData->m_hasTexDiffuse = true; // this name has to be the same as texManager added texture name - matData.m_texDiffuse = "myTexture"; + matData->m_texDiffuse = "myTexture"; // the entity get's this new component ownership. a bit wired since hidden in ctor. - new Ra::Engine::Scene::TriangleMeshComponent( "Quad Mesh", e, std::move( quad ), &matData ); + new Ra::Engine::Scene::TriangleMeshComponent( "Quad Mesh", e, std::move( quad ), matData ); //! [Create an entity and component to draw or data] //! [Tell the window that something is to be displayed] diff --git a/src/Core/Asset/AnimationData.cpp b/src/Core/Asset/AnimationData.cpp index b4aa88ffca9..26e9b8fa23c 100644 --- a/src/Core/Asset/AnimationData.cpp +++ b/src/Core/Asset/AnimationData.cpp @@ -1,17 +1,20 @@ #include +#include + namespace Ra { namespace Core { namespace Asset { -HandleAnimation::HandleAnimation( const std::string& name ) : - m_name( name ), m_anim( -1, Transform::Identity() ) {} - -AnimationData::AnimationData( const std::string& name ) : - AssetData( name ), m_time(), m_dt( 0.0 ), m_keyFrame() {} - -AnimationData::~AnimationData() {} - +void AnimationData::displayInfo() const { + using namespace Core::Utils; // log + LOG( logDEBUG ) << "======== ANIMATION INFO ========"; + LOG( logDEBUG ) << " Name : " << getName(); + LOG( logDEBUG ) << " Start Time : " << m_time.getStart(); + LOG( logDEBUG ) << " End Time : " << m_time.getEnd(); + LOG( logDEBUG ) << " Time Step : " << m_dt; + LOG( logDEBUG ) << " Animated Object # : " << m_keyFrame.size(); +} } // namespace Asset } // namespace Core } // namespace Ra diff --git a/src/Core/Asset/AnimationData.hpp b/src/Core/Asset/AnimationData.hpp index 525431879df..81f99bb4e95 100644 --- a/src/Core/Asset/AnimationData.hpp +++ b/src/Core/Asset/AnimationData.hpp @@ -4,26 +4,27 @@ #include #include #include -#include #include #include namespace Ra { namespace Core { +using namespace Animation; namespace Asset { /** * A HandleAnimation stores data for an animation Handle. */ struct RA_CORE_API HandleAnimation { - explicit HandleAnimation( const std::string& name = "" ); + explicit HandleAnimation( const std::string& name = "" ) : + m_name( name ), m_anim( -1, Transform::Identity() ) {} /// The Handle's name. std::string m_name; /// The list of KeyFramed transforms applied to the Handle. - Core::Animation::KeyFramedValue m_anim; + KeyFramedValue m_anim; /// The AnimationTime for the Handle. AnimationTime m_animationTime; @@ -37,14 +38,8 @@ struct RA_CORE_API HandleAnimation { class RA_CORE_API AnimationData : public AssetData { public: - explicit AnimationData( const std::string& name = "" ); - - ~AnimationData(); - - /** - * Sets the name of the animation. - */ - inline void setName( const std::string& name ) { m_name = name; } + explicit AnimationData( const std::string& name = "" ) : + AssetData( name ), m_dt( 0.0 ), m_keyFrame() {} /// \name Time /// \{ @@ -59,12 +54,12 @@ class RA_CORE_API AnimationData : public AssetData */ inline void setTime( const AnimationTime& time ) { m_time = time; } /** - * \returns the animation timestep. + * \returns the animation time-step. */ inline AnimationTime::Time getTimeStep() const { return m_dt; } /** - * Sets the animation timestep. + * Sets the animation time-step.  */ inline void setTimeStep( const AnimationTime::Time& delta ) { m_dt = delta; } @@ -81,49 +76,32 @@ class RA_CORE_API AnimationData : public AssetData /** * \returns the list of HandleAnimations, i.e. the whole animation frames. */ - inline std::vector getHandleData() const { return m_keyFrame; } + inline const std::vector& getHandleData() const { return m_keyFrame; } /** * Sets the animation frames. */ - inline void setHandleData( const std::vector& frameList ); + inline void setHandleData( std::vector&& keyFrames ) { + m_keyFrame = std::move( keyFrames ); + } /// \} /** * Print stat info to the Debug output. */ - inline void displayInfo() const; + void displayInfo() const; - protected: + private: /// The AnimationTime for the object. AnimationTime m_time; - /// The animation timestep. + /// The animation time-step. AnimationTime::Time m_dt { 0 }; /// The animation frames. std::vector m_keyFrame; }; -inline void AnimationData::setHandleData( const std::vector& frameList ) { - const uint size = frameList.size(); - m_keyFrame.resize( size ); -#pragma omp parallel for - for ( int i = 0; i < int( size ); ++i ) { - m_keyFrame[i] = frameList[i]; - } -} - -inline void AnimationData::displayInfo() const { - using namespace Core::Utils; // log - LOG( logDEBUG ) << "======== ANIMATION INFO ========"; - LOG( logDEBUG ) << " Name : " << m_name; - LOG( logDEBUG ) << " Start Time : " << m_time.getStart(); - LOG( logDEBUG ) << " End Time : " << m_time.getEnd(); - LOG( logDEBUG ) << " Time Step : " << m_dt; - LOG( logDEBUG ) << " Animated Object # : " << m_keyFrame.size(); -} - } // namespace Asset } // namespace Core } // namespace Ra diff --git a/src/Core/Asset/AnimationTime.hpp b/src/Core/Asset/AnimationTime.hpp index 6eb774cb906..cb28b28795a 100644 --- a/src/Core/Asset/AnimationTime.hpp +++ b/src/Core/Asset/AnimationTime.hpp @@ -1,6 +1,6 @@ #pragma once - #include + #include #include @@ -20,13 +20,9 @@ class RA_CORE_API AnimationTime using Time = Scalar; AnimationTime( const Time& start = std::numeric_limits