Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ PointCloudCommon::PointCloudCommon(rviz_common::Display * display)
style_property_->addOption("Spheres", rviz_rendering::PointCloud::RM_SPHERES);
style_property_->addOption("Boxes", rviz_rendering::PointCloud::RM_BOXES);
style_property_->addOption("Tiles", rviz_rendering::PointCloud::RM_TILES);
style_property_->addOption("Depth Fade Points", rviz_rendering::PointCloud::RM_DEPTH_FADE_POINTS);

point_world_size_property_ = new rviz_common::properties::FloatProperty(
"Size (m)", 0.01f,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,6 @@
#define RVIZ_RENDERING_UP_PARAMETER 4
#define RVIZ_RENDERING_HIGHLIGHT_PARAMETER 5
#define RVIZ_RENDERING_AUTO_SIZE_PARAMETER 6
#define RVIZ_RENDERING_VIEWPORT_HEIGHT_PARAMETER 7

#endif // RVIZ_RENDERING__CUSTOM_PARAMETER_INDICES_HPP_
2 changes: 2 additions & 0 deletions rviz_rendering/include/rviz_rendering/objects/point_cloud.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class PointCloud : public Ogre::MovableObject
RM_SPHERES,
RM_TILES,
RM_BOXES,
RM_DEPTH_FADE_POINTS,
};

RVIZ_RENDERING_PUBLIC
Expand Down Expand Up @@ -313,6 +314,7 @@ class PointCloud : public Ogre::MovableObject
Ogre::MaterialPtr tile_material_;
Ogre::MaterialPtr box_material_;
Ogre::MaterialPtr current_material_;
Ogre::MaterialPtr depth_fade_point_material_;
float alpha_;

bool color_by_index_;
Expand Down
73 changes: 73 additions & 0 deletions rviz_rendering/ogre_media/materials/glsl120/depth_fade_point.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#version 120

// Vertex shader for point sprites with depth-based fading
// sets position, point size and alpha.

// This shader employs three techniques to simulate depth fading:
// 1. Scaling the rendered point shape based on world size and distance to the camera.
// 2. Reducing alpha based on distance to the camera for points smaller than a pixel.
// 3. Stochastic point removal for very small alphas to prevent alpha-related rendering artifacts.

uniform mat4 worldviewproj_matrix;
uniform mat4 worldview_matrix;
uniform mat4 projection_matrix;

uniform vec4 size; // size.x = world size of point sprites in world units [e.g. meters]
uniform float alpha; // global alpha multiplier
uniform float viewport_height; // Required to convert world size to pixel size

const float MAX_PIXEL_SIZE = 100.0; // Limit max point size to avoid high fill rate
const float MIN_ALPHA_THRESHOLD = 0.04; // Minimum alpha threshold for stochastic point removal

// Simple hash function (point -> float [0,1])
float hash21(vec3 p)
{
// add some randomness based on position
p = fract(p * 0.3183099 + 0.1);
p *= 17.0;
return fract(p.x * p.y * p.z * (p.x + p.y + p.z));
}

void main()
{
gl_Position = worldviewproj_matrix * gl_Vertex;

vec4 pos_rel_view = worldview_matrix * gl_Vertex;
float depth = -pos_rel_view.z;

if (depth < 1e-6)
{
// point is behind the camera, remove it
gl_Position.w = -1.0; // outside frustum
return;
}

float focal = projection_matrix[1][1];
// Perspective projection needs distance attenuation, orthographic does not.
// In OpenGL-style projection matrices, m[3][3] is 0 for perspective and 1 for ortho.
bool is_ortho = projection_matrix[3][3] > 0.5;

// Compute pixel size from world-size (size.x), projection scale and viewport height.
float depth_for_scale = is_ortho ? 1.0 : depth;
float pixelSize = size.x * focal / depth_for_scale * (viewport_height * 0.5);
gl_PointSize = clamp(pixelSize, 1.0, MAX_PIXEL_SIZE);

// For very small points, reduce alpha to create a fading effect
// alpha scales with pixel size squared (area)
float sizeAlpha = clamp(pixelSize * pixelSize, 0.0, 1.0);
float finalAlpha = gl_Color.a * alpha * sizeAlpha;

// Stochastic point removal for very small alphas
if (finalAlpha < MIN_ALPHA_THRESHOLD) {
float h = hash21(gl_Vertex.xyz) * MIN_ALPHA_THRESHOLD;
if (h > finalAlpha)
{
// remove point
gl_Position.w = -1.0; // outside frustum
return;
}
finalAlpha = MIN_ALPHA_THRESHOLD;
}

gl_FrontColor = vec4(gl_Color.rgb, finalAlpha);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#version 120

// Passes the fragment color

uniform vec4 highlight;


void main()
{
vec3 col = gl_Color.xyz + gl_Color.xyz * highlight.xyz;
gl_FragColor = vec4(col, gl_Color.a);
}
22 changes: 22 additions & 0 deletions rviz_rendering/ogre_media/materials/glsl120/glsl120.program
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ vertex_program rviz/glsl120/depth.vert glsl
}
}

