Loading modules/advancedraycasting/advancedraycasting.cmake +4 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading modules/advancedraycasting/advancedraycasting.cpp +9 −1 Original line number Diff line number Diff line Loading @@ -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>; } modules/advancedraycasting/decorators/localambientocclusiondecorator.cpp 0 → 100644 +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; } } modules/advancedraycasting/decorators/localambientocclusiondecorator.h 0 → 100644 +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__ modules/advancedraycasting/glsl/ambientvolumegenerator.comp 0 → 100644 +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
modules/advancedraycasting/advancedraycasting.cmake +4 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading
modules/advancedraycasting/advancedraycasting.cpp +9 −1 Original line number Diff line number Diff line Loading @@ -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>; }
modules/advancedraycasting/decorators/localambientocclusiondecorator.cpp 0 → 100644 +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; } }
modules/advancedraycasting/decorators/localambientocclusiondecorator.h 0 → 100644 +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__
modules/advancedraycasting/glsl/ambientvolumegenerator.comp 0 → 100644 +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 }