Skip to content

Commit

Permalink
Apply particle scattering effect to lidars (#252)
Browse files Browse the repository at this point in the history
Signed-off-by: Ian Chen <ichen@osrfoundation.org>
  • Loading branch information
iche033 committed Feb 17, 2021
1 parent 7c76651 commit 3f71f83
Show file tree
Hide file tree
Showing 5 changed files with 332 additions and 11 deletions.
86 changes: 84 additions & 2 deletions ogre2/src/Ogre2GpuRays.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "ignition/rendering/RenderTypes.hh"
#include "ignition/rendering/ogre2/Ogre2Conversions.hh"
#include "ignition/rendering/ogre2/Ogre2Includes.hh"
#include "ignition/rendering/ogre2/Ogre2ParticleEmitter.hh"
#include "ignition/rendering/ogre2/Ogre2RenderTarget.hh"
#include "ignition/rendering/ogre2/Ogre2RenderTypes.hh"
#include "ignition/rendering/ogre2/Ogre2Scene.hh"
Expand Down Expand Up @@ -162,6 +163,13 @@ class ignition::rendering::Ogre2GpuRaysPrivate
/// \brief Pointer to material switcher
public: std::unique_ptr<Ogre2LaserRetroMaterialSwitcher>
laserRetroMaterialSwitcher[6];

/// \brief standard deviation of particle noise
public: double particleStddev = 0.01;

/// \brief Particle scatter ratio. This is used to determine the ratio of
/// particles that will detected by the depth camera
public: double particleScatterRatio = 0.1;
};

using namespace ignition;
Expand Down Expand Up @@ -607,6 +615,10 @@ void Ogre2GpuRays::Setup1stPass()
static_cast<float>(this->dataMaxVal));
psParams->setNamedConstant("min",
static_cast<float>(this->dataMinVal));
psParams->setNamedConstant("particleStddev",
static_cast<float>(this->dataPtr->particleStddev));
psParams->setNamedConstant("particleScatterRatio",
static_cast<float>(this->dataPtr->particleScatterRatio));

// Create 1st pass compositor
auto engine = Ogre2RenderEngine::Instance();
Expand All @@ -622,6 +634,8 @@ void Ogre2GpuRays::Setup1stPass()
// in 0 rt_input
// texture depthTexture target_width target_height PF_D32_FLOAT
// texture colorTexture target_width target_height PF_R8G8B8
// texture particleTexture target_width target_height PF_L8
// texture particleDepthTexture target_width target_height PF_D32_FLOAT
// target colorTexture
// {
// pass clear
Expand All @@ -630,6 +644,18 @@ void Ogre2GpuRays::Setup1stPass()
// }
// pass render_scene
// {
// visibility_mask 0x11011111
// }
// }
// target particleTexture
// {
// pass clear
// {
// colour_value 0.0 0.0 0.0 1.0
// }
// pass render_scene
// {
// visibility_mask 0.00100000
// }
// }
// target rt_input
Expand Down Expand Up @@ -697,7 +723,42 @@ void Ogre2GpuRays::Setup1stPass()
colorTexDef->preferDepthTexture = true;
colorTexDef->fsaaExplicitResolve = false;

nodeDef->setNumTargetPass(2);
Ogre::TextureDefinitionBase::TextureDefinition *particleDepthTexDef =
nodeDef->addTextureDefinition("particleDepthTexture");
particleDepthTexDef->textureType = Ogre::TEX_TYPE_2D;
particleDepthTexDef->width = 0;
particleDepthTexDef->height = 0;
particleDepthTexDef->depth = 1;
particleDepthTexDef->numMipmaps = 0;
particleDepthTexDef->widthFactor = 0.5;
particleDepthTexDef->heightFactor = 0.5;
particleDepthTexDef->formatList = {Ogre::PF_D32_FLOAT};
particleDepthTexDef->fsaa = 0;
particleDepthTexDef->uav = false;
particleDepthTexDef->automipmaps = false;
particleDepthTexDef->hwGammaWrite = Ogre::TextureDefinitionBase::BoolFalse;
particleDepthTexDef->depthBufferId = Ogre::DepthBuffer::POOL_DEFAULT;

Ogre::TextureDefinitionBase::TextureDefinition *particleTexDef =
nodeDef->addTextureDefinition("particleTexture");
particleTexDef->textureType = Ogre::TEX_TYPE_2D;
particleTexDef->width = 0;
particleTexDef->height = 0;
particleTexDef->depth = 1;
particleTexDef->numMipmaps = 0;
particleTexDef->widthFactor = 0.5;
particleTexDef->heightFactor = 0.5;
particleTexDef->formatList = {Ogre::PF_R8G8B8};
particleTexDef->fsaa = 0;
particleTexDef->uav = false;
particleTexDef->automipmaps = false;
particleTexDef->hwGammaWrite = Ogre::TextureDefinitionBase::BoolFalse;
particleTexDef->depthBufferId = Ogre::DepthBuffer::POOL_DEFAULT;
particleTexDef->depthBufferFormat = Ogre::PF_D32_FLOAT;
particleTexDef->preferDepthTexture = true;
particleTexDef->fsaaExplicitResolve = false;

nodeDef->setNumTargetPass(3);

Ogre::CompositorTargetDef *colorTargetDef =
nodeDef->addTargetPass("colorTexture");
Expand All @@ -713,7 +774,26 @@ void Ogre2GpuRays::Setup1stPass()
static_cast<Ogre::CompositorPassSceneDef *>(
colorTargetDef->addPass(Ogre::PASS_SCENE));
// set camera custom visibility mask when rendering laser retro
passScene->mVisibilityMask = 0x01000000;
passScene->mVisibilityMask = 0x01000000 &
~Ogre2ParticleEmitter::kParticleVisibilityFlags;
}

Ogre::CompositorTargetDef *particleTargetDef =
nodeDef->addTargetPass("particleTexture");
particleTargetDef->setNumPasses(2);
{
// clear pass
Ogre::CompositorPassClearDef *passClear =
static_cast<Ogre::CompositorPassClearDef *>(
particleTargetDef->addPass(Ogre::PASS_CLEAR));
passClear->mColourValue = Ogre::ColourValue::Black;
// scene pass
Ogre::CompositorPassSceneDef *passScene =
static_cast<Ogre::CompositorPassSceneDef *>(
particleTargetDef->addPass(Ogre::PASS_SCENE));
// set camera custom visibility mask when rendering laser retro
passScene->mVisibilityMask =
Ogre2ParticleEmitter::kParticleVisibilityFlags;
}

// rt_input target - converts depth to range
Expand All @@ -733,6 +813,8 @@ void Ogre2GpuRays::Setup1stPass()
passQuad->mMaterialName = this->dataPtr->matFirstPass->getName();
passQuad->addQuadTextureSource(0, "depthTexture", 0);
passQuad->addQuadTextureSource(1, "colorTexture", 0);
passQuad->addQuadTextureSource(2, "particleDepthTexture", 0);
passQuad->addQuadTextureSource(3, "particleTexture", 0);
passQuad->mFrustumCorners =
Ogre::CompositorPassQuadDef::VIEW_SPACE_CORNERS;
}
Expand Down
61 changes: 55 additions & 6 deletions ogre2/src/media/materials/programs/gpu_rays_1st_pass_fs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ in block

uniform sampler2D depthTexture;
uniform sampler2D colorTexture;
uniform sampler2D particleDepthTexture;
uniform sampler2D particleTexture;

out vec4 fragColor;

Expand All @@ -34,19 +36,45 @@ uniform float far;
uniform float min;
uniform float max;

float getDepth(vec2 uv)
uniform float particleStddev;
uniform float particleScatterRatio;
uniform float time;

// see gaussian_noise_fs.glsl for documentation on the rand and gaussrand
// functions

#define PI 3.14159265358979323846264

float rand(vec2 co)
{
float fDepth = texture(depthTexture, uv).x;
float linearDepth = projectionParams.y / (fDepth - projectionParams.x);
return linearDepth;
float r = fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);
// Make sure that we don't return 0.0
if(r == 0.0)
return 0.000000000001;
else
return r;
}

vec4 gaussrand(vec2 co, vec3 offsets, float stddev, float mean)
{
float U, V, R, Z;
U = rand(co + vec2(offsets.x, offsets.x));
V = rand(co + vec2(offsets.y, offsets.y));
R = rand(co + vec2(offsets.z, offsets.z));
if(R < 0.5)
Z = sqrt(-2.0 * log(U)) * sin(2.0 * PI * V);
else
Z = sqrt(-2.0 * log(U)) * cos(2.0 * PI * V);
Z = Z * stddev + mean;
return vec4(Z, Z, Z, 0.0);
}

void main()
{
// get linear depth
float d = getDepth(inPs.uv0);

float fDepth = texture(depthTexture, inPs.uv0).x;
float d = projectionParams.y / (fDepth - projectionParams.x);

// get retro
float retro = texture(colorTexture, inPs.uv0).x * 2000.0;

Expand All @@ -56,6 +84,27 @@ void main()
// get length of 3d point, i.e.range
float l = length(viewSpacePos);

// particle mask - color and depth
vec4 particle = texture(particleTexture, inPs.uv0);
float particleDepth = texture(particleDepthTexture, inPs.uv0).x;

if (particle.x > 0.0 && particleDepth > 0.0 && particleDepth < fDepth)
{
// apply scatter effect so that only some of the smoke pixels are visible
float r = rand(inPs.uv0 + vec2(time, time));
if (r < particleScatterRatio)
{
float pd = projectionParams.y / (particleDepth - projectionParams.x);
vec3 point = inPs.cameraDir * pd;

// apply gaussian noise to particle depth data
point = point + gaussrand(inPs.uv0, vec3(time, time, time),
particleStddev, 0.0).xyz;

l = length(point);
}
}

if (l > far)
l = max;
else if (l < near)
Expand Down
6 changes: 3 additions & 3 deletions ogre2/src/media/materials/programs/gpu_rays_2nd_pass_fs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ void main()
else if (faceIdx == 5)
d = getRange(uv, tex5);

// todo(anyone) set retro values
float retro = 0.0;
float range = d.x;
float retro = d.y;

fragColor = vec4(d.x, d.y, 0, 1.0);
fragColor = vec4(range, retro, 0, 1.0);
return;
}
13 changes: 13 additions & 0 deletions ogre2/src/media/materials/scripts/gpu_rays.material
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ fragment_program GpuRaysScan1stFS glsl

default_params
{
param_named_auto time time
param_named depthTexture int 0
param_named colorTexture int 1
param_named particleDepthTexture int 2
param_named particleTexture int 3
}
}

Expand All @@ -53,6 +56,16 @@ material GpuRaysScan1st
filtering none
tex_address_mode clamp
}
texture_unit particleDepthTexture
{
filtering none
tex_address_mode clamp
}
texture_unit particleTexture
{
filtering none
tex_address_mode clamp
}
}
}
}
Expand Down
Loading

0 comments on commit 3f71f83

Please sign in to comment.