diff --git a/CMakeLists.txt b/CMakeLists.txt index bde066f92..b5e956aa0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ set(IGN_MATH_VER ${ignition-math6_VERSION_MAJOR}) # Find ignition-common ign_find_package(ignition-common3 REQUIRED COMPONENTS graphics events - VERSION 3.9) + VERSION 3.10) set(IGN_COMMON_VER ${ignition-common3_VERSION_MAJOR}) #-------------------------------------- diff --git a/examples/simple_demo/Main.cc b/examples/simple_demo/Main.cc index 36f09cf4c..6f70ba2e8 100644 --- a/examples/simple_demo/Main.cc +++ b/examples/simple_demo/Main.cc @@ -79,7 +79,7 @@ void buildScene(ScenePtr _scene) center->SetMaterial(green); root->AddChild(center); - +//! [red material] // create red material MaterialPtr red = _scene->CreateMaterial(); red->SetAmbient(0.5, 0.0, 0.0); @@ -87,6 +87,8 @@ void buildScene(ScenePtr _scene) red->SetSpecular(0.5, 0.5, 0.5); red->SetShininess(50); red->SetReflectivity(0); + red->SetRenderOrder(3); +//! [red material] // create sphere visual VisualPtr sphere = _scene->CreateVisual(); @@ -116,12 +118,15 @@ void buildScene(ScenePtr _scene) box->SetMaterial(blue); root->AddChild(box); +//! [white material] // create white material MaterialPtr white = _scene->CreateMaterial(); white->SetAmbient(0.5, 0.5, 0.5); white->SetDiffuse(0.8, 0.8, 0.8); white->SetReceiveShadows(true); white->SetReflectivity(0); + white->SetRenderOrder(0); +//! [white material] // create plane visual VisualPtr plane = _scene->CreateVisual(); @@ -131,6 +136,15 @@ void buildScene(ScenePtr _scene) plane->SetMaterial(white); root->AddChild(plane); + // create plane visual + VisualPtr plane2 = _scene->CreateVisual(); + plane2->AddGeometry(_scene->CreatePlane()); + plane2->SetLocalScale(5, 8, 1); + plane2->SetLocalPosition(4, 0.5, -0.5); + plane2->Scale(0.1, 0.1, 1); + plane2->SetMaterial(red); + root->AddChild(plane2); + // create axis visual VisualPtr axis = _scene->CreateAxisVisual(); axis->SetLocalPosition(4.0, 0.5, -0.4); diff --git a/include/ignition/rendering/Material.hh b/include/ignition/rendering/Material.hh index 5789c17ee..57d3f4017 100644 --- a/include/ignition/rendering/Material.hh +++ b/include/ignition/rendering/Material.hh @@ -322,6 +322,17 @@ namespace ignition /// \brief Removes any light map mapped to this material public: virtual void ClearLightMap() = 0; + /// \brief Set the render order. When polygons are coplanar, you can get + /// problems with 'depth fighting' where the pixels from the two polys + /// compete for the same screen pixel. This param help to avoid this + /// problem. + /// \param[in] _renderOrder Render order to set to + public: virtual void SetRenderOrder(const float _renderOrder) = 0; + + /// \brief Get the render order value of this material. + /// \return Material render order + public: virtual float RenderOrder() const = 0; + /// \brief Set the roughness value. Only affects material of type MT_PBS /// \param[in] _roughness Roughness to set to public: virtual void SetRoughness(const float _roughness) = 0; diff --git a/include/ignition/rendering/MeshDescriptor.hh b/include/ignition/rendering/MeshDescriptor.hh index ff6928a1d..ca71faf51 100644 --- a/include/ignition/rendering/MeshDescriptor.hh +++ b/include/ignition/rendering/MeshDescriptor.hh @@ -65,12 +65,16 @@ namespace ignition public: const common::Mesh *mesh = nullptr; IGN_COMMON_WARN_RESUME__DLL_INTERFACE_MISSING + IGN_COMMON_WARN_IGNORE__DLL_INTERFACE_MISSING /// \brief Name of the registered Mesh public: std::string meshName; + IGN_COMMON_WARN_RESUME__DLL_INTERFACE_MISSING + IGN_COMMON_WARN_IGNORE__DLL_INTERFACE_MISSING /// \brief Name of the sub-mesh to be loaded. An empty string signifies /// all sub-meshes should be loaded. public: std::string subMeshName; + IGN_COMMON_WARN_RESUME__DLL_INTERFACE_MISSING /// \brief Denotes if the loaded sub-mesh vertices should be centered public: bool centerSubMesh = false; diff --git a/include/ignition/rendering/base/BaseMaterial.hh b/include/ignition/rendering/base/BaseMaterial.hh index 275146f1e..f46513841 100644 --- a/include/ignition/rendering/base/BaseMaterial.hh +++ b/include/ignition/rendering/base/BaseMaterial.hh @@ -248,6 +248,12 @@ namespace ignition // Documentation inherited public: virtual void ClearLightMap() override; + // Documentation inherited + public: virtual void SetRenderOrder(const float _renderOrder) override; + + // Documentation inherited + public: virtual float RenderOrder() const override; + // Documentation inherited public: virtual void SetRoughness(const float _roughness) override; @@ -338,6 +344,9 @@ namespace ignition /// \brief Enable two sided rendering protected: bool twoSidedEnabled = false; + /// \brief Material render order + protected: double renderOrder = 0.0; + /// \brief Shininess factor protected: double shininess = 0.0; @@ -529,6 +538,13 @@ namespace ignition this->receiveShadows = _receive; } + ////////////////////////////////////////////////// + template + void BaseMaterial::SetRenderOrder(const float _renderorder) + { + this->renderOrder = _renderorder; + } + ////////////////////////////////////////////////// template math::Color BaseMaterial::Ambient() const @@ -571,6 +587,13 @@ namespace ignition return this->transparency; } + ////////////////////////////////////////////////// + template + float BaseMaterial::RenderOrder() const + { + return this->renderOrder; + } + ////////////////////////////////////////////////// template double BaseMaterial::Reflectivity() const @@ -923,6 +946,7 @@ namespace ignition this->SetDiffuse(_material->Diffuse()); this->SetSpecular(_material->Specular()); this->SetEmissive(_material->Emissive()); + this->SetRenderOrder(_material->RenderOrder()); this->SetShininess(_material->Shininess()); this->SetTransparency(_material->Transparency()); this->SetAlphaFromTexture(_material->TextureAlphaEnabled(), @@ -962,6 +986,7 @@ namespace ignition this->SetTransparency(_material.Transparency()); this->SetAlphaFromTexture(_material.TextureAlphaEnabled(), _material.AlphaThreshold(), _material.TwoSidedEnabled()); + this->SetRenderOrder(_material.RenderOrder()); // TODO(anyone): update common::Material this->SetReflectivity(0); this->SetTexture(_material.TextureImage()); @@ -1015,6 +1040,7 @@ namespace ignition this->SetDiffuse(1.0, 1.0, 1.0); this->SetSpecular(0.2, 0.2, 0.2); this->SetEmissive(0, 0, 0); + this->SetRenderOrder(0); this->SetShininess(1.5); this->SetTransparency(0); this->SetReflectivity(0); @@ -1026,6 +1052,7 @@ namespace ignition this->ClearRoughnessMap(); this->ClearMetalnessMap(); this->ClearEmissiveMap(); + this->ClearLightMap(); this->SetRoughness(kDefaultPbr.Roughness()); this->SetMetalness(kDefaultPbr.Metalness()); this->SetShaderType(ST_PIXEL); diff --git a/ogre/include/ignition/rendering/ogre/OgreMaterial.hh b/ogre/include/ignition/rendering/ogre/OgreMaterial.hh index 1e14fe3ef..77c41a2e3 100644 --- a/ogre/include/ignition/rendering/ogre/OgreMaterial.hh +++ b/ogre/include/ignition/rendering/ogre/OgreMaterial.hh @@ -103,6 +103,15 @@ namespace ignition public: virtual void SetReceiveShadows(const bool _receiveShadows) override; + // Documentation inherited + public: virtual float RenderOrder() const override; + + // Documentation inherited + // Review the official documentation to get more details about this + // parameter, in particular Ogre::Pass::setDepthBias() + // https://www.ogre3d.org/docs/api/1.8/class_ogre_1_1_pass.html + public: virtual void SetRenderOrder(const float _renderOrder) override; + public: virtual bool ReflectionEnabled() const override; public: virtual void SetReflectionEnabled(const bool _enabled) override; diff --git a/ogre/src/OgreMaterial.cc b/ogre/src/OgreMaterial.cc index a92132791..7bb90d0c4 100644 --- a/ogre/src/OgreMaterial.cc +++ b/ogre/src/OgreMaterial.cc @@ -156,6 +156,19 @@ void OgreMaterial::SetEmissive(const math::Color &_color) #endif } +////////////////////////////////////////////////// +float OgreMaterial::RenderOrder() const +{ + return this->renderOrder; +} + +////////////////////////////////////////////////// +void OgreMaterial::SetRenderOrder(const float _renderOrder) +{ + this->renderOrder = _renderOrder; + this->ogrePass->setDepthBias(this->renderOrder); +} + ////////////////////////////////////////////////// double OgreMaterial::Shininess() const { diff --git a/ogre2/include/ignition/rendering/ogre2/Ogre2Material.hh b/ogre2/include/ignition/rendering/ogre2/Ogre2Material.hh index eee3754e9..b7d6d90ef 100644 --- a/ogre2/include/ignition/rendering/ogre2/Ogre2Material.hh +++ b/ogre2/include/ignition/rendering/ogre2/Ogre2Material.hh @@ -71,6 +71,14 @@ namespace ignition public: virtual void SetAlphaFromTexture(bool _enabled, double _alpha = 0.5, bool _twoSided = true) override; + // Documentation inherited + public: virtual float RenderOrder() const override; + + // Documentation inherited + // Review the official documentation to get more details about this + // parameter, in particular mDepthBiasConstant + public: virtual void SetRenderOrder(const float _renderOrder) override; + // Documentation inherited public: virtual bool ReceiveShadows() const override; diff --git a/ogre2/src/Ogre2Material.cc b/ogre2/src/Ogre2Material.cc index 445434a7c..deb0a2f28 100644 --- a/ogre2/src/Ogre2Material.cc +++ b/ogre2/src/Ogre2Material.cc @@ -154,8 +154,8 @@ void Ogre2Material::SetAlphaFromTexture(bool _enabled, Ogre::HlmsBlendblock block; if (_enabled) { - block.setBlendType(Ogre::SBT_TRANSPARENT_ALPHA); this->ogreDatablock->setAlphaTest(Ogre::CMPF_GREATER_EQUAL); + block.setBlendType(Ogre::SBT_TRANSPARENT_ALPHA); this->ogreDatablock->setBlendblock(block); } else @@ -167,6 +167,22 @@ void Ogre2Material::SetAlphaFromTexture(bool _enabled, this->ogreDatablock->setTwoSidedLighting(_twoSided); } +////////////////////////////////////////////////// +float Ogre2Material::RenderOrder() const +{ + return this->renderOrder; +} + +////////////////////////////////////////////////// +void Ogre2Material::SetRenderOrder(const float _renderOrder) +{ + this->renderOrder = _renderOrder; + Ogre::HlmsMacroblock macroblock( + *this->ogreDatablock->getMacroblock()); + macroblock.mDepthBiasConstant = _renderOrder; + this->ogreDatablock->setMacroblock(macroblock); +} + ////////////////////////////////////////////////// bool Ogre2Material::ReceiveShadows() const { diff --git a/tutorials.md.in b/tutorials.md.in index 28beae56a..6b248afcb 100644 --- a/tutorials.md.in +++ b/tutorials.md.in @@ -22,6 +22,7 @@ Ignition @IGN_DESIGNATION_CAP@ library and how to use the library effectively. 8. \subpage simple_demo "Simple demo" 9. \subpage text_geom "Text geom" 10. \subpage particles "Particles" +11. \subpage render_order "Render Order" ## License diff --git a/tutorials/21_render_order.md b/tutorials/21_render_order.md new file mode 100644 index 000000000..c6a37daf3 --- /dev/null +++ b/tutorials/21_render_order.md @@ -0,0 +1,52 @@ +\page render_order Render order + +This example shows how to set the render order for coplanar polygons. + +The material API allows changing the render order. When polygons are coplanar, you can get problems +with `depth fighting` (also known as z fighting) where the pixels from the two polys compete for the same screen pixel. +As you can see in the following image: + +@image html img/render_order_bad.png + +The method `SetRenderOrder` in the Material class allows you to avoid this issue. The higher value will +be rendered on top of other coplanar polygons. This method will set the depth bias value of objects that the material is assigned to. + +In the `simple_demo` example you can find two materials with different render orders. The red material +(`SetRenderOrder(3)`) has a higher value than the white material (`SetRenderOrder(3)`). + +\snippet examples/simple_demo/Main.cc red material + +\snippet examples/simple_demo/Main.cc white material + +As you can see in the following image the depth fighting issue is resolved. + +@image html img/render_order_good.png + +You can set this in your SDF file including in the material tag a new tag called `render_order` with +a float value: + +```xml + + 5 + 0 0 1 1 + 0 0 1 1 + 0 0 1 1 + +``` + +Clone the source code, create a build directory and use `cmake` and `make` to compile the code: + +```{.sh} +git clone https://github.com/ignitionrobotics/ign-rendering +cd ign-rendering/examples/simple_demo +mkdir build +cd build +cmake .. +make +``` + +Execute the example: + +```{.sh} +./simple_demo +``` diff --git a/tutorials/img/render_order_bad.png b/tutorials/img/render_order_bad.png new file mode 100644 index 000000000..40ad77ca1 Binary files /dev/null and b/tutorials/img/render_order_bad.png differ diff --git a/tutorials/img/render_order_good.png b/tutorials/img/render_order_good.png new file mode 100644 index 000000000..1ecba8950 Binary files /dev/null and b/tutorials/img/render_order_good.png differ