Commit d97de6a8 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge

Merge branch 'ipsvi-raycaster' into 'master'

Ipsvi raycaster



See merge request !5
parents 3739711e d259aab2
......@@ -46,7 +46,11 @@ vec3 computeGradientForwardDifferencesLod(in sampler3D tex, in TextureParameters
* \param texCoords Lookup position in texture coordinates
*/
vec3 computeGradientForwardDifferences(in sampler3D tex, in TextureParameters3D texParams, in vec3 texCoords) {
return computeGradientForwardDifferencesLod(tex, texParams, texCoords, 0.0);
float v = texture(tex, texCoords).r;
float dx = textureOffset(tex, texCoords, ivec3(1, 0, 0)).r;
float dy = textureOffset(tex, texCoords, ivec3(0, 1, 0)).r;
float dz = textureOffset(tex, texCoords, ivec3(0, 0, 1)).r;
return vec3(dx - v, dy - v, dz - v) * texParams._voxelSize;
}
/**
......@@ -73,7 +77,13 @@ vec3 computeGradientCentralDifferencesLod(in sampler3D tex, in TextureParameters
* \param texCoords Lookup position in texture coordinates
*/
vec3 computeGradientCentralDifferences(in sampler3D tex, in TextureParameters3D texParams, in vec3 texCoords) {
return computeGradientCentralDifferencesLod(tex, texParams, texCoords, 0.0);
float dx = textureOffset(tex, texCoords, ivec3(1, 0, 0)).r;
float dy = textureOffset(tex, texCoords, ivec3(0, 1, 0)).r;
float dz = textureOffset(tex, texCoords, ivec3(0, 0, 1)).r;
float mdx = textureOffset(tex, texCoords, ivec3(-1, 0, 0)).r;
float mdy = textureOffset(tex, texCoords, ivec3(0, -1, 0)).r;
float mdz = textureOffset(tex, texCoords, ivec3(0, 0, -1)).r;
return vec3(dx - mdx, dy - mdy, dz - mdz) * texParams._voxelSize * 0.5;
}
......
......@@ -115,7 +115,7 @@ vec3 calculatePhongShading(in vec3 position, in LightSource light, in vec3 camer
* \param normal Normal
* \param materialColor Material color (used for all shading coefficients)
*/
vec3 calculatePhongShading(in vec3 position, in LightSource light, in vec3 camera, in vec3 normal, in vec3 materialColor) {
vec3 calculatePhongShading(in vec3 position, in vec3 ambientColorOverride, LightSource light, in vec3 camera, in vec3 normal, in vec3 materialColor) {
vec3 N = normalize(normal);
vec3 V = normalize(camera - position);
......@@ -124,7 +124,7 @@ vec3 calculatePhongShading(in vec3 position, in LightSource light, in vec3 camer
float d = length(L);
L /= d;
vec3 toReturn = materialColor * light._ambientColor; // ambient term
vec3 toReturn = materialColor * ambientColorOverride; // ambient term
toReturn += materialColor * getDiffuseTerm(light._diffuseColor, N, L);
toReturn += materialColor * getSpecularTerm(light._specularColor, N, L, V, light._shininess);
#ifdef PHONG_APPLY_ATTENUATION
......@@ -133,6 +133,19 @@ vec3 calculatePhongShading(in vec3 position, in LightSource light, in vec3 camer
return toReturn;
}
/**
* Computes the phong shading according to the given parameters.
*
* \param position sample position
* \param light LightSource
* \param camera Camera position
* \param normal Normal
* \param materialColor Material color (used for all shading coefficients)
*/
vec3 calculatePhongShading(in vec3 position, in LightSource light, in vec3 camera, in vec3 normal, in vec3 materialColor) {
return calculatePhongShading(position, light._ambientColor, light, camera, normal, materialColor);
}
/**
* Computes the phong shading intensity according to the given parameters.
......
......@@ -61,7 +61,7 @@ vec4 textureToWorld(in TextureParameters3D texParams, in vec4 texCoords) {
*/
vec3 textureToWorld(in TextureParameters3D texParams, in vec3 texCoords) {
vec4 v = textureToWorld(texParams, vec4(texCoords, 1.0));
return v.xyz;
return (v / v.w).xyz;
}
/**
......@@ -82,6 +82,7 @@ vec4 worldToTexture(in TextureParameters3D texParams, in vec4 worldCoords) {
* \param worldCoords world coordinates
* \return \a texCoords transformes to texture coordinates.
*/
vec4 worldToTexture(in TextureParameters3D texParams, in vec3 worldCoords) {
return worldToTexture(texParams, vec4(worldCoords, 1.0));
vec3 worldToTexture(in TextureParameters3D texParams, in vec3 worldCoords) {
vec4 v = worldToTexture(texParams, vec4(worldCoords, 1.0));
return (v / v.w).xyz;
}
......@@ -38,10 +38,8 @@ namespace campvis {
ProcessorDecoratorGradient::ProcessorDecoratorGradient()
: AbstractProcessorDecorator()
, p_gradientMethod("GradientMethod", "Gradient Computation Method", gradientOptions, 4)
, p_lod("GradientLod", "LOD for Gradient Computation", 0.5f, 0.f, 5.f, .1f, 1)
{
p_gradientMethod.setValue(1);
p_gradientMethod.s_changed.connect(this, &ProcessorDecoratorGradient::onGradientMethodChanged);
}
ProcessorDecoratorGradient::~ProcessorDecoratorGradient() {
......@@ -50,19 +48,16 @@ namespace campvis {
void ProcessorDecoratorGradient::addProperties(AbstractProcessor* propCollection) {
propCollection->addProperty(p_gradientMethod, AbstractProcessor::INVALID_SHADER | AbstractProcessor::INVALID_RESULT);
propCollection->addProperty(p_lod);
}
std::string ProcessorDecoratorGradient::generateHeader() const {
std::string toReturn;
switch (p_gradientMethod.getOptionValue()) {
case ForwardDifferences:
toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientForwardDifferencesLod(tex, texParams, texCoords, _gradientLod)\n");
toReturn.append("uniform float _gradientLod = 0.0;\n");
toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientForwardDifferences(tex, texParams, texCoords)\n");
break;
case CentralDifferences:
toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientCentralDifferencesLod(tex, texParams, texCoords, _gradientLod)\n");
toReturn.append("uniform float _gradientLod = 0.0;\n");
toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientCentralDifferences(tex, texParams, texCoords)\n");
break;
case FilteredCentralDifferences:
toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientFilteredCentralDifferences(tex, texParams, texCoords)\n");
......@@ -78,14 +73,4 @@ namespace campvis {
return toReturn;
}
void ProcessorDecoratorGradient::renderProlog(const DataContainer& dataContainer, cgt::Shader* shader) {
if (p_gradientMethod.getOptionValue() == ForwardDifferences || p_gradientMethod.getOptionValue() == CentralDifferences) {
shader->setUniform("_gradientLod", p_lod.getValue());
}
}
void ProcessorDecoratorGradient::onGradientMethodChanged(const AbstractProperty* prop) {
p_lod.setVisible(p_gradientMethod.getOptionValue() == ForwardDifferences || p_gradientMethod.getOptionValue() == CentralDifferences);
}
}
......@@ -59,16 +59,10 @@ namespace campvis {
protected:
/// \see AbstractProcessorDecorator::addProperties()
void addProperties(AbstractProcessor* propCollection);
/// \see AbstractProcessorDecorator::renderProlog()
virtual void renderProlog(const DataContainer& dataContainer, cgt::Shader* shader);
/// \see AbstractProcessorDecorator::generateHeader()
std::string generateHeader() const;
/// Callback method when p_gradientMethod has changed
void onGradientMethodChanged(const AbstractProperty* prop);
GenericOptionProperty<GradientMethod> p_gradientMethod; ///< Method for calculating the gradients
FloatProperty p_lod; ///< LOD to use for texture lookup during gradient computation
};
......
......@@ -95,17 +95,6 @@ namespace campvis {
if (img != nullptr && entryPoints != nullptr && exitPoints != nullptr && camera != nullptr) {
if (img->getDimensionality() == 3) {
// little hack to support LOD texture lookup for the gradients:
// if texture does not yet have mipmaps, create them.
const cgt::Texture* tex = img->getTexture();
if (tex->getFilter() != cgt::Texture::MIPMAP) {
const_cast<cgt::Texture*>(tex)->setFilter(cgt::Texture::MIPMAP);
glGenerateMipmap(GL_TEXTURE_3D);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
LGL_ERROR;
}
_shader->activate();
_shader->setIgnoreUniformLocationError(true);
......
......@@ -472,6 +472,9 @@ const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::CGT_GL_VERSION_3_3(
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::CGT_GL_VERSION_4_0(4,0,0);
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::CGT_GL_VERSION_4_1(4,1,0);
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::CGT_GL_VERSION_4_2(4,2,0);
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::CGT_GL_VERSION_4_3(4,3,0);
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::CGT_GL_VERSION_4_4(4,4,0);
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::CGT_GL_VERSION_4_5(4,5,0);
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::SHADER_VERSION_110(1,10); ///< GLSL version 1.10
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::SHADER_VERSION_120(1,20); ///< GLSL version 1.20
......@@ -482,6 +485,9 @@ const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::SHADER_VERSION_330(
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::SHADER_VERSION_400(4, 0); ///< GLSL version 4.00
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::SHADER_VERSION_410(4,10); ///< GLSL version 4.10
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::SHADER_VERSION_420(4,20); ///< GLSL version 4.20
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::SHADER_VERSION_430(4,30); ///< GLSL version 4.30
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::SHADER_VERSION_440(4,40); ///< GLSL version 4.40
const GpuCapabilities::GlVersion GpuCapabilities::GlVersion::SHADER_VERSION_450(4,50); ///< GLSL version 4.50
GpuCapabilities::GlVersion::GlVersion(int major, int minor, int release)
: major_(major), minor_(minor), release_(release)
......
......@@ -114,6 +114,9 @@ public:
static const GlVersion CGT_GL_VERSION_4_0;
static const GlVersion CGT_GL_VERSION_4_1;
static const GlVersion CGT_GL_VERSION_4_2;
static const GlVersion CGT_GL_VERSION_4_3;
static const GlVersion CGT_GL_VERSION_4_4;
static const GlVersion CGT_GL_VERSION_4_5;
static const GlVersion SHADER_VERSION_110; ///< GLSL version 1.10
static const GlVersion SHADER_VERSION_120; ///< GLSL version 1.20
......@@ -124,6 +127,9 @@ public:
static const GlVersion SHADER_VERSION_400; ///< GLSL version 4.00
static const GlVersion SHADER_VERSION_410; ///< GLSL version 4.10
static const GlVersion SHADER_VERSION_420; ///< GLSL version 4.20
static const GlVersion SHADER_VERSION_430; ///< GLSL version 4.30
static const GlVersion SHADER_VERSION_440; ///< GLSL version 4.40
static const GlVersion SHADER_VERSION_450; ///< GLSL version 4.50
};
......
......@@ -73,6 +73,7 @@ const float SAMPLING_BASE_INTERVAL_RCP = 200.0;
vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords) {
vec4 result = vec4(0.0);
vec3 direction = exitPoint - entryPoint;
float len = length(direction);
// Adjust direction a bit to prevent division by zero
direction.x = (abs(direction.x) < 0.0000001) ? 0.0000001 : direction.x;
......@@ -129,7 +130,7 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
}
// advance to the next evaluation point along the ray
tNear += _samplingStepSize;
tNear += _samplingStepSize / len;
}
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2015, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
layout(location = 0) out vec4 out_Color; ///< outgoing fragment color
layout(location = 1) out vec4 out_FHP; ///< outgoing fragment first hitpoint
layout(location = 2) out vec4 out_FHN; ///< outgoing fragment first hit normal
#include "tools/gradient.frag"
#include "tools/raycasting.frag"
#include "tools/shading.frag"
#include "tools/texture2d.frag"
#include "tools/texture3d.frag"
#include "tools/transferfunction.frag"
#include "modules/vis/glsl/voxelhierarchy.frag"
uniform vec2 _viewportSizeRCP;
uniform float _jitterStepSizeMultiplier;
// ray entry points
uniform sampler2D _entryPoints;
uniform sampler2D _entryPointsDepth;
uniform TextureParameters2D _entryParams;
// ray exit points
uniform sampler2D _exitPoints;
uniform sampler2D _exitPointsDepth;
uniform TextureParameters2D _exitParams;
// DRR volume
uniform sampler3D _volume;
uniform TextureParameters3D _volumeTextureParams;
// Transfer function
uniform sampler1D _transferFunction;
uniform TFParameters1D _transferFunctionParams;
// Illumination cache
uniform layout(r32f) image2D _icImageIn;
uniform layout(r32f) image2D _icImageOut;
uniform vec3 _icOrigin;
uniform vec3 _icNormal;
uniform vec3 _icRightVector;
uniform vec3 _icUpVector;
uniform float _shadowIntensity = 0.5;
// Voxel Hierarchy Lookup volume
uniform usampler2D _voxelHierarchy;
uniform int _vhMaxMipMapLevel;
uniform LightSource _lightSource;
uniform vec3 _cameraPosition;
uniform float _samplingStepSize;
const float SAMPLING_BASE_INTERVAL_RCP = 200.0;
// projects a vector in world coordinates onto the IC
// returns world coordinates
ivec2 calcIcSamplePosition(vec3 worldPosition) {
// project world position onto IC plane
const vec3 diag = worldPosition - _icOrigin;
const float distance = abs(dot(diag, _icNormal));
const vec3 worldProjected = diag - (-distance * _icNormal);
// transforms world coordinates (have to be lying on the IC plane) to IC pixel space
return ivec2(round(dot(worldProjected, _icRightVector)), round(dot(worldProjected, _icUpVector)));
}
// the composite function can be used for additional shadow ray integration
// from the current sample to the position of the IC.
// However, it's currently not used for performance reasons
void composite(vec3 startPosition, vec3 endPosition, inout float opacity) {
vec3 direction = endPosition - startPosition;
float t = _samplingStepSize;
jitterFloat(t, _samplingStepSize); // jitter startpoint to avoid ringing artifacts (not really effective...)
float tend = min(length(direction), 4*_samplingStepSize);
direction = normalize(direction);
while (t < tend) {
// lookup intensity and TF
vec3 samplePosition = startPosition.xyz + t * direction;
float intensity = texture(_volume, samplePosition).r;
float tfOpacity = lookupTF(_transferFunction, _transferFunctionParams, intensity).a;
opacity = opacity + (1.0 - opacity) * tfOpacity;
t += _samplingStepSize;
}
}
/**
* Performs the raycasting and returns the final fragment color.
*/
vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords) {
vec4 result = vec4(0.0);
float firstHitT = -1.0;
// calculate ray parameters
vec3 direction = exitPoint.rgb - entryPoint.rgb;
float len = length(direction);
// Adjust direction a bit to prevent division by zero
direction.x = (abs(direction.x) < 0.0001) ? 0.0001 : direction.x;
direction.y = (abs(direction.y) < 0.0001) ? 0.0001 : direction.y;
direction.z = (abs(direction.z) < 0.0001) ? 0.0001 : direction.z;
OFFSET = (0.25 / (1 << _vhMaxMipMapLevel)); //< offset value used to avoid self-intersection or previous voxel intersection.
float t = clipFirstHitpoint(_voxelHierarchy, _vhMaxMipMapLevel, entryPoint, direction, 0.0, 1.0);
float tend = 1.0 - clipFirstHitpoint(_voxelHierarchy, _vhMaxMipMapLevel, exitPoint, -direction, 0.0, 1.0);
jitterEntryPoint(entryPoint, direction, _samplingStepSize * _jitterStepSizeMultiplier);
ivec2 icPositionPrev = calcIcSamplePosition(textureToWorld(_volumeTextureParams, entryPoint.rgb + t * direction));
float icIn = imageLoad(_icImageIn, icPositionPrev).r;
float icOut = (0.0);
bool toBeSaved = false;
while (t < tend) {
// compute sample position
vec3 samplePosition = entryPoint.rgb + t * direction;
vec3 worldPos = textureToWorld(_volumeTextureParams, samplePosition);
ivec2 icPosition = calcIcSamplePosition(worldPos);
// optimization: Only store/load when the icPosition has changed
// otherwise we can reuse the variables from the previous sample
if (icPositionPrev != icPosition) {
// write illumination information
if (toBeSaved)
imageStore(_icImageOut, icPositionPrev, vec4(icOut));
toBeSaved = false;
// load illumination information
icIn = imageLoad(_icImageIn, icPosition).r;
// perform a compositing from samplePosition to the samplePosition of the IC
// Currently disabled since it leads to ringing artifacts...
//if (icIn.xyz != vec3(0.0))
// composite(samplePosition, icIn.xyz, icIn.a);
}
// lookup intensity and TF
float intensity = texture(_volume, samplePosition).r;
vec4 color = lookupTF(_transferFunction, _transferFunctionParams, intensity);
// perform compositing
if (color.a > 0.0) {
// compute gradient (needed for shading and normals)
vec3 gradient = computeGradient(_volume, _volumeTextureParams, samplePosition);
// accomodate for variable sampling rates
color.a = 1.0 - pow(1.0 - color.a, _samplingStepSize * SAMPLING_BASE_INTERVAL_RCP);
// perform global illumination
// back-to-front compositing from light-direction
// (for now, we ignore the color contribution and store the world position instead)
// icOut.rgb = ((1.0 - color.a) * icIn.rgb) + (color.a * color.rgb);
//icOut.xyz = samplePosition;
icOut = ((1.0 - color.a) * icIn) + color.a;
toBeSaved = true;
// apply shadowing
const vec3 ambientColorOverride = _lightSource._ambientColor * (1.0 - icIn * _shadowIntensity);
color.rgb = calculatePhongShading(worldPos, ambientColorOverride, _lightSource, _cameraPosition, gradient, color.rgb);
// front-to-back compositing along view direction
result.rgb = result.rgb + color.rgb * color.a * (1.0 - result.a);
result.a = result.a + (1.0 -result.a) * color.a;
icPositionPrev = icPosition;
}
// save first hit ray parameter for depth value calculation
if (firstHitT < 0.0 && result.a > 0.0) {
firstHitT = t;
out_FHP = vec4(samplePosition, 1.0);
out_FHN = vec4(icPosition, 0.0, 0.0);// vec4(normalize(computeGradient(_volume, _volumeTextureParams, samplePosition)), 1.0);
}
// early ray termination (disabled!)
//if (result.a > 0.975) {
// result.a = 1.0;
// t = tend;
//}
// advance to the next evaluation point along the ray
t += _samplingStepSize / len;
}
if (toBeSaved)
imageStore(_icImageOut, icPositionPrev, vec4(icOut));
// calculate depth value from ray parameter
gl_FragDepth = 1.0;
if (firstHitT >= 0.0) {
float depthEntry = texture(_entryPointsDepth, texCoords).z;
float depthExit = texture(_exitPointsDepth, texCoords).z;
gl_FragDepth = calculateDepthValue(firstHitT/tend, depthEntry, depthExit);
}
return result;
}
/***
* The main method.
***/
void main() {
vec2 p = gl_FragCoord.xy * _viewportSizeRCP;
vec3 frontPos = texture(_entryPoints, p).rgb;
vec3 backPos = texture(_exitPoints, p).rgb;
//determine whether the ray has to be casted
if (frontPos == backPos) {
//background need no raycasting
discard;
} else {
//fragCoords are lying inside the boundingbox
out_Color = performRaycasting(frontPos, backPos, p);
}
}
\ No newline at end of file
......@@ -67,7 +67,7 @@ namespace campvis {
dvrTF->addGeometry(TFGeometry1D::createQuad(cgt::vec2(.19f, .28f), cgt::col4(89, 89, 89, 155), cgt::col4(89, 89, 89, 155)));
dvrTF->addGeometry(TFGeometry1D::createQuad(cgt::vec2(.41f, .51f), cgt::col4(170, 170, 128, 64), cgt::col4(192, 192, 128, 64)));
static_cast<TransferFunctionProperty*>(_vr.getNestedProperty("RaycasterProps::TransferFunction"))->replaceTF(dvrTF);
static_cast<FloatProperty*>(_vr.getNestedProperty("RaycasterProps::SamplingRate"))->setValue(4.f);
static_cast<FloatProperty*>(_vr.getNestedProperty("RaycasterProps::SamplingRate"))->setValue(2.f);
}
}
\ No newline at end of file
......@@ -55,8 +55,6 @@ namespace campvis {
}
void AdvOptimizedRaycaster::init() {
RaycastingProcessor::init();
_vhm = new VoxelHierarchyMapper();
......@@ -84,10 +82,6 @@ namespace campvis {
ScopedTypedData<LightSourceData> light(data, p_lightId.getValue());
if (p_enableShading.getValue() == false || light != nullptr) {
// undo MIPMAP hack from RaycastingProcessor, as mipmapping results in artifacts during ray clipping...
if (image->getTexture()->getFilter() != cgt::Texture::LINEAR)
const_cast<cgt::Texture*>(image->getTexture())->setFilter(cgt::Texture::LINEAR);
_shader->activate();
cgt::TextureUnit xorUnit, bbvUnit;
......
This diff is collapsed.
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2015, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#ifndef IPSVIRAYCASTER_H__
#define IPSVIRAYCASTER_H__
#include "core/pipeline/raycastingprocessor.h"
#include "core/properties/floatingpointproperty.h"
#include "core/properties/genericproperty.h"
#include "core/properties/transferfunctionproperty.h"
#include "modules/modulesapi.h"
#include <string>
namespace cgt {
class Shader;
class Texture;
}
namespace campvis {
class CameraData;
class LightSourceData;
class VoxelHierarchyMapper;
/**
* Raycaster that implements the Image Plane Sweep Volume Illumation algorithm of Sundn et al.
* This raycasting processor supports real-time directional light shadowing and additionally
* uses the VoxelHierarchyMapper for optimized entry-exit points.
*
* Requires OpenGL 4.4!
*/
class CAMPVIS_MODULES_API IpsviRaycaster : public RaycastingProcessor {
public:
enum AdditionalInvalidationLevels {
INVALID_BBV = AbstractProcessor::FIRST_FREE_TO_USE_INVALIDATION_LEVEL,
INVALID_IC_TEXTURES = AbstractProcessor::FIRST_FREE_TO_USE_INVALIDATION_LEVEL << 1,
};
/**
* Constructs a new IpsviRaycaster Processor
**/
explicit IpsviRaycaster(IVec2Property* viewportSizeProp);
/**
* Destructor
**/
virtual ~IpsviRaycaster();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "IpsviRaycaster"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Raycaster that implements the Image Plane Sweep Volume Illumation algorithm of Sundn et al."; };
/// \see AbstractProcessor::getAuthor()
virtual const std::string getAuthor() const { return "Christian Schulte zu Berge <christian.szb@in.tum.de>"; };
/// \see AbstractProcessor::getProcessorState()
virtual ProcessorState getProcessorState() const { return AbstractProcessor::TESTING; };
/// \see AbstractProcessor::init
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
DataNameProperty p_lightId; ///< Name/ID for the LightSource to use
IntProperty p_sweepLineWidth; ///< Width of the sweep line in pixels
IVec2Property p_icTextureSize; ///< Size of the Illumination Cache texture
FloatProperty p_shadowIntensity; ///< Intensity of the shadowing effect
protected:
/// \see RaycastingProcessor::updateResult()
virtual void updateResult(DataContainer& data) override;
/// \see RaycastingProcessor::processImpl()
virtual void processImpl(DataContainer& data, ImageRepresentationGL::ScopedRepresentation& image);
void processDirectional(DataContainer& data, ImageRepresentationGL::ScopedRepresentation& image, const CameraData& camera, const LightSourceData& light);
void processPointLight(DataContainer& data, ImageRepresentationGL::ScopedRepresentation& image, const CameraData& camera, const LightSourceData& light);
VoxelHierarchyMapper* _vhm; ///< for optimizing entry/exit points
cgt::Texture* _icTextures[2]; ///< Illumination cache textures
bool _gl44Supported; ///< Flag whether OpenGL 4.4 is supported.
static const std::string loggerCat_;
};
}
#endif // IPSVIRAYCASTER_H__
......@@ -39,6 +39,7 @@
#include "modules/vis/processors/drrraycaster.h"
#include "modules/vis/processors/eepgenerator.h"
#include "modules/vis/processors/geometryrenderer.h"
#include "modules/vis/processors/ipsviraycaster.h"
#include "modules/vis/processors/mprrenderer.h"
#include "modules/vis/processors/orientationoverlay.h"
#include "modules/vis/processors/proxygeometrygenerator.h"
......@@ -71,6 +72,7 @@ namespace campvis {
template class SmartProcessorRegistrar<DRRRaycaster>;
template class SmartProcessorRegistrar<EEPGenerator>;
template class SmartProcessorRegistrar<GeometryRenderer>;
template class SmartProcessorRegistrar<IpsviRaycaster>;
template class SmartProcessorRegistrar<MprRenderer>;
template class SmartProcessorRegistrar<OrientationOverlay>;
template class SmartProcessorRegistrar<ProxyGeometryGenerator>;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment