Skip to content

Commit 4bb2154

Browse files
authored
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 dd8568a commit 4bb2154

12 files changed

+339
-2
lines changed

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

+4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ namespace ignition
4848
//
4949
// forward declaration
5050
class Ogre2RenderEnginePrivate;
51+
class Ogre2IgnHlmsCustomizations;
5152

5253
/// \brief Plugin for loading ogre render engine
5354
class IGNITION_RENDERING_OGRE2_VISIBLE Ogre2RenderEnginePlugin :
@@ -163,6 +164,9 @@ namespace ignition
163164
/// \return a list of FSAA levels
164165
public: std::vector<unsigned int> FSAALevels() const;
165166

167+
/// \brief Retrieves Hlms customizations for tweaking them
168+
public: Ogre2IgnHlmsCustomizations& HlmsCustomizations();
169+
166170
/// \internal
167171
/// \brief Get a pointer to the Ogre overlay system.
168172
/// \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
@@ -218,6 +219,16 @@ Ogre2LaserRetroMaterialSwitcher::Ogre2LaserRetroMaterialSwitcher(
218219
void Ogre2LaserRetroMaterialSwitcher::preRenderTargetUpdate(
219220
const Ogre::RenderTargetEvent & /*_evt*/)
220221
{
222+
{
223+
auto engine = Ogre2RenderEngine::Instance();
224+
Ogre2IgnHlmsCustomizations &hlmsCustomizations =
225+
engine->HlmsCustomizations();
226+
Ogre::Pass *pass =
227+
this->laserRetroSourceMaterial->getBestTechnique()->getPass(0u);
228+
pass->getVertexProgramParameters()->setNamedConstant(
229+
"ignMinClipDistance", hlmsCustomizations.minDistanceClip );
230+
}
231+
221232
// swap item to use v1 shader material
222233
// Note: keep an eye out for performance impact on switching materials
223234
// on the fly. We are not doing this often so should be ok.
@@ -314,6 +325,11 @@ void Ogre2LaserRetroMaterialSwitcher::postRenderTargetUpdate(
314325
Ogre::SubItem *subItem = it.first;
315326
subItem->setDatablock(it.second);
316327
}
328+
329+
Ogre::Pass *pass =
330+
this->laserRetroSourceMaterial->getBestTechnique()->getPass(0u);
331+
pass->getVertexProgramParameters()->setNamedConstant(
332+
"ignMinClipDistance", 0.0f );
317333
}
318334

319335

@@ -1130,8 +1146,15 @@ void Ogre2GpuRays::Render()
11301146
{
11311147
this->scene->StartRendering();
11321148

1149+
auto engine = Ogre2RenderEngine::Instance();
1150+
Ogre2IgnHlmsCustomizations &hlmsCustomizations =
1151+
engine->HlmsCustomizations();
1152+
1153+
hlmsCustomizations.minDistanceClip =
1154+
static_cast<float>(this->NearClipPlane());
11331155
this->UpdateRenderTarget1stPass();
11341156
this->UpdateRenderTarget2ndPass();
1157+
hlmsCustomizations.minDistanceClip = -1;
11351158

11361159
this->scene->FlushGpuCommandsAndStartNewFrame(6u, false);
11371160
}
+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;
@@ -645,6 +649,10 @@ void Ogre2RenderEngine::CreateResources()
645649

646650
Ogre::ArchiveManager &archiveManager = Ogre::ArchiveManager::getSingleton();
647651

652+
Ogre::Archive *customizationsArchiveLibrary =
653+
archiveManager.load( rootHlmsFolder + "Hlms/Ignition", "FileSystem",
654+
true );
655+
648656
{
649657
Ogre::HlmsUnlit *hlmsUnlit = 0;
650658
// Create & Register HlmsUnlit
@@ -664,13 +672,16 @@ void Ogre2RenderEngine::CreateResources()
664672
++libraryFolderPathIt;
665673
}
666674

675+
archiveUnlitLibraryFolders.push_back( customizationsArchiveLibrary );
676+
667677
// Create and register the unlit Hlms
668678
hlmsUnlit = OGRE_NEW Ogre::HlmsUnlit(archiveUnlit,
669679
&archiveUnlitLibraryFolders);
670680
Ogre::Root::getSingleton().getHlmsManager()->registerHlms(hlmsUnlit);
671681

672682
// disable writting debug output to disk
673683
hlmsUnlit->setDebugOutputPath(false, false);
684+
hlmsUnlit->setListener(&this->dataPtr->hlmsCustomizations);
674685
}
675686

676687
{
@@ -694,12 +705,15 @@ void Ogre2RenderEngine::CreateResources()
694705
++libraryFolderPathIt;
695706
}
696707

708+
archivePbsLibraryFolders.push_back( customizationsArchiveLibrary );
709+
697710
// Create and register
698711
hlmsPbs = OGRE_NEW Ogre::HlmsPbs(archivePbs, &archivePbsLibraryFolders);
699712
Ogre::Root::getSingleton().getHlmsManager()->registerHlms(hlmsPbs);
700713

701714
// disable writting debug output to disk
702715
hlmsPbs->setDebugOutputPath(false, false);
716+
hlmsPbs->setListener(&this->dataPtr->hlmsCustomizations);
703717
}
704718
}
705719

@@ -815,6 +829,12 @@ std::vector<unsigned int> Ogre2RenderEngine::FSAALevels() const
815829
return this->dataPtr->fsaaLevels;
816830
}
817831

832+
/////////////////////////////////////////////////
833+
Ogre2IgnHlmsCustomizations& Ogre2RenderEngine::HlmsCustomizations()
834+
{
835+
return this->dataPtr->hlmsCustomizations;
836+
}
837+
818838
/////////////////////////////////////////////////
819839
Ogre::v1::OverlaySystem *Ogre2RenderEngine::OverlaySystem() const
820840
{
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)