vertex_program rviz/glsl120/depth_fade_point.vert glsl
{
source depth_fade_point.vert
default_params {
param_named_auto worldviewproj_matrix worldviewproj_matrix
param_named_auto worldview_matrix worldview_matrix
param_named_auto projection_matrix projection_matrix
param_named_auto size custom 0
param_named_auto viewport_height custom 7
param_named_auto alpha custom 1
}
}

fragment_program rviz/glsl120/flat_color.frag glsl
{
Expand All @@ -67,6 +79,16 @@ fragment_program rviz/glsl120/flat_color_circle.frag glsl
}


fragment_program rviz/glsl120/flat_color_no_alpha.frag glsl
{
source flat_color_no_alpha.frag
default_params
{
param_named_auto highlight custom 5
}
}


fragment_program rviz/glsl120/indexed_8bit_image.frag glsl
{
source indexed_8bit_image.frag
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
material rviz/PointCloudDepthFadePoint
{
technique gp
{
pass
{
alpha_rejection greater_equal 1
point_size_attenuation on
point_sprites on
vertex_program_ref rviz/glsl120/depth_fade_point.vert {}
fragment_program_ref rviz/glsl120/flat_color_no_alpha.frag {}
}
}

technique depth
{
scheme Depth
pass
{
point_size_attenuation on
vertex_program_ref rviz/glsl120/point.vert(with_depth) {}
fragment_program_ref rviz/glsl120/depth_circle.frag {}
}
}

technique selection_first_pass
{
scheme Pick
pass
{
point_size_attenuation on
vertex_program_ref rviz/glsl120/point.vert {}
fragment_program_ref rviz/glsl120/pickcolor_circle.frag {}
}
}

technique selection_second_pass
{
scheme Pick1
pass
{
point_size_attenuation on
vertex_program_ref rviz/glsl120/point.vert {}
fragment_program_ref rviz/glsl120/pass_color_circle.frag {}
}
}
}
34 changes: 33 additions & 1 deletion rviz_rendering/src/rviz_rendering/objects/point_cloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <OgreSharedPtr.h>
#include <OgreTechnique.h>
#include <OgreCamera.h>
#include <OgreViewport.h>

#include "rviz_rendering/custom_parameter_indices.hpp"
#include "rviz_rendering/logging.hpp"
Expand Down Expand Up @@ -155,6 +156,8 @@ uint32_t PointCloud::getVerticesPerPoint()
return 6;
case RM_BOXES:
return 36;
case RM_DEPTH_FADE_POINTS:
return 1;
default:
throw std::runtime_error("unexpected render_mode_");
}
Expand All @@ -178,6 +181,8 @@ float * PointCloud::getVertices()
return g_billboard_vertices;
case RM_BOXES:
return g_box_vertices;
case RM_DEPTH_FADE_POINTS:
return g_point_vertices;
default:
throw std::runtime_error("unexpected render_mode_");
}
Expand All @@ -198,6 +203,8 @@ Ogre::MaterialPtr PointCloud::getMaterialForRenderMode(RenderMode mode)
return Ogre::MaterialPtr(tile_material_);
case RM_BOXES:
return Ogre::MaterialPtr(box_material_);
case RM_DEPTH_FADE_POINTS:
return Ogre::MaterialPtr(depth_fade_point_material_);
default:
throw std::runtime_error("unexpected render_mode_");
}
Expand All @@ -220,20 +227,25 @@ PointCloud::PointCloud()
sphere_material_ = Ogre::MaterialManager::getSingleton().getByName("rviz/PointCloudSphere");
tile_material_ = Ogre::MaterialManager::getSingleton().getByName("rviz/PointCloudTile");
box_material_ = Ogre::MaterialManager::getSingleton().getByName("rviz/PointCloudBox");
depth_fade_point_material_ = Ogre::MaterialManager::getSingleton().getByName(
"rviz/PointCloudDepthFadePoint");

