Skip to content

Commit 6643f2f

Browse files
darksylinciche033
authored andcommitted
Use clipping distance for minimum LIDAR distance (#365)
* Use clipping distance for minimum LIDAR distance Using Hlms custom pieces and a listener to implement it See changes to Ogre2GpuRays::Render for usage Update ogre2/src/media/Hlms/Pbs/GLSL/VertexShader_vs.glsl to latest upstream version Signed-off-by: Matias N. Goldberg <[email protected]> * Add gl_ClipDistance to low level material that needed it Needs Ogre 2.1 update to actually take effect The `num_clip_distances` keyword will otherwise be ignored Signed-off-by: Matias N. Goldberg <[email protected]>
1 parent 4153898 commit 6643f2f

12 files changed

+339
-2
lines changed

ogre2/include/ignition/rendering/ogre2/Ogre2RenderEngine.hh

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ namespace ignition
4949
//
5050
// forward declaration
5151
class Ogre2RenderEnginePrivate;
52+
class Ogre2IgnHlmsCustomizations;
5253

5354
/// \brief Plugin for loading ogre render engine
5455
class IGNITION_RENDERING_OGRE2_VISIBLE Ogre2RenderEnginePlugin :
@@ -170,6 +171,9 @@ namespace ignition
170171
/// \return a list of FSAA levels
171172
public: std::vector<unsigned int> FSAALevels() const;
172173

174+
/// \brief Retrieves Hlms customizations for tweaking them
175+
public: Ogre2IgnHlmsCustomizations& HlmsCustomizations();
176+
173177
/// \internal
174178
/// \brief Get a pointer to the Ogre overlay system.
175179
/// \return Pointer to the ogre overlay system.

ogre2/src/Ogre2GpuRays.cc

+23
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "ignition/rendering/ogre2/Ogre2Sensor.hh"
3434
#include "ignition/rendering/ogre2/Ogre2Visual.hh"
3535

36+
#include "Ogre2IgnHlmsCustomizations.hh"
3637
#include "Ogre2ParticleNoiseListener.hh"
3738

3839
#ifdef _MSC_VER
@@ -212,6 +213,16 @@ Ogre2LaserRetroMaterialSwitcher::Ogre2LaserRetroMaterialSwitcher(
212213
void Ogre2LaserRetroMaterialSwitcher::cameraPreRenderScene(
213214
Ogre::Camera * /*_cam*/)
214215
{
216+
{
217+
auto engine = Ogre2RenderEngine::Instance();
218+
Ogre2IgnHlmsCustomizations &hlmsCustomizations =
219+
engine->HlmsCustomizations();
220+
Ogre::Pass *pass =
221+
this->laserRetroSourceMaterial->getBestTechnique()->getPass(0u);
222+
pass->getVertexProgramParameters()->setNamedConstant(
223+
"ignMinClipDistance", hlmsCustomizations.minDistanceClip );
224+
}
225+
215226
// swap item to use v1 shader material
216227
// Note: keep an eye out for performance impact on switching materials
217228
// on the fly. We are not doing this often so should be ok.
@@ -308,6 +319,11 @@ void Ogre2LaserRetroMaterialSwitcher::cameraPostRenderScene(
308319
Ogre::SubItem *subItem = it.first;
309320
subItem->setDatablock(it.second);
310321
}
322+
323+
Ogre::Pass *pass =
324+
this->laserRetroSourceMaterial->getBestTechnique()->getPass(0u);
325+
pass->getVertexProgramParameters()->setNamedConstant(
326+
"ignMinClipDistance", 0.0f );
311327
}
312328

313329

@@ -1237,8 +1253,15 @@ void Ogre2GpuRays::Render()
12371253
{
12381254
this->scene->StartRendering();
12391255

1256+
auto engine = Ogre2RenderEngine::Instance();
1257+
Ogre2IgnHlmsCustomizations &hlmsCustomizations =
1258+
engine->HlmsCustomizations();
1259+
1260+
hlmsCustomizations.minDistanceClip =
1261+
static_cast<float>(this->NearClipPlane());
12401262
this->UpdateRenderTarget1stPass();
12411263
this->UpdateRenderTarget2ndPass();
1264+
hlmsCustomizations.minDistanceClip = -1;
12421265

12431266
this->scene->FlushGpuCommandsAndStartNewFrame(6u, false);
12441267
}
+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Copyright (C) 2021 Open Source Robotics Foundation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
#include "Ogre2IgnHlmsCustomizations.hh"
19+
20+
#ifdef _MSC_VER
21+
#pragma warning(push, 0)
22+
#endif
23+
#include <OgreCamera.h>
24+
#include <OgreHlms.h>
25+
#include <OgreRenderTarget.h>
26+
#include <OgreSceneManager.h>
27+
#include <OgreViewport.h>
28+
#ifdef _MSC_VER
29+
#pragma warning(pop)
30+
#endif
31+
32+
using namespace ignition;
33+
using namespace rendering;
34+
35+
//////////////////////////////////////////////////
36+
void Ogre2IgnHlmsCustomizations::preparePassHash(
37+
const Ogre::CompositorShadowNode */*_shadowNode*/,
38+
bool _casterPass, bool /*_dualParaboloid*/,
39+
Ogre::SceneManager */*_sceneManager*/,
40+
Ogre::Hlms *_hlms)
41+
{
42+
this->needsWorldPos = false;
43+
if (!_casterPass && this->MinDistanceClipEnabled())
44+
{
45+
const Ogre::int32 numClipPlanes =
46+
_hlms->_getProperty("hlms_pso_clip_distances");
47+
_hlms->_setProperty( "ign_spherical_clip_min_distance", 1 );
48+
_hlms->_setProperty( "ign_spherical_clip_idx", numClipPlanes );
49+
_hlms->_setProperty( "hlms_pso_clip_distances", numClipPlanes + 1 );
50+
51+
if (_hlms->getType() == Ogre::HLMS_UNLIT)
52+
{
53+
if (_hlms->_getProperty("hlms_global_clip_planes") == 0)
54+
{
55+
this->needsWorldPos = true;
56+
_hlms->_setProperty( "ign_spherical_clip_needs_worldPos", 1 );
57+
}
58+
}
59+
}
60+
}
61+
62+
//////////////////////////////////////////////////
63+
Ogre::uint32 Ogre2IgnHlmsCustomizations::getPassBufferSize(
64+
const Ogre::CompositorShadowNode */*_shadowNode*/,
65+
bool _casterPass, bool /*_dualParaboloid*/,
66+
Ogre::SceneManager */*_sceneManager*/) const
67+
{
68+
if (_casterPass || !this->MinDistanceClipEnabled())
69+
return 0u;
70+
71+
Ogre::uint32 bufferSize = sizeof(float) * 4u;
72+
if (this->needsWorldPos)
73+
bufferSize += sizeof(float) * 16u;
74+
75+
return bufferSize;
76+
}
77+
78+
//////////////////////////////////////////////////
79+
float* Ogre2IgnHlmsCustomizations::preparePassBuffer(
80+
const Ogre::CompositorShadowNode */*_shadowNode*/,
81+
bool _casterPass, bool /*_dualParaboloid*/,
82+
Ogre::SceneManager *_sceneManager,
83+
float *_passBufferPtr)
84+
{
85+
if (!_casterPass && this->MinDistanceClipEnabled())
86+
{
87+
Ogre::Camera *camera = _sceneManager->getCameraInProgress();
88+
const Ogre::Vector3 &camPos = camera->getDerivedPosition();
89+
90+
// float4 ignMinClipDistance_ignCameraPos
91+
*_passBufferPtr++ = this->minDistanceClip;
92+
*_passBufferPtr++ = camPos.x;
93+
*_passBufferPtr++ = camPos.y;
94+
*_passBufferPtr++ = camPos.z;
95+
96+
if (this->needsWorldPos)
97+
{
98+
// TODO(dark_sylinc): Modify Ogre to access HlmsUnlit::mPreparedPass
99+
// so we get the view matrix that's going to be used instead of
100+
// recalculating everything again (which can get complex if VR is
101+
// being used)
102+
const Ogre::RenderTarget *renderTarget =
103+
_sceneManager->getCurrentViewport()->getTarget();
104+
Ogre::Matrix4 projectionMatrix =
105+
camera->getProjectionMatrixWithRSDepth();
106+
if( renderTarget->requiresTextureFlipping() )
107+
{
108+
projectionMatrix[1][0] = -projectionMatrix[1][0];
109+
projectionMatrix[1][1] = -projectionMatrix[1][1];
110+
projectionMatrix[1][2] = -projectionMatrix[1][2];
111+
projectionMatrix[1][3] = -projectionMatrix[1][3];
112+
}
113+
114+
Ogre::Matrix4 invViewProj = (projectionMatrix *
115+
camera->getViewMatrix(true)).inverse();
116+
for (size_t i = 0; i < 16u; ++i)
117+
*_passBufferPtr++ = static_cast<float>(invViewProj[0][i]);
118+
}
119+
}
120+
return _passBufferPtr;
121+
}
+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Copyright (C) 2021 Open Source Robotics Foundation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
#ifndef IGNITION_RENDERING_OGRE2_OGRE2IGNHLMSCUSTOMIZATIONS_HH_
19+
#define IGNITION_RENDERING_OGRE2_OGRE2IGNHLMSCUSTOMIZATIONS_HH_
20+
21+
#include "ignition/rendering/config.hh"
22+
#include "ignition/rendering/ogre2/Export.hh"
23+
24+
#ifdef _MSC_VER
25+
#pragma warning(push, 0)
26+
#endif
27+
#include <OgreHlmsListener.h>
28+
#ifdef _MSC_VER
29+
#pragma warning(pop)
30+
#endif
31+
32+
namespace ignition
33+
{
34+
namespace rendering
35+
{
36+
inline namespace IGNITION_RENDERING_VERSION_NAMESPACE {
37+
//
38+
/// \brief Controls custom shader snippets of Hlms (both Pbs and Unlit):
39+
///
40+
/// - Toggles them on/off
41+
/// - Sends relevant data to the GPU buffers for shaders to use
42+
///
43+
/// This listener requires Hlms to have been created with the piece data
44+
/// files in ogre2/src/media/Hlms/Ignition registered
45+
///
46+
/// \internal
47+
/// \remark Public variables take effect immediately (i.e. for the
48+
/// next render)
49+
class IGNITION_RENDERING_OGRE2_VISIBLE Ogre2IgnHlmsCustomizations final :
50+
public Ogre::HlmsListener
51+
{
52+
public:
53+
virtual ~Ogre2IgnHlmsCustomizations() = default;
54+
55+
/// \brief
56+
/// \return Returns true if spherical clipping customizations should
57+
/// be active
58+
public: bool MinDistanceClipEnabled() const
59+
{
60+
return this->minDistanceClip >= 0.0f;
61+
}
62+
63+
/// \brief Determines which custom pieces we should activate
64+
/// \param _casterPass
65+
/// \param _hlms
66+
private: virtual void preparePassHash(
67+
const Ogre::CompositorShadowNode *_shadowNode,
68+
bool _casterPass, bool _dualParaboloid,
69+
Ogre::SceneManager *_sceneManager,
70+
Ogre::Hlms *_hlms) override;
71+
72+
/// \brief Tells Ogre the buffer data sent to GPU should be a little
73+
/// bigger to fit our data we need to send
74+
///
75+
/// This data is sent in Ogre2IgnHlmsCustomizations::preparePassBuffer
76+
/// \param _casterPass
77+
/// \param _hlms
78+
private: virtual Ogre::uint32 getPassBufferSize(
79+
const Ogre::CompositorShadowNode *_shadowNode,
80+
bool _casterPass, bool _dualParaboloid,
81+
Ogre::SceneManager *_sceneManager) const override;
82+
83+
/// \brief Sends our custom data to GPU buffers that our
84+
/// pieces activated in Ogre2IgnHlmsCustomizations::preparePassHash
85+
/// will need.
86+
///
87+
/// Bytes written must not exceed what we informed in getPassBufferSize
88+
/// \param _casterPass
89+
/// \param _sceneManager
90+
/// \param _passBufferPtr
91+
/// \return The pointer where Ogre should continue appending more data
92+
private: virtual float* preparePassBuffer(
93+
const Ogre::CompositorShadowNode *_shadowNode,
94+
bool _casterPass, bool _dualParaboloid,
95+
Ogre::SceneManager *_sceneManager,
96+
float *_passBufferPtr) override;
97+
98+
/// \brief Min distance to clip geometry against in a spherical manner
99+
/// (i.e. vertices that are too close to camera are clipped)
100+
/// Usually this means the min lidar distance
101+
///
102+
/// Regular near clip distance clips in a rectangular way, so
103+
/// it's not enough.
104+
///
105+
/// Set to a negative value to disable (0 does NOT disable it!)
106+
///
107+
/// See https://github.com/ignitionrobotics/ign-rendering/pull/356
108+
public: float minDistanceClip = -1.0f;
109+
110+
/// \brief When true, we're currently dealing with HlmsUnlit
111+
/// where we need to define and calculate `float3 worldPos`
112+
/// \internal
113+
private: bool needsWorldPos = false;
114+
};
115+
}
116+
}
117+
}
118+
#endif

ogre2/src/Ogre2RenderEngine.cc

+20
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "ignition/rendering/ogre2/Ogre2Scene.hh"
4242
#include "ignition/rendering/ogre2/Ogre2Storage.hh"
4343

44+
#include "Ogre2IgnHlmsCustomizations.hh"
4445

4546
class ignition::rendering::Ogre2RenderEnginePrivate
4647
{
@@ -50,6 +51,9 @@ class ignition::rendering::Ogre2RenderEnginePrivate
5051

5152
/// \brief A list of supported fsaa levels
5253
public: std::vector<unsigned int> fsaaLevels;
54+
55+
/// \brief Controls Hlms customizations for both PBS and Unlit
56+
public: ignition::rendering::Ogre2IgnHlmsCustomizations hlmsCustomizations;
5357
};
5458

5559
using namespace ignition;
@@ -659,6 +663,10 @@ void Ogre2RenderEngine::RegisterHlms()
659663

660664
Ogre::ArchiveManager &archiveManager = Ogre::ArchiveManager::getSingleton();
661665

666+
Ogre::Archive *customizationsArchiveLibrary =
667+
archiveManager.load( rootHlmsFolder + "Hlms/Ignition", "FileSystem",
668+
true );
669+
662670
{
663671
Ogre::HlmsUnlit *hlmsUnlit = 0;
664672
// Create & Register HlmsUnlit
@@ -678,13 +686,16 @@ void Ogre2RenderEngine::RegisterHlms()
678686
++libraryFolderPathIt;
679687
}
680688

689+
archiveUnlitLibraryFolders.push_back( customizationsArchiveLibrary );
690+
681691
// Create and register the unlit Hlms
682692
hlmsUnlit = OGRE_NEW Ogre::HlmsUnlit(archiveUnlit,
683693
&archiveUnlitLibraryFolders);
684694
Ogre::Root::getSingleton().getHlmsManager()->registerHlms(hlmsUnlit);
685695

686696
// disable writting debug output to disk
687697
hlmsUnlit->setDebugOutputPath(false, false);
698+
hlmsUnlit->setListener(&this->dataPtr->hlmsCustomizations);
688699
}
689700

690701
{
@@ -708,12 +719,15 @@ void Ogre2RenderEngine::RegisterHlms()
708719
++libraryFolderPathIt;
709720
}
710721

722+
archivePbsLibraryFolders.push_back( customizationsArchiveLibrary );
723+
711724
// Create and register
712725
hlmsPbs = OGRE_NEW Ogre::HlmsPbs(archivePbs, &archivePbsLibraryFolders);
713726
Ogre::Root::getSingleton().getHlmsManager()->registerHlms(hlmsPbs);
714727

715728
// disable writting debug output to disk
716729
hlmsPbs->setDebugOutputPath(false, false);
730+
hlmsPbs->setListener(&this->dataPtr->hlmsCustomizations);
717731
}
718732
}
719733

@@ -873,6 +887,12 @@ std::vector<unsigned int> Ogre2RenderEngine::FSAALevels() const
873887
return this->dataPtr->fsaaLevels;
874888
}
875889

890+
/////////////////////////////////////////////////
891+
Ogre2IgnHlmsCustomizations& Ogre2RenderEngine::HlmsCustomizations()
892+
{
893+
return this->dataPtr->hlmsCustomizations;
894+
}
895+
876896
/////////////////////////////////////////////////
877897
Ogre::v1::OverlaySystem *Ogre2RenderEngine::OverlaySystem() const
878898
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@property( ign_spherical_clip_min_distance )
2+
@piece( custom_passBuffer )
3+
#define ignMinClipDistance ignMinClipDistance_ignCameraPos.x
4+
#define ignCameraPos ignMinClipDistance_ignCameraPos.yzw
5+
float4 ignMinClipDistance_ignCameraPos;
6+
7+
@property( ign_spherical_clip_needs_worldPos )
8+
float4x4 invViewProj;
9+
@end
10+
@end
11+
@end

0 commit comments

Comments
 (0)