OpenWalnut 1.3.1
WGEPostprocessorLineAO.cpp
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #include <osg/Camera>
00026 
00027 #include "../shaders/WGEPropertyUniform.h"
00028 #include "../shaders/WGEShaderPropertyDefine.h"
00029 #include "WGEPostprocessorGauss.h"
00030 #include "WGEPostprocessorMergeOp.h"
00031 
00032 #include "WGEPostprocessorLineAO.h"
00033 
00034 WGEPostprocessorLineAO::WGEPostprocessorLineAO():
00035     WGEPostprocessor( "LineAO",
00036                       "LineAO is a special ambient occlusion technique optimized for dense line and tube rendering." )
00037 {
00038 }
00039 
00040 WGEPostprocessorLineAO::WGEPostprocessorLineAO( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
00041                                                           const WGEPostprocessor::PostprocessorInput& gbuffer ):
00042     WGEPostprocessor( "LineAO",
00043                       "LineAO is a special ambient occlusion technique optimized for dense line and tube rendering." )
00044 {
00045     // the LineAO algorithm has some parameters. Provide these parameters to the user
00046     WPropInt lineaoSamples = m_properties->addProperty( "Samples", "The number of samples to take in screen-space. Higher values produce better "
00047                                                                  "quality but can reduce FPS dramatically.", 32 );
00048     lineaoSamples->setMin( 1 );
00049     lineaoSamples->setMax( 128 );
00050 
00051     WPropInt lineaoScalers = m_properties->addProperty( "Hemispheres", "The number of hemispheres to sample around each pixel. Higher values "
00052                                                                        "produce better quality but can reduce FPS dramatically.", 3 );
00053     lineaoScalers->setMin( 1 );
00054     lineaoScalers->setMax( 8 );
00055 
00056     WPropDouble lineaoRadiusSS = m_properties->addProperty( "Radius", "The radius around the pixel to sample for occluders in pixels.", 2.0 );
00057     lineaoRadiusSS->setMin( 0.01 );
00058     lineaoRadiusSS->setMax( 10.0 );
00059 
00060     WPropDouble lineaoTotalStrength = m_properties->addProperty( "Total Strength", "The strength of the effect. Higher values emphasize the effect.",
00061                                                                                  1.0 );
00062     lineaoTotalStrength->setMin( 0.0 );
00063     lineaoTotalStrength->setMax( 5.0 );
00064 
00065     WPropDouble lineaoDensityWeight = m_properties->addProperty( "Density Weight", "The strength of the occluder influence in relation to the "
00066                                                                                    "geometry density. The higher the value, the larger the "
00067                                                                                    "influence. Low values remove the drop-shadow effect. "
00068                                                                                    "This defines the influence of one occluder to the overall "
00069                                                                                    "AO effect.", 1.0 );
00070     lineaoDensityWeight->setMin( 0.001 );
00071     lineaoDensityWeight->setMax( 2.0 );
00072 
00073     // NOTE: The paper proposes to use a gaussian pyramid of the depth and normal maps. We skip this step. Skipping this causes the AO to look
00074     // more crispy and more detailed at local scope.
00075 
00076     // use the standard postprocessor uber-shader
00077     WGEShader::RefPtr s = new WGEShader( "WGEPostprocessor" );
00078     s->setDefine( "WGE_POSTPROCESSOR_LINEAO" );
00079 
00080     // also add the m_effectOnly property as shader preprocessor
00081     s->addPreprocessor( m_effectOnlyPreprocessor );
00082     s->addPreprocessor( WGEShaderPreprocessor::SPtr(
00083         new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_LINEAO_SCALERS", lineaoScalers ) )
00084     );
00085     s->addPreprocessor( WGEShaderPreprocessor::SPtr(
00086         new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_LINEAO_SAMPLES", lineaoSamples ) )
00087     );
00088 
00089     // create the LineAO rendering pass
00090     osg::ref_ptr< WGEOffscreenTexturePass > lineAOPass = offscreen->addTextureProcessingPass( s, "LineAO" );
00091     lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoDensityWeight", lineaoDensityWeight ) );
00092     lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoTotalStrength", lineaoTotalStrength ) );
00093     lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoRadiusSS", lineaoRadiusSS ) );
00094 
00095     // attach color0 output
00096     m_resultTextures.push_back( lineAOPass->attach( osg::Camera::COLOR_BUFFER0, GL_RGB ) );
00097 
00098     // provide the Gbuffer input
00099     size_t gBufUnitOffset = gbuffer.bind( lineAOPass );
00100 
00101     // this effect needs some additional noise texture:
00102     const size_t size = 64;
00103     osg::ref_ptr< WGETexture2D > randTex = wge::genWhiteNoiseTexture( size, size, 3 );
00104     lineAOPass->bind( randTex, gBufUnitOffset );
00105 }
00106 
00107 WGEPostprocessorLineAO::~WGEPostprocessorLineAO()
00108 {
00109     // cleanup
00110 }
00111 
00112 WGEPostprocessor::SPtr WGEPostprocessorLineAO::create( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
00113     const WGEPostprocessor::PostprocessorInput& gbuffer ) const
00114 {
00115     return WGEPostprocessor::SPtr( new WGEPostprocessorLineAO( offscreen, gbuffer ) );
00116 }