@@ -68,6 +68,22 @@ class ignition::rendering::Ogre2MaterialPrivate
68
68
// / \brief Parameters to be bound to the fragment shader
69
69
public: ShaderParamsPtr fragmentShaderParams;
70
70
71
+ // / \brief Material to be used when rendering to special
72
+ // / cameras (e.g. sensors) like Ogre2GpuRays,
73
+ // / Ogre2LaserRetroMaterialSwitcher, etc
74
+ // /
75
+ // / It shares the same Vertex Shader, but uses a different
76
+ // / Pixel Shader
77
+ public: Ogre::MaterialPtr ogreSolidColorMat;
78
+
79
+ // / \brief A clone of plaincolor_fs. We need a clone
80
+ // / because some Metal needs to pair with the vertex shader they're
81
+ // / going to be used and Vulkan needs to have the same or a compatible
82
+ // / Root Layout profile.
83
+ // /
84
+ // / Used in ogreSolidColorMat
85
+ public: Ogre::HighLevelGpuProgramPtr ogreSolidColorShader;
86
+
71
87
// / \brief Returns the shader language code.
72
88
// / \param[in] _graphicsAPI The graphic API.
73
89
// / \return The shader language code string.
@@ -77,6 +93,8 @@ class ignition::rendering::Ogre2MaterialPrivate
77
93
{
78
94
case GraphicsAPI::OPENGL:
79
95
return " glsl" ;
96
+ case GraphicsAPI::VULKAN:
97
+ return " glslvk" ;
80
98
case GraphicsAPI::METAL:
81
99
return " metal" ;
82
100
default :
@@ -125,6 +143,13 @@ void Ogre2Material::Destroy()
125
143
Ogre::MaterialManager &matManager = Ogre::MaterialManager::getSingleton ();
126
144
matManager.remove (this ->ogreMaterial );
127
145
this ->ogreMaterial .reset ();
146
+
147
+ matManager.remove (this ->dataPtr ->ogreSolidColorMat );
148
+ this ->dataPtr ->ogreSolidColorMat .reset ();
149
+
150
+ Ogre::HighLevelGpuProgramManager::getSingleton ().remove (
151
+ this ->dataPtr ->ogreSolidColorShader );
152
+ this ->dataPtr ->ogreSolidColorShader .reset ();
128
153
}
129
154
130
155
Ogre::Root *root = Ogre2RenderEngine::Instance ()->OgreRoot ();
@@ -630,11 +655,15 @@ void Ogre2Material::UpdateShaderParams()
630
655
if (this ->dataPtr ->vertexShaderParams &&
631
656
this ->dataPtr ->vertexShaderParams ->IsDirty ())
632
657
{
633
- Ogre::GpuProgramParametersSharedPtr ogreParams;
634
- auto mat = this ->Material ();
635
- auto pass = mat->getTechnique (0u )->getPass (0 );
636
- ogreParams = pass->getVertexProgramParameters ();
637
- this ->UpdateShaderParams (this ->dataPtr ->vertexShaderParams , ogreParams);
658
+ Ogre::MaterialPtr mat[2 ] = { this ->Material (),
659
+ this ->dataPtr ->ogreSolidColorMat };
660
+ for (int i = 0 ; i < 2 ; ++i)
661
+ {
662
+ Ogre::GpuProgramParametersSharedPtr ogreParams;
663
+ auto pass = mat[i]->getTechnique (0u )->getPass (0 );
664
+ ogreParams = pass->getVertexProgramParameters ();
665
+ this ->UpdateShaderParams (this ->dataPtr ->vertexShaderParams , ogreParams);
666
+ }
638
667
this ->dataPtr ->vertexShaderParams ->ClearDirty ();
639
668
}
640
669
if (this ->dataPtr ->fragmentShaderParams &&
@@ -802,6 +831,43 @@ Ogre::MaterialPtr Ogre2Material::Material()
802
831
Ogre::MaterialManager &matManager = Ogre::MaterialManager::getSingleton ();
803
832
this ->ogreMaterial = matManager.create (this ->name ,
804
833
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
834
+
835
+ this ->dataPtr ->ogreSolidColorMat = matManager.create (
836
+ this ->name + " _solid" ,
837
+ Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
838
+
839
+ const auto graphicsApi = Ogre2RenderEngine::Instance ()->GraphicsAPI ();
840
+
841
+ this ->dataPtr ->ogreSolidColorShader =
842
+ Ogre::HighLevelGpuProgramManager::getSingleton ().createProgram (
843
+ " _ign_" + this ->name + " _solid_fs" ,
844
+ Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
845
+ this ->dataPtr ->shaderLanguageCode (graphicsApi),
846
+ Ogre::GpuProgramType::GPT_FRAGMENT_PROGRAM);
847
+
848
+ switch (graphicsApi)
849
+ {
850
+ case GraphicsAPI::OPENGL:
851
+ case GraphicsAPI::VULKAN:
852
+ this ->dataPtr ->ogreSolidColorShader ->setSourceFile (" plain_color_fs.glsl" );
853
+ break ;
854
+ case GraphicsAPI::DIRECT3D11:
855
+ this ->dataPtr ->ogreSolidColorShader ->setSourceFile (" plain_color_fs.hlsl" );
856
+ break ;
857
+ case GraphicsAPI::METAL:
858
+ this ->dataPtr ->ogreSolidColorShader ->setSourceFile (
859
+ " plain_color_fs.metal" );
860
+ break ;
861
+ default :
862
+ IGN_ASSERT (false , " Impossible path!" );
863
+ }
864
+
865
+ auto mat = this ->dataPtr ->ogreSolidColorMat ;
866
+ auto pass = mat->getTechnique (0u )->getPass (0 );
867
+ pass->setFragmentProgram (this ->dataPtr ->ogreSolidColorShader ->getName ());
868
+ auto psParams = pass->getFragmentProgramParameters ();
869
+ psParams->setNamedAutoConstant (" inColor" ,
870
+ Ogre::GpuProgramParameters::ACT_CUSTOM, 1u );
805
871
}
806
872
807
873
return this ->ogreMaterial ;
@@ -1136,11 +1202,37 @@ void Ogre2Material::SetVertexShader(const std::string &_path)
1136
1202
assert (!(vertexShader->hasCompileError ()));
1137
1203
assert (vertexShader->isSupported ());
1138
1204
1139
- auto mat = this ->Material ();
1140
- auto pass = mat->getTechnique (0u )->getPass (0 );
1141
- pass->setVertexProgram (vertexShader->getName ());
1142
- mat->compile ();
1143
- mat->load ();
1205
+ // Call it now to ensure ogreSolidColorShader is created
1206
+ auto mainMat = this ->Material ();
1207
+
1208
+ // We can set this setting now for the solid pixel shader
1209
+ // Metal needs this. Other APIs will ignore it.
1210
+ this ->dataPtr ->ogreSolidColorShader ->setParameter (
1211
+ " shader_reflection_pair_hint" , vertexShader->getName ());
1212
+
1213
+ Ogre::MaterialPtr mat[2 ] = { mainMat, this ->dataPtr ->ogreSolidColorMat };
1214
+
1215
+ for (int i = 0 ; i < 2 ; ++i)
1216
+ {
1217
+ auto pass = mat[i]->getTechnique (0u )->getPass (0 );
1218
+ pass->setVertexProgram (vertexShader->getName ());
1219
+ mat[i]->compile ();
1220
+ mat[i]->load ();
1221
+ }
1222
+
1223
+ if (this ->dataPtr ->ogreSolidColorMat ->getNumSupportedTechniques () == 0u )
1224
+ {
1225
+ ignwarn
1226
+ << " Material '" << this ->Name ()
1227
+ << " ' could not be paired with special pixel shader '"
1228
+ << this ->dataPtr ->ogreSolidColorShader ->getSourceFile ()
1229
+ << " ' See Ogre.log for details. This shader is used for special "
1230
+ " rendering in sensors (e.g. Lidar, Thermal). Your vertex shader "
1231
+ " must have a compatible signature if you want it to work.\n "
1232
+ " See https://github.com/ignitionrobotics/ign-rendering/issues/544\n "
1233
+ " If this issue isn't fixed, sensor rendering MIGHT not be correct"
1234
+ " if your vertex shader performs custom geometry deformation" ;
1235
+ }
1144
1236
1145
1237
this ->dataPtr ->vertexShaderPath = _path;
1146
1238
this ->dataPtr ->vertexShaderParams .reset (new ShaderParams);
0 commit comments