point_material_ = Ogre::MaterialPtr(point_material_)->clone(ss.str() + "Point");
square_material_ = Ogre::MaterialPtr(square_material_)->clone(ss.str() + "Square");
flat_square_material_ = Ogre::MaterialPtr(flat_square_material_)->clone(ss.str() + "FlatSquare");
sphere_material_ = Ogre::MaterialPtr(sphere_material_)->clone(ss.str() + "Sphere");
tile_material_ = Ogre::MaterialPtr(tile_material_)->clone(ss.str() + "Tiles");
box_material_ = Ogre::MaterialPtr(box_material_)->clone(ss.str() + "Box");
depth_fade_point_material_ = Ogre::MaterialPtr(depth_fade_point_material_)->clone(ss.str() +
"DepthFadePoint");

point_material_->load();
square_material_->load();
flat_square_material_->load();
sphere_material_->load();
tile_material_->load();
box_material_->load();
depth_fade_point_material_->load();

setAlpha(1.0f);
setRenderMode(RM_SPHERES);
Expand All @@ -258,13 +270,15 @@ PointCloud::~PointCloud()
sphere_material_->unload();
tile_material_->unload();
box_material_->unload();
depth_fade_point_material_->unload();

removeMaterial(point_material_);
removeMaterial(square_material_);
removeMaterial(flat_square_material_);
removeMaterial(sphere_material_);
removeMaterial(tile_material_);
removeMaterial(box_material_);
removeMaterial(depth_fade_point_material_);
}

const Ogre::AxisAlignedBox & PointCloud::getBoundingBox() const
Expand Down Expand Up @@ -443,13 +457,15 @@ void PointCloud::setAlpha(float alpha, bool per_point_alpha)
setAlphaBlending(sphere_material_);
setAlphaBlending(tile_material_);
setAlphaBlending(box_material_);
setAlphaBlending(depth_fade_point_material_);
} else {
setReplace(point_material_);
setReplace(square_material_);
setReplace(flat_square_material_);
setReplace(sphere_material_);
setReplace(tile_material_);
setReplace(box_material_);
setReplace(depth_fade_point_material_);
}

Ogre::Vector4 alpha4(alpha_, alpha_, alpha_, alpha_);
Expand Down Expand Up @@ -526,7 +542,7 @@ Ogre::RenderOperation::OperationType PointCloud::getRenderOperationType() const
if (current_mode_supports_geometry_shader_) {
op_type = Ogre::RenderOperation::OT_POINT_LIST;
} else {
if (render_mode_ == RM_POINTS) {
if (render_mode_ == RM_POINTS || render_mode_ == RM_DEPTH_FADE_POINTS) {
op_type = Ogre::RenderOperation::OT_POINT_LIST;
} else {
op_type = Ogre::RenderOperation::OT_TRIANGLE_LIST;
Expand Down Expand Up @@ -674,6 +690,20 @@ void PointCloud::resetBoundingBoxForCurrentPoints()
void PointCloud::_notifyCurrentCamera(Ogre::Camera * camera)
{
Ogre::MovableObject::_notifyCurrentCamera(camera);
if (!camera) {
return;
}

Ogre::Viewport * vp = camera->getViewport();
if (!vp) {
return;
}

float height = static_cast<float>(vp->getActualHeight());
Ogre::Vector4 vh(height, 0.0f, 0.0f, 0.0f);
for (auto & renderable : renderables_) {
renderable->setCustomParameter(RVIZ_RENDERING_VIEWPORT_HEIGHT_PARAMETER, vh);
}
}

void PointCloud::_updateRenderQueue(Ogre::RenderQueue * queue)
Expand Down Expand Up @@ -715,6 +745,8 @@ PointCloudRenderablePtr PointCloud::createRenderable(
rend->setCustomParameter(RVIZ_RENDERING_ALPHA_PARAMETER, alpha);
rend->setCustomParameter(RVIZ_RENDERING_HIGHLIGHT_PARAMETER, highlight);
rend->setCustomParameter(RVIZ_RENDERING_PICK_COLOR_PARAMETER, pick_col);
rend->setCustomParameter(RVIZ_RENDERING_VIEWPORT_HEIGHT_PARAMETER,
Ogre::Vector4(600.0f, 0.0f, 0.0f, 0.0f));
rend->setCustomParameter(RVIZ_RENDERING_NORMAL_PARAMETER, Ogre::Vector4(common_direction_));
rend->setCustomParameter(RVIZ_RENDERING_UP_PARAMETER, Ogre::Vector4(common_up_vector_));
if (getParentSceneNode()) {
Expand Down