Commit cd918f81 authored by Jakob Weiss's avatar Jakob Weiss
Browse files

Advanced Raycasting features

* ambient occlusion refactored as a decorator
* pre-integrated raycaster and processor to pre-integrate TF
parent 88c45357
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ SET(ThisModStatus EXPERIMENTAL)
IF(${ModuleEnabled})
	# Source files:
    FILE(GLOB ThisModSources RELATIVE ${ModulesDir}
        modules/advancedraycasting/decorators/*.cpp
		modules/advancedraycasting/pipelines/*.cpp
		modules/advancedraycasting/processors/*.cpp
		modules/advancedraycasting/tools/*.cpp
@@ -17,6 +18,7 @@ IF(${ModuleEnabled})
		modules/advancedraycasting/glsl/*.geom
        modules/advancedraycasting/glsl/*.vert
        modules/advancedraycasting/glsl/*.comp
        modules/advancedraycasting/decorators/*.h
        modules/advancedraycasting/pipelines/*.h
		modules/advancedraycasting/processors/*.h
		modules/advancedraycasting/tools/*.h
+9 −1
Original line number Diff line number Diff line
@@ -25,13 +25,21 @@
#include "core/pipeline/pipelinefactory.h"
#include "core/pipeline/processorfactory.h"

#include "modules/advancedraycasting/pipelines/preintegratedraycasterdemo.h"

#include "modules/advancedraycasting/processors/ambientvolumegenerator.h"
#include "modules/advancedraycasting/processors/laoraycaster.h"
#include "modules/advancedraycasting/processors/preintegratedraycaster.h"
#include "modules/advancedraycasting/processors/tfpreintegrator.h"

namespace campvis {

    // explicitly instantiate templates to register the pipelines
    //template class PipelineRegistrar<OCTStereoPlaneDemo>;
    template class PipelineRegistrar<PreintegratedRayCasterDemo>;

    template class SmartProcessorRegistrar<AmbientVolumeGenerator>;
    template class SmartProcessorRegistrar<LAORaycaster>;
    template class SmartProcessorRegistrar<PreintegratedRaycaster>;
    template class SmartProcessorRegistrar<TFPreIntegrator>;

}
+103 −0
Original line number Diff line number Diff line
// ================================================================================================
// 
// 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.
// 
// ================================================================================================

#include "localambientocclusiondecorator.h"

#include "cgt/shadermanager.h"
#include "cgt/textureunit.h"
#include "core/properties/propertycollection.h"

#include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/renderdata.h"
#include "core/classification/geometry1dtransferfunction.h"

namespace campvis {

    LocalAmbientOcclusionDecorator::LocalAmbientOcclusionDecorator()
        : AbstractProcessorDecorator()
        , p_aoRays("AORays", "Number of directional samples", 8, 0, 50)
        , p_aoSamples("AOSamples", "Number of Samples per ray (controls size of AO sphere)", 10, 0, 80)
        , p_aoSphereRadius("AOSphereRadius", "AO Sphere Radius [voxels]", 8.0f, 0.1f, 50.0f, 0.25f)
        , p_aoOpacityScale("OpacityScale", "Opacity Scaling", 1.0f, 0.0f, 5.f)
        , p_aoEffectGamma("AOEffectGamma", "AO Scale Gamma", 1.0f, .0f, 5.f)
        , p_aoEmissiveTransferFunction("AOTransferFunction", "Emissive Transfer Function", new Geometry1DTransferFunction(128))
        , p_aoEmissiveScale("EmissiveScale", "Emissive Color Scaling", 1.0f, 0.0f, 10.f)
    {
    }

    LocalAmbientOcclusionDecorator::~LocalAmbientOcclusionDecorator() {

    }

    void LocalAmbientOcclusionDecorator::addProperties(AbstractProcessor* propCollection) {
        propCollection->addProperty(p_aoRays, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_PROPERTIES | AbstractProcessor::INVALID_SHADER);
        propCollection->addProperty(p_aoSamples, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_PROPERTIES | AbstractProcessor::INVALID_SHADER);
        propCollection->addProperty(p_aoSphereRadius);
        propCollection->addProperty(p_aoOpacityScale);
        propCollection->addProperty(p_aoEffectGamma);
        propCollection->addProperty(p_aoEmissiveTransferFunction);
        propCollection->addProperty(p_aoEmissiveScale);
    }

    void LocalAmbientOcclusionDecorator::renderProlog(const DataContainer& dataContainer, cgt::Shader* shader) {
        auto aotf = p_aoEmissiveTransferFunction.getTF();
        _aoTFUnit = std::make_unique<cgt::TextureUnit>();
        aotf->bind(shader, *_aoTFUnit, "_aoEmissiveTF", "_aoEmissiveTFParams");

        shader->setUniform("_aoSphereRadius", p_aoSphereRadius.getValue());
        shader->setUniform("_aoGamma", p_aoEffectGamma.getValue());
        shader->setUniform("_aoEmissiveScale", p_aoEmissiveScale.getValue());
        shader->setUniform("_aoOpacityScale", p_aoOpacityScale.getValue());
    }

    void LocalAmbientOcclusionDecorator::renderEpilog(cgt::Shader * shader)
    {
        // delete the TF texture unit
        _aoTFUnit = nullptr;
    }

    std::string LocalAmbientOcclusionDecorator::generateHeader() const
    {
        std::string toReturn;
        // the defines need to exist before the include
        toReturn +=
            "#define NUM_AO_RAYS " + std::to_string(p_aoRays.getValue()) + "\n"
            "#define NUM_AO_RAY_STEPS " + std::to_string(p_aoSamples.getValue()) + "\n"
            "\n"
            "uniform float _aoSphereRadius;\n"
            "uniform float _aoGamma;\n"
            "uniform float _aoOpacityScale;\n"
            "uniform float _aoEmissiveScale;\n"
            "\n"
            "#define AO_GAMMA _aoGamma\n"
            "#define AO_OPACITY_SCALE _aoOpacityScale\n"
            "#define AO_EMISSIVE_SCALE _aoEmissiveScale\n";

        // the include has the actual functions
        toReturn += "#include \"modules/advancedraycasting/glsl/localambientocclusion.frag\"\n";

        return toReturn;
    }

}
+74 −0
Original line number Diff line number Diff line
// ================================================================================================
// 
// 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 LOCALAMBIENTOCCLUSIONDECORATOR_H__
#define LOCALAMBIENTOCCLUSIONDECORATOR_H__

#include "core/pipeline/abstractprocessordecorator.h"
#include "core/properties/floatingpointproperty.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/colorproperty.h"
#include "core/properties/optionproperty.h"
#include "core/properties/transferfunctionproperty.h"

#include "modules/modulesapi.h"

namespace cgt {
    class TextureUnit;
}

namespace campvis {
    /**
     *  \class RaycastingGridDecorator
     *  Provides a fragment shader function that can test samples and modify their opacity valued to 
     */
    class CAMPVIS_MODULES_API LocalAmbientOcclusionDecorator : public AbstractProcessorDecorator {
    public:
        LocalAmbientOcclusionDecorator();
        virtual ~LocalAmbientOcclusionDecorator();

    protected:
        void addProperties(AbstractProcessor* propCollection) override;

        virtual void renderProlog(const DataContainer& dataContainer, cgt::Shader* shader) override;

        virtual void renderEpilog(cgt::Shader* shader) override;

        virtual std::string generateHeader() const override;

        IntProperty  p_aoRays;                      ///< Number of directional AO samples
        IntProperty  p_aoSamples;                   ///< Number of steps per directional sample
        FloatProperty p_aoSphereRadius;             ///< The AO Sphere radius in voxels
        FloatProperty p_aoEffectGamma;              ///< Gamma controls the strength of the AO effect
        FloatProperty p_aoOpacityScale;             ///< Scales opacity when sampling for AO rays

        TransferFunctionProperty p_aoEmissiveTransferFunction;
        FloatProperty p_aoEmissiveScale;            ///< Scales the emissive color to increase/decrease the emissive effect

        std::unique_ptr<cgt::TextureUnit> _aoTFUnit;
    };

}

#endif // LOCALAMBIENTOCCLUSIONDECORATOR_H__
+92 −0
Original line number Diff line number Diff line
// ================================================================================================
// 
// 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.
// 
// ================================================================================================

// (c) 2017 Jakob Weiss <jakob.weiss@tum.de>

// ==================== Shader for median filtering. ====================
// Expects the following dynamic defines:
//
// #define OUTPUT_TEXTURE_FORMAT
//          The texture format of the output texture. Preferrably specified through Texture::calcMatchingWriteFormat()
//
// uniform _outputImage
//          dynamically defined (i|u)image(1|2|3)D uniform to allow imageStore operation of the output
// #define TEXTURE_DIMENSIONALITY
//          The dimensionality of the texture [1,2,3]

// The work group size can be overridden by dynamic defines
#ifndef WORK_GROUP_SIZE_X
#define WORK_GROUP_SIZE_X 1
#endif
#ifndef WORK_GROUP_SIZE_Y
#define WORK_GROUP_SIZE_Y 1
#endif
#ifndef WORK_GROUP_SIZE_Z
#define WORK_GROUP_SIZE_Z 1
#endif

#include "tools/transferfunction.frag"


// volume
uniform sampler3D _volume;
uniform TextureParameters3D _volumeTextureParams;

// Transfer function
uniform sampler1D _transferFunction;
uniform TFParameters1D _transferFunctionParams;

// Transfer function
uniform sampler1D _aoEmissiveTF;
uniform TFParameters1D _aoEmissiveTFParams;

layout(local_size_x = WORK_GROUP_SIZE_X, local_size_y = WORK_GROUP_SIZE_Y, local_size_z = WORK_GROUP_SIZE_Z) in;


void main() {
    // get index in global work group i.e x,y position
    ivec3 pixel_coords = ivec3(gl_GlobalInvocationID.xyz);
    vec3 samplePosition = vec3(pixel_coords)*_volumeTextureParams._sizeRCP;

    float sampleIntensity = texture(_volume, samplePosition).r;
    vec4 sampleTFColor = lookupTF(_transferFunction, _transferFunctionParams, sampleIntensity);
    
    // precompute the LAO ray directions
    vec4 aoRayDirs[NUM_AO_RAYS];
    initLAODirs(aoRayDirs, _aoSphereRadius, _volumeTextureParams);

    vec3 ambientOcclusion = computeLAO(samplePosition, aoRayDirs, _volume, _transferFunction, _transferFunctionParams, _aoEmissiveTF, _aoEmissiveTFParams);

    vec4 result = vec4(ambientOcclusion, sampleTFColor.a);

    // output to a specific pixel in the image
    #if TEXTURE_DIMENSIONALITY == 1
    imageStore(_outputImage, pixel_coords.x, vec4(result));
    #elif TEXTURE_DIMENSIONALITY == 2
    imageStore(_outputImage, pixel_coords.xy, vec4(result));
    #else
    imageStore(_outputImage, pixel_coords, vec4(result));
    #endif

}
Loading