OpenWalnut  1.5.0dev
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.0 );
58  lineaoRadiusSS->setMax( 100.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  WPropBool lineaoUseGaussedNDMap = m_properties->addProperty( "Use Gaussed ND-Map", "When enabling, the LineAO algorithm uses a scale-base "
74  "pyramid for sampling the depth and normal maps. Unlike "
75  "described in the paper, this is turned off by default to "
76  "ensure that details of far occluders are retained (the "
77  "images look crispier).", false );
78  WPropBool lineaoUseOccluderLight = m_properties->addProperty( "Use Occluder Light", "When enabling, the LineAO algorithm uses the light "
79  "reflected by the occluder as contribution to ambient "
80  "light energy of the pixel. This creates a more realistic "
81  "rendering but might brighten areas you might want to stay "
82  "dark.", true );
83 
84  // 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
85  // more crispy and more detailed at local scope.
86 
87  // use the standard postprocessor uber-shader
88  WGEShader::RefPtr s = new WGEShader( "WGEPostprocessor" );
89  s->setDefine( "WGE_POSTPROCESSOR_LINEAO" );
90 
91  // also add the m_effectOnly property as shader preprocessor
92  s->addPreprocessor( m_effectOnlyPreprocessor );
93  s->addPreprocessor( WGEShaderPreprocessor::SPtr(
94  new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_LINEAO_SCALERS", lineaoScalers ) )
95  );
96  s->addPreprocessor( WGEShaderPreprocessor::SPtr(
97  new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_LINEAO_SAMPLES", lineaoSamples ) )
98  );
99 
100  s->addPreprocessor( WGEShaderPreprocessor::SPtr(
101  new WGEShaderPropertyDefineOptions< WPropBool >( lineaoUseGaussedNDMap, "WGE_POSTPROCESSOR_LINEAO_USEDIRECTNDMAP",
102  "WGE_POSTPROCESSOR_LINEAO_USEGAUSSPYRAMID" ) )
103  );
104 
105  s->addPreprocessor( WGEShaderPreprocessor::SPtr(
106  new WGEShaderPropertyDefineOptions< WPropBool >( lineaoUseOccluderLight, "WGE_POSTPROCESSOR_LINEAO_NOOCCLUDERLIGHT",
107  "WGE_POSTPROCESSOR_LINEAO_OCCLUDERLIGHT" ) )
108  );
109 
110  // create the LineAO rendering pass
111  osg::ref_ptr< WGEOffscreenTexturePass > lineAOPass = offscreen->addTextureProcessingPass( s, "LineAO" );
112  lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoDensityWeight", lineaoDensityWeight ) );
113  lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoTotalStrength", lineaoTotalStrength ) );
114  lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoRadiusSS", lineaoRadiusSS ) );
115 
116  // attach color0 output
117  m_resultTextures.push_back( lineAOPass->attach( WGECamera::COLOR_BUFFER0, GL_RGB ) );
118 
119  // provide the Gbuffer input, with several mipmap levels
120  gbuffer.m_depthTexture->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
121  gbuffer.m_normalTexture->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
122  gbuffer.m_tangentTexture->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
123 
124  size_t gBufUnitOffset = gbuffer.bind( lineAOPass );
125 
126  // this effect needs some additional noise texture:
127  const size_t size = 64;
128  osg::ref_ptr< WGETexture2D > randTex = wge::genWhiteNoiseTexture( size, size, 3 );
129  lineAOPass->bind( randTex, gBufUnitOffset );
130 
131  // also utilize the pre-blend scale
132  m_effectScale->setHidden( false );
133  lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_effectPreBlendScale", m_effectScale ) );
134 }
135 
137 {
138  // cleanup
139 }
140 
141 WGEPostprocessor::SPtr WGEPostprocessorLineAO::create( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
142  const WGEPostprocessor::PostprocessorInput& gbuffer ) const
143 {
144  return WGEPostprocessor::SPtr( new WGEPostprocessorLineAO( offscreen, gbuffer ) );
145 }
virtual WGEPostprocessor::SPtr create(osg::ref_ptr< WGEOffscreenRenderNode > offscreen, const PostprocessorInput &gbuffer) const
Create instance.
virtual ~WGEPostprocessorLineAO()
Destructor.
WGEPostprocessorLineAO()
Default constructor.
This class encapsulates a G-Buffer.
osg::ref_ptr< osg::Texture2D > m_normalTexture
Normal in RGB.
osg::ref_ptr< osg::Texture2D > m_tangentTexture
Tangent in RGB.
osg::ref_ptr< osg::Texture2D > m_depthTexture
Depth.
size_t bind(osg::ref_ptr< WGEOffscreenRenderPass > to) const
Attaches these textures to the specified renderpass.
The base class for all custom post-processors.
WGEShaderPreprocessor::SPtr m_effectOnlyPreprocessor
For convenience, this is a shader preprocessor controlled by m_effectOnly property.
WPropGroup m_properties
All the properties of the post-processor.
WPropDouble m_effectScale
Scale the effect prior to blending it.
std::shared_ptr< WGEPostprocessor > SPtr
Convenience typedef for an osg::ref_ptr< WGEPostprocessor >.
std::vector< osg::ref_ptr< osg::Texture2D > > m_resultTextures
The textures contain the result.
Class implementing a uniform which can be controlled by a property instance.
std::shared_ptr< WGEShaderPreprocessor > SPtr
Shared pointer for this class.
This is a WGEShaderDefineOptions class which additionally uses a property to automatically control th...
This class is able to provide arbitrary values as define statements in GLSL code.
Class encapsulating the OSG Program class for a more convenient way of adding and modifying shader.
Definition: WGEShader.h:48
osg::ref_ptr< WGEShader > RefPtr
Convenience typedef for an osg::ref_ptr.
Definition: WGEShader.h:53
osg::ref_ptr< WGETexture< osg::Texture1D > > genWhiteNoiseTexture(size_t sizeX, size_t channels)
This generates an 1D texture only containing white noise in its channels.