OpenWalnut  1.5.0dev
WGEPostprocessorSSAO.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 "../WGETextureUtils.h"
28 #include "../shaders/WGEPropertyUniform.h"
29 #include "../shaders/WGEShaderPropertyDefine.h"
30 
31 #include "WGEPostprocessorSSAO.h"
32 
34  WGEPostprocessor( "SSAO",
35  "SSAO is a special ambient occlusion technique." )
36 {
37 }
38 
39 WGEPostprocessorSSAO::WGEPostprocessorSSAO( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
40  const WGEPostprocessor::PostprocessorInput& gbuffer ):
41  WGEPostprocessor( "SSAO",
42  "SSAO is a special ambient occlusion technique." )
43 {
44  // the SSAO algorithm has some parameters. Provide these parameters to the user
45  WPropInt ssaoSamples = m_properties->addProperty( "Samples", "The number of samples to take in screen-space. Higher values produce better "
46  "quality but can reduce FPS dramatically.", 16 );
47  ssaoSamples->setMin( 1 );
48  ssaoSamples->setMax( 128 );
49 
50  WPropDouble ssaoRadius = m_properties->addProperty( "Radius", "The radius around the pixel to sample for occluders in pixels.", 10.0 );
51  ssaoRadius->setMin( 0.0 );
52  ssaoRadius->setMax( 500.0 );
53 
54  WPropDouble ssaoTotalStrength = m_properties->addProperty( "Total Strength", "The strength of the effect. Higher values emphasize the effect.",
55  2.0 );
56  ssaoTotalStrength->setMin( 0.0 );
57  ssaoTotalStrength->setMax( 100.0 );
58 
59  WPropDouble ssaoStrength = m_properties->addProperty( "Strength", "This defines the influence of one occluder to the overall AO effect.", 1.0 );
60  ssaoStrength->setMin( 0.0 );
61  ssaoStrength->setMax( 1.0 );
62 
63  WPropDouble ssaoFalloff = m_properties->addProperty( "Falloff", "Define the edge at which a depth difference between two pixels is assumed to "
64  "be non-zero.", 0.0 );
65  ssaoFalloff->setMin( 0.0 );
66  ssaoFalloff->setMax( 1.0 );
67 
68  // Use the standard postprocessor uber-shader
69  WGEShader::RefPtr s = new WGEShader( "WGEPostprocessor" );
70  s->setDefine( "WGE_POSTPROCESSOR_SSAO" );
71 
72  // also add the m_effectOnly property as shader preprocessor
73  s->addPreprocessor( m_effectOnlyPreprocessor );
74  s->addPreprocessor( WGEShaderPreprocessor::SPtr(
75  new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_SSAO_SAMPLES", ssaoSamples ) )
76  );
77 
78  // create the rendering pass
79  osg::ref_ptr< WGEOffscreenTexturePass > pass = offscreen->addTextureProcessingPass( s, "SSAO" );
80  pass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_ssaoTotalStrength", ssaoTotalStrength ) );
81  pass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_ssaoStrength", ssaoStrength ) );
82  pass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_ssaoRadius", ssaoRadius ) );
83  pass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_ssaoFalloff", ssaoFalloff ) );
84 
85  // attach color0 output
86  m_resultTextures.push_back( pass->attach( WGECamera::COLOR_BUFFER0, GL_RGB ) );
87 
88  // provide the Gbuffer input
89  size_t gBufUnitOffset = gbuffer.bind( pass );
90 
91  // this effect needs some additional noise texture:
92  // some of the post-processors need some white noise, like the ssao
93  const size_t size = 64;
94  osg::ref_ptr< WGETexture2D > randTex = wge::genWhiteNoiseTexture( size, size, 3 );
95  pass->bind( randTex, gBufUnitOffset );
96 }
97 
99 {
100  // cleanup
101 }
102 
103 WGEPostprocessor::SPtr WGEPostprocessorSSAO::create( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
104  const WGEPostprocessor::PostprocessorInput& gbuffer ) const
105 {
106  return WGEPostprocessor::SPtr( new WGEPostprocessorSSAO( offscreen, gbuffer ) );
107 }
virtual WGEPostprocessor::SPtr create(osg::ref_ptr< WGEOffscreenRenderNode > offscreen, const PostprocessorInput &gbuffer) const
Create instance.
WGEPostprocessorSSAO()
Default constructor.
virtual ~WGEPostprocessorSSAO()
Destructor.
This class encapsulates a G-Buffer.
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.
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 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.