Commit b81b25e0 authored by schultezub's avatar schultezub

* added forward-/central differences switch to ProcessorDecoratorShading

 * introducing DepthDarkening processor

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@301 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent d5d28a05
......@@ -154,7 +154,7 @@ namespace TUMVis {
tgt::Shader* shader,
const tgt::TextureUnit* colorTexUnit,
const tgt::TextureUnit* depthTexUnit,
const std::string& colorTexUniform = "_colorTextures",
const std::string& colorTexUniform = "_colorTexture",
const std::string& depthTexUniform = "_depthTexture",
size_t index = 0) const;
......
......@@ -36,6 +36,7 @@ namespace TUMVis {
ProcessorDecoratorShading::ProcessorDecoratorShading(const std::string& lightUniformName /*= "_lightSource"*/)
: AbstractProcessorDecorator()
, _enableShading("EnableShading", "Enable Shading", true, InvalidationLevel::INVALID_SHADER)
, _centralDifferences("CentralDifferences", "Use Central instead of Forward Differences", false, InvalidationLevel::INVALID_SHADER)
, _lightPosition("LightPosition", "Light Position", tgt::vec3(-8.f), tgt::vec3(-500.f), tgt::vec3(500.f))
, _ambientColor("AmbientColor", "Ambient Light Color", tgt::vec3(0.5f), tgt::vec3(0.f), tgt::vec3(1.f))
, _diffuseColor("DiffuseColor", "Diffuse Light Color", tgt::vec3(0.75f), tgt::vec3(0.f), tgt::vec3(1.f))
......@@ -51,6 +52,7 @@ namespace TUMVis {
void ProcessorDecoratorShading::addProperties(HasPropertyCollection* propCollection) {
propCollection->addProperty(&_enableShading);
propCollection->addProperty(&_centralDifferences);
propCollection->addProperty(&_lightPosition);
propCollection->addProperty(&_ambientColor);
propCollection->addProperty(&_diffuseColor);
......@@ -70,12 +72,15 @@ namespace TUMVis {
std::string ProcessorDecoratorShading::generateHeader() const {
if (_enableShading.getValue()) {
return "#define ENABLE_SHADING\n";
}
else {
return "";
}
std::string toReturn;
if (_enableShading.getValue())
toReturn.append("#define ENABLE_SHADING\n");
if (_centralDifferences.getValue())
toReturn.append("#define computeGradient(tex,texCoords) computeGradientFilteredCentralDifferences(tex, texCoords)\n");
else
toReturn.append("#define computeGradient(tex,texCoords) computeGradientForwardDifferences(tex, texCoords)\n");
return toReturn;
}
}
......@@ -52,6 +52,7 @@ namespace TUMVis {
std::string generateHeader() const;
BoolProperty _enableShading; ///< Flag whether to enable shading;
BoolProperty _centralDifferences; ///< Use central instead of forward-differences for gradient calculation
Vec3Property _lightPosition; ///< Light position
Vec3Property _ambientColor; ///< Ambient light color
Vec3Property _diffuseColor; ///< Diffuse light color
......
......@@ -72,11 +72,9 @@ namespace TUMVis {
void RaycastingProcessor::init() {
VisualizationProcessor::init();
_shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", _fragmentShaderFilename, "", false);
_shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", _fragmentShaderFilename, generateHeader(), false);
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
_shader->setHeaders(generateHeader());
_shader->rebuild();
}
void RaycastingProcessor::deinit() {
......
......@@ -46,7 +46,7 @@ namespace TUMVis {
, _vmEepGenerator(_renderTargetSize)
, _dvrNormal(_renderTargetSize)
, _dvrVM(_renderTargetSize)
, _clRaycaster(_renderTargetSize)
, _depthDarkening(_renderTargetSize)
, _combine(_renderTargetSize)
, _trackballEH(0)
{
......@@ -63,7 +63,7 @@ namespace TUMVis {
_processors.push_back(&_vmEepGenerator);
_processors.push_back(&_dvrNormal);
_processors.push_back(&_dvrVM);
_processors.push_back(&_clRaycaster);
_processors.push_back(&_depthDarkening);
_processors.push_back(&_combine);
}
......@@ -80,7 +80,6 @@ namespace TUMVis {
_camera.addSharedProperty(&_vmEepGenerator._camera);
_camera.addSharedProperty(&_dvrNormal._camera);
_camera.addSharedProperty(&_dvrVM._camera);
_camera.addSharedProperty(&_clRaycaster._camera);
_imageReader._url.setValue("D:\\Medical Data\\smallHeart.mhd");
_imageReader._targetImageID.setValue("reader.output");
......@@ -91,9 +90,6 @@ namespace TUMVis {
_dvrVM._targetImageID.setValue("dvr.output");
_dvrVM._sourceImageID.setValue("eep.input");
_clRaycaster._targetImageID.setValue("clr.output");
_clRaycaster._sourceImageID.setValue("clr.input");
_eepGenerator._sourceImageID.setValue("eep.input");
_vmEepGenerator._sourceImageID.setValue("eep.input");
_pgGenerator._sourceImageID.setValue("eep.input");
......@@ -119,16 +115,16 @@ namespace TUMVis {
_eepGenerator._entryImageID.connect(&_dvrNormal._entryImageID);
_vmEepGenerator._entryImageID.connect(&_dvrVM._entryImageID);
_eepGenerator._entryImageID.connect(&_clRaycaster._entryImageID);
_eepGenerator._exitImageID.connect(&_dvrNormal._exitImageID);
_vmEepGenerator._exitImageID.connect(&_dvrVM._exitImageID);
_eepGenerator._exitImageID.connect(&_clRaycaster._exitImageID);
_dvrNormal._targetImageID.connect(&_combine._normalImageID);
_dvrVM._targetImageID.connect(&_combine._mirrorImageID);
_combine._targetImageID.setValue("combine");
_dvrNormal._targetImageID.connect(&_depthDarkening._inputImage);
_depthDarkening._outputImage.connect(&_combine._normalImageID);
_imageReader.s_invalidated.connect<DVRVis>(this, &DVRVis::onProcessorInvalidated);
_vmgGenerator.s_invalidated.connect<DVRVis>(this, &DVRVis::onProcessorInvalidated);
_vmRenderer.s_invalidated.connect<DVRVis>(this, &DVRVis::onProcessorInvalidated);
......@@ -137,7 +133,7 @@ namespace TUMVis {
_vmEepGenerator.s_invalidated.connect<DVRVis>(this, &DVRVis::onProcessorInvalidated);
_dvrNormal.s_invalidated.connect<DVRVis>(this, &DVRVis::onProcessorInvalidated);
_dvrVM.s_invalidated.connect<DVRVis>(this, &DVRVis::onProcessorInvalidated);
_clRaycaster.s_invalidated.connect<DVRVis>(this, &DVRVis::onProcessorInvalidated);
_depthDarkening.s_invalidated.connect<DVRVis>(this, &DVRVis::onProcessorInvalidated);
_combine.s_invalidated.connect<DVRVis>(this, &DVRVis::onProcessorInvalidated);
_trackballEH->setViewportSize(_renderTargetSize.getValue());
......@@ -193,17 +189,18 @@ namespace TUMVis {
}
if (!_dvrNormal.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_dvrNormal);
lockGLContextAndExecuteProcessor(&_depthDarkening);
}
if (!_dvrVM.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_dvrVM);
lockGLContextAndExecuteProcessor(&_combine);
}
if (!_depthDarkening.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_depthDarkening);
}
if (!_combine.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_combine);
}
if (!_clRaycaster.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_clRaycaster);
}
}
const std::string DVRVis::getName() const {
......
......@@ -40,7 +40,7 @@
#include "modules/vis/eepgenerator.h"
#include "modules/vis/drrraycaster.h"
#include "modules/vis/simpleraycaster.h"
#include "modules/vis/clraycaster.h"
#include "modules/vis/depthdarkening.h"
#include "modules/vis/virtualmirrorcombine.h"
namespace TUMVis {
......@@ -79,7 +79,7 @@ namespace TUMVis {
EEPGenerator _vmEepGenerator;
SimpleRaycaster _dvrNormal;
SimpleRaycaster _dvrVM;
CLRaycaster _clRaycaster;
DepthDarkening _depthDarkening;
VirtualMirrorCombine _combine;
TrackballNavigationEventHandler* _trackballEH;
......
// ================================================================================================
//
// This file is part of the TUMVis Visualization Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge (christian.szb@in.tum.de)
// Chair for Computer Aided Medical Procedures
// Technische Universitt Mnchen
// Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#include "depthdarkening.h"
#include "tgt/logmanager.h"
#include "tgt/shadermanager.h"
#include "tgt/textureunit.h"
#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagedatagl.h"
#include "core/datastructures/imagedatarendertarget.h"
#include "core/datastructures/imagedataconverter.h"
#include "core/classification/simpletransferfunction.h"
#include "core/tools/quadrenderer.h"
namespace TUMVis {
const std::string DepthDarkening::loggerCat_ = "TUMVis.modules.vis.DepthDarkening";
DepthDarkening::DepthDarkening(GenericProperty<tgt::ivec2>& canvasSize)
: VisualizationProcessor(canvasSize)
, _inputImage("InputImage", "Input Image", "", DataNameProperty::READ)
, _outputImage("OutputImage", "Output Image", "dd.output", DataNameProperty::WRITE)
, _sigma("Sigma", "Sigma of Gaussian Filter", 2.f, 0.f, 10.f)
, _lambda("Lambda", "Strength of Depth Darkening Effect", 10.f, 0.f, 50.f)
, _shader(0)
{
addProperty(&_inputImage);
addProperty(&_outputImage);
addProperty(&_sigma);
addProperty(&_lambda);
}
DepthDarkening::~DepthDarkening() {
}
void DepthDarkening::init() {
VisualizationProcessor::init();
_shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "modules/vis/depthdarkening.frag", "", false);
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
}
void DepthDarkening::deinit() {
VisualizationProcessor::deinit();
ShdrMgr.dispose(_shader);
}
void DepthDarkening::process(DataContainer& data) {
DataContainer::ScopedTypedData<ImageDataRenderTarget> inputImage(data, _inputImage.getValue());
if (inputImage != 0) {
// TODO: const cast is ugly...
const_cast<tgt::Texture*>(inputImage->getDepthTexture())->downloadTexture();
float* pixels = (float*)inputImage->getDepthTexture()->getPixelData();
float curDepth = *(pixels);
float minDepth = curDepth;
float maxDepth = curDepth;
size_t numPixels = inputImage->getNumElements();
for (size_t i = 1; i < numPixels; ++i) {
curDepth = pixels[i];
minDepth = std::min(minDepth, curDepth);
maxDepth = std::max(maxDepth, curDepth);
}
ImageDataRenderTarget* tempTarget = new ImageDataRenderTarget(tgt::svec3(_renderTargetSize.getValue(), 1));
ImageDataRenderTarget* outputTarget = new ImageDataRenderTarget(tgt::svec3(_renderTargetSize.getValue(), 1));
glPushAttrib(GL_ALL_ATTRIB_BITS);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
_shader->activate();
tgt::TextureUnit colorUnit, depthUnit, pass2DepthUnit;
inputImage->bind(_shader, &colorUnit, &depthUnit);
inputImage->bind(_shader, 0, &pass2DepthUnit, "", "_depthPass2Texture");
_shader->setUniform("_viewportSizeRCP", 1.f / tgt::vec2(_renderTargetSize.getValue()));
_shader->setUniform("_direction", tgt::vec2(1.f, 0.f));
_shader->setUniform("_sigma", _sigma.getValue());
_shader->setUniform("_lambda", _lambda.getValue());
_shader->setUniform("_minDepth", minDepth);
_shader->setUniform("_maxDepth", maxDepth);
tempTarget->activate();
LGL_ERROR;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QuadRdr.renderQuad();
tempTarget->deactivate();
inputImage->bind(_shader, &colorUnit, &depthUnit);
tempTarget->bind(_shader, 0, &pass2DepthUnit, "", "_depthPass2Texture");
_shader->setUniform("_direction", tgt::vec2(0.f, 1.f));
outputTarget->activate();
LGL_ERROR;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QuadRdr.renderQuad();
outputTarget->deactivate();
_shader->deactivate();
tgt::TextureUnit::setZeroUnit();
glPopAttrib();
LGL_ERROR;
data.addData(_outputImage.getValue() + "temp", tempTarget);
data.addData(_outputImage.getValue(), outputTarget);
_outputImage.issueWrite();
}
else {
LERROR("No suitable input image found.");
}
_invalidationLevel.setValid();
}
}
// ================================================================================================
//
// This file is part of the TUMVis Visualization Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge (christian.szb\in.tum.de)
// Chair for Computer Aided Medical Procedures
// Technische Universitt Mnchen
// Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#version 330
out vec4 out_Color;
#include "tools/texture2d.frag"
uniform vec2 _viewportSizeRCP;
uniform Texture2D _colorTexture;
uniform Texture2D _depthTexture;
uniform Texture2D _depthPass2Texture;
uniform vec2 _direction;
uniform float _sigma;
uniform float _lambda;
uniform float _minDepth;
uniform float _maxDepth;
int _halfKernelDimension;
float[25] _gaussKernel;
float _norm;
/**
* Normalize the current input depth value to interval [_minDepth, _maxDepth].
* \depth depth value to be normalized
*/
float normalizeDepth(float depth) {
return (depth - _minDepth) * (1.0 / (_maxDepth - _minDepth));
}
/**
* Initializes the Gauss kernel and its norm.
*/
void initGaussKernel() {
_halfKernelDimension = int(2.5 * _sigma);
_norm = 0.0;
// compute kernel
for (int i=0; i<=_halfKernelDimension; i++) {
_gaussKernel[i] = exp(-float(i*i)/(2.0*_sigma*_sigma));
_norm += _gaussKernel[i];
}
// so far we have just computed norm for one half
_norm = (_norm * 2.0) - _gaussKernel[0];
}
/**
* Apply the Gauss filter in the given direction and return its result.
* \param texCoord Texture coordinates for lookup
*/
float applyDepthGaussFilter(in vec2 texCoord) {
float result = 0.0;
for (int i = -_halfKernelDimension; i <= _halfKernelDimension; ++i) {
// TODO: why the fuck dose abs(i) not work here?!?
int absi = (i < 0) ? -i : i;
float curDepth = getElement2DNormalized(_depthPass2Texture, texCoord + (_direction * _viewportSizeRCP * i)).z;
result += curDepth * _gaussKernel[absi];
}
result /= _norm;
return result;
}
void main() {
vec2 texCoord = gl_FragCoord.xy * _viewportSizeRCP;
// initialize and apply Gaussian filter
initGaussKernel();
float filteredDepth = applyDepthGaussFilter(texCoord);
// separate two passes
if (_direction.y != 1.0) {
// only write out filtered depth value
out_Color = vec4(1.0);
gl_FragDepth = filteredDepth;
} else {
// we are in the second vertical pass and have to modulate the color
float curDepth = getElement2DNormalized(_depthTexture, texCoord).z;
float deltaD = normalizeDepth(filteredDepth) - normalizeDepth(curDepth);
// apply depth darkening
vec4 curColor = getElement2DNormalized(_colorTexture, texCoord);
if (curColor.a == 0)
discard;
if (deltaD < 0.0) {
curColor.rgb += deltaD * _lambda;
}
// write out modulated color and original depth value
out_Color = curColor;
gl_FragDepth = curDepth;
}
}
// ================================================================================================
//
// This file is part of the TUMVis Visualization Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge (christian.szb@in.tum.de)
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#ifndef DEPTHDARKENING_H__
#define DEPTHDARKENING_H__
#include <string>
#include "core/pipeline/visualizationprocessor.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/numericproperty.h"
namespace tgt {
class Shader;
}
namespace TUMVis {
class ImageData;
/**
* Extracts a slice from a 3D image and renders it into a rendertarget.
*/
class DepthDarkening : public VisualizationProcessor {
public:
/**
* Constructs a new DepthDarkening Processor
**/
DepthDarkening(GenericProperty<tgt::ivec2>& canvasSize);
/**
* Destructor
**/
virtual ~DepthDarkening();
/// \see AbstractProcessor::init
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "DepthDarkening"; };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Applies depth darkening post processing to simulate shadows."; };
virtual void process(DataContainer& data);
DataNameProperty _inputImage; ///< image ID for input image
DataNameProperty _outputImage; ///< image ID for output image
FloatProperty _sigma; ///< sigma, standard deviation of the gaussian filter
FloatProperty _lambda; ///< strength of depth effect
protected:
tgt::Shader* _shader; ///< Shader for slice rendering
static const std::string loggerCat_;
};
}
#endif // DEPTHDARKENING_H__
......@@ -79,7 +79,7 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
while (t < tend) {
vec3 samplePosition = entryPoint.rgb + t * direction;
float intensity = getElement3DNormalized(_volume, samplePosition).a;
vec3 gradient = computeGradientCentralDifferences(_volume, samplePosition);
vec3 gradient = computeGradient(_volume, samplePosition);
vec4 color = lookupTF(_tfTextureParameters, _tfTex, intensity);
#ifdef ENABLE_SHADING
......
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