Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply particle scattering effect to lidars #252

Merged
merged 6 commits into from
Feb 17, 2021
Merged
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
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;
adlarkin marked this conversation as resolved.
Show resolved Hide resolved

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);
adlarkin marked this conversation as resolved.
Show resolved Hide resolved

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