From 3923010331438cb5c1aea8399942815dde80245a Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Thu, 27 Jun 2024 18:28:03 -0700 Subject: [PATCH 1/2] Fix 1st pass tex resoultion for lidars with FOV < 90% Signed-off-by: Ian Chen --- ogre2/src/Ogre2GpuRays.cc | 19 +++++++++++++------ test/integration/gpu_rays.cc | 18 +++++++++++++----- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/ogre2/src/Ogre2GpuRays.cc b/ogre2/src/Ogre2GpuRays.cc index 48e1dc5f6..82f619c3a 100644 --- a/ogre2/src/Ogre2GpuRays.cc +++ b/ogre2/src/Ogre2GpuRays.cc @@ -765,10 +765,13 @@ void Ogre2GpuRays::ConfigureCamera() // Configure first pass texture size // Each cubemap texture covers 90 deg FOV so determine number of samples // within the view for both horizontal and vertical FOV - unsigned int hs = static_cast( - GZ_PI * 0.5 / hfovAngle.Radian() * this->RangeCount()); - unsigned int vs = static_cast( - GZ_PI * 0.5 / vfovAngle * this->VerticalRangeCount()); + unsigned int hs = (hfovAngle.Radian() < GZ_PI_2) ? this->RangeCount() : + static_cast( + GZ_PI_2 / hfovAngle.Radian() * this->RangeCount()); + + unsigned int vs = (vfovAngle < GZ_PI_2) ? this->VerticalRangeCount() : + static_cast( + GZ_PI_2 / vfovAngle * this->VerticalRangeCount()); // get the max number from the two unsigned int v = std::max(hs, vs); @@ -782,12 +785,12 @@ void Ogre2GpuRays::ConfigureCamera() v |= v >> 16; v++; - // limit min texture size to 128 // This is needed for large fov with low sample count, // e.g. 360 degrees and only 4 samples. Otherwise the depth data returned are // inaccurate. // \todo(anyone) For small fov, we shouldn't need such a high min texture size - // requirement, e.g. a single ray lidar only needs 1x1 texture. Look for ways + // requirement, e.g. a single ray lidar only needs 1x1 texture. However, + // using lower res textures also give inaccurate results. Look for ways // to compute the optimal min texture size unsigned int min1stPassSamples = 128u; @@ -986,6 +989,7 @@ void Ogre2GpuRays::Setup1stPass() Ogre::TextureFlags::RenderToTexture, Ogre::TextureTypes::Type2D); this->dataPtr->colorTexture->setResolution(this->dataPtr->w1st, this->dataPtr->h1st); + this->dataPtr->colorTexture->setNumMipmaps(1u); this->dataPtr->colorTexture->setPixelFormat(Ogre::PFG_R16_UNORM); this->dataPtr->colorTexture->scheduleTransitionTo( Ogre::GpuResidency::Resident); @@ -996,6 +1000,7 @@ void Ogre2GpuRays::Setup1stPass() Ogre::TextureFlags::RenderToTexture, Ogre::TextureTypes::Type2D); this->dataPtr->depthTexture->setResolution(this->dataPtr->w1st, this->dataPtr->h1st); + this->dataPtr->depthTexture->setNumMipmaps(1u); this->dataPtr->depthTexture->setPixelFormat(Ogre::PFG_D32_FLOAT); this->dataPtr->depthTexture->scheduleTransitionTo( Ogre::GpuResidency::Resident); @@ -1006,6 +1011,7 @@ void Ogre2GpuRays::Setup1stPass() Ogre::TextureFlags::RenderToTexture, Ogre::TextureTypes::Type2D); this->dataPtr->particleTexture->setResolution(this->dataPtr->w1st / 2u, this->dataPtr->h1st/ 2u); + this->dataPtr->particleTexture->setNumMipmaps(1u); this->dataPtr->particleTexture->setPixelFormat(Ogre::PFG_RGBA8_UNORM); this->dataPtr->particleTexture->scheduleTransitionTo( Ogre::GpuResidency::Resident); @@ -1016,6 +1022,7 @@ void Ogre2GpuRays::Setup1stPass() Ogre::TextureFlags::RenderToTexture, Ogre::TextureTypes::Type2D); this->dataPtr->particleDepthTexture->setResolution(this->dataPtr->w1st / 2u, this->dataPtr->h1st / 2u); + this->dataPtr->particleDepthTexture->setNumMipmaps(1u); this->dataPtr->particleDepthTexture->setPixelFormat(Ogre::PFG_D32_FLOAT); this->dataPtr->particleDepthTexture->scheduleTransitionTo( Ogre::GpuResidency::Resident); diff --git a/test/integration/gpu_rays.cc b/test/integration/gpu_rays.cc index 63413af51..100d14ede 100644 --- a/test/integration/gpu_rays.cc +++ b/test/integration/gpu_rays.cc @@ -697,8 +697,8 @@ TEST_F(GpuRaysTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(SingleRay)) GTEST_SKIP() << "Unsupported on apple, see issue #35."; #endif - // Test GPU single ray box intersection. - // Place GPU above box looking downwards + // Test single ray box intersection. + // Place ray above box looking downwards // ray should intersect with center of box const double hMinAngle = 0.0; @@ -713,7 +713,7 @@ TEST_F(GpuRaysTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(SingleRay)) VisualPtr root = scene->RootVisual(); - // Create first ray caster + // Create ray caster gz::math::Pose3d testPose(gz::math::Vector3d(0, 0, 7), gz::math::Quaterniond(0, GZ_PI/2.0, 0)); @@ -731,7 +731,7 @@ TEST_F(GpuRaysTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(SingleRay)) // box in the center gz::math::Pose3d box01Pose(gz::math::Vector3d(0, 0, 4.5), - gz::math::Quaterniond::Identity); + gz::math::Quaterniond::Identity); VisualPtr visualBox1 = scene->CreateVisual("UnitBox1"); visualBox1->AddGeometry(scene->CreateBox()); visualBox1->SetWorldPosition(box01Pose.Pos()); @@ -756,7 +756,15 @@ TEST_F(GpuRaysTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(SingleRay)) double expectedRangeAtMidPointBox = testPose.Pos().Z() - (abs(box01Pose.Pos().Z()) + unitBoxSize/2); - // rays caster 1 should see box01 and box02 + // ray should detect box + EXPECT_NEAR(scan[mid], expectedRangeAtMidPointBox, LASER_TOL); + + gz::math::Pose3d newBox01Pose(gz::math::Vector3d(0, 0, 3.5), + gz::math::Quaterniond::Identity); + visualBox1->SetWorldPosition(newBox01Pose.Pos()); + gpuRays->Update(); + expectedRangeAtMidPointBox = testPose.Pos().Z() - + (abs(newBox01Pose.Pos().Z()) + unitBoxSize/2); EXPECT_NEAR(scan[mid], expectedRangeAtMidPointBox, LASER_TOL); c.reset(); From 5df10a07794d01f4377f07bd1cf4f12196ab37ae Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Fri, 28 Jun 2024 16:48:25 +0000 Subject: [PATCH 2/2] style Signed-off-by: Ian Chen --- test/integration/gpu_rays.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/gpu_rays.cc b/test/integration/gpu_rays.cc index 100d14ede..a5f18b826 100644 --- a/test/integration/gpu_rays.cc +++ b/test/integration/gpu_rays.cc @@ -754,7 +754,7 @@ TEST_F(GpuRaysTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(SingleRay)) int mid = 0; double unitBoxSize = 1.0; double expectedRangeAtMidPointBox = testPose.Pos().Z() - - (abs(box01Pose.Pos().Z()) + unitBoxSize/2); + (std::abs(box01Pose.Pos().Z()) + unitBoxSize / 2); // ray should detect box EXPECT_NEAR(scan[mid], expectedRangeAtMidPointBox, LASER_TOL); @@ -764,7 +764,7 @@ TEST_F(GpuRaysTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(SingleRay)) visualBox1->SetWorldPosition(newBox01Pose.Pos()); gpuRays->Update(); expectedRangeAtMidPointBox = testPose.Pos().Z() - - (abs(newBox01Pose.Pos().Z()) + unitBoxSize/2); + (std::abs(newBox01Pose.Pos().Z()) + unitBoxSize / 2); EXPECT_NEAR(scan[mid], expectedRangeAtMidPointBox, LASER_TOL); c.reset();