OpenWalnut  1.3.1
WGEPostprocessorLineAO.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <osg/Camera>
26 
27 #include "../shaders/WGEPropertyUniform.h"
28 #include "../shaders/WGEShaderPropertyDefine.h"
29 #include "WGEPostprocessorGauss.h"
30 #include "WGEPostprocessorMergeOp.h"
31 
32 #include "WGEPostprocessorLineAO.h"
33 
35  WGEPostprocessor( "LineAO",
36  "LineAO is a special ambient occlusion technique optimized for dense line and tube rendering." )
37 {
38 }
39 
40 WGEPostprocessorLineAO::WGEPostprocessorLineAO( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
41  const WGEPostprocessor::PostprocessorInput& gbuffer ):
42  WGEPostprocessor( "LineAO",
43  "LineAO is a special ambient occlusion technique optimized for dense line and tube rendering." )
44 {
45  // the LineAO algorithm has some parameters. Provide these parameters to the user
46  WPropInt lineaoSamples = m_properties->addProperty( "Samples", "The number of samples to take in screen-space. Higher values produce better "
47  "quality but can reduce FPS dramatically.", 32 );
48  lineaoSamples->setMin( 1 );
49  lineaoSamples->setMax( 128 );
50 
51  WPropInt lineaoScalers = m_properties->addProperty( "Hemispheres", "The number of hemispheres to sample around each pixel. Higher values "
52  "produce better quality but can reduce FPS dramatically.", 3 );
53  lineaoScalers->setMin( 1 );
54  lineaoScalers->setMax( 8 );
55 
56  WPropDouble lineaoRadiusSS = m_properties->addProperty( "Radius", "The radius around the pixel to sample for occluders in pixels.", 2.0 );
57  lineaoRadiusSS->setMin( 0.01 );
58  lineaoRadiusSS->setMax( 10.0 );
59 
60  WPropDouble lineaoTotalStrength = m_properties->addProperty( "Total Strength", "The strength of the effect. Higher values emphasize the effect.",
61  1.0 );
62  lineaoTotalStrength->setMin( 0.0 );
63  lineaoTotalStrength->setMax( 5.0 );
64 
65  WPropDouble lineaoDensityWeight = m_properties->addProperty( "Density Weight", "The strength of the occluder influence in relation to the "
66  "geometry density. The higher the value, the larger the "
67  "influence. Low values remove the drop-shadow effect. "
68  "This defines the influence of one occluder to the overall "
69  "AO effect.", 1.0 );
70  lineaoDensityWeight->setMin( 0.001 );
71  lineaoDensityWeight->setMax( 2.0 );
72 
73  // 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
74  // more crispy and more detailed at local scope.
75 
76  // use the standard postprocessor uber-shader
77  WGEShader::RefPtr s = new WGEShader( "WGEPostprocessor" );
78  s->setDefine( "WGE_POSTPROCESSOR_LINEAO" );
79 
80  // also add the m_effectOnly property as shader preprocessor
81  s->addPreprocessor( m_effectOnlyPreprocessor );
82  s->addPreprocessor( WGEShaderPreprocessor::SPtr(
83  new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_LINEAO_SCALERS", lineaoScalers ) )
84  );
85  s->addPreprocessor( WGEShaderPreprocessor::SPtr(
86  new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_LINEAO_SAMPLES", lineaoSamples ) )
87  );
88 
89  // create the LineAO rendering pass
90  osg::ref_ptr< WGEOffscreenTexturePass > lineAOPass = offscreen->addTextureProcessingPass( s, "LineAO" );
91  lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoDensityWeight", lineaoDensityWeight ) );
92  lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoTotalStrength", lineaoTotalStrength ) );
93  lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoRadiusSS", lineaoRadiusSS ) );
94 
95  // attach color0 output
96  m_resultTextures.push_back( lineAOPass->attach( osg::Camera::COLOR_BUFFER0, GL_RGB ) );
97 
98  // provide the Gbuffer input
99  size_t gBufUnitOffset = gbuffer.bind( lineAOPass );
100 
101  // this effect needs some additional noise texture:
102  const size_t size = 64;
103  osg::ref_ptr< WGETexture2D > randTex = wge::genWhiteNoiseTexture( size, size, 3 );
104  lineAOPass->bind( randTex, gBufUnitOffset );
105 }
106 
108 {
109  // cleanup
110 }
111 
112 WGEPostprocessor::SPtr WGEPostprocessorLineAO::create( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
113  const WGEPostprocessor::PostprocessorInput& gbuffer ) const
114 {
115  return WGEPostprocessor::SPtr( new WGEPostprocessorLineAO( offscreen, gbuffer ) );
116 }