OpenWalnut
1.4.0
|
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 "../WGETextureUtils.h" 00028 #include "../shaders/WGEPropertyUniform.h" 00029 #include "../shaders/WGEShaderPropertyDefine.h" 00030 00031 #include "WGEPostprocessorSSAO.h" 00032 00033 WGEPostprocessorSSAO::WGEPostprocessorSSAO(): 00034 WGEPostprocessor( "SSAO", 00035 "SSAO is a special ambient occlusion technique." ) 00036 { 00037 } 00038 00039 WGEPostprocessorSSAO::WGEPostprocessorSSAO( osg::ref_ptr< WGEOffscreenRenderNode > offscreen, 00040 const WGEPostprocessor::PostprocessorInput& gbuffer ): 00041 WGEPostprocessor( "SSAO", 00042 "SSAO is a special ambient occlusion technique." ) 00043 { 00044 // the SSAO algorithm has some parameters. Provide these parameters to the user 00045 WPropInt ssaoSamples = m_properties->addProperty( "Samples", "The number of samples to take in screen-space. Higher values produce better " 00046 "quality but can reduce FPS dramatically.", 16 ); 00047 ssaoSamples->setMin( 1 ); 00048 ssaoSamples->setMax( 128 ); 00049 00050 WPropDouble ssaoRadius = m_properties->addProperty( "Radius", "The radius around the pixel to sample for occluders in pixels.", 10.0 ); 00051 ssaoRadius->setMin( 0.0 ); 00052 ssaoRadius->setMax( 500.0 ); 00053 00054 WPropDouble ssaoTotalStrength = m_properties->addProperty( "Total Strength", "The strength of the effect. Higher values emphasize the effect.", 00055 2.0 ); 00056 ssaoTotalStrength->setMin( 0.0 ); 00057 ssaoTotalStrength->setMax( 100.0 ); 00058 00059 WPropDouble ssaoStrength = m_properties->addProperty( "Strength", "This defines the influence of one occluder to the overall AO effect.", 1.0 ); 00060 ssaoStrength->setMin( 0.0 ); 00061 ssaoStrength->setMax( 1.0 ); 00062 00063 WPropDouble ssaoFalloff = m_properties->addProperty( "Falloff", "Define the edge at which a depth difference between two pixels is assumed to " 00064 "be non-zero.", 0.0 ); 00065 ssaoFalloff->setMin( 0.0 ); 00066 ssaoFalloff->setMax( 1.0 ); 00067 00068 // Use the standard postprocessor uber-shader 00069 WGEShader::RefPtr s = new WGEShader( "WGEPostprocessor" ); 00070 s->setDefine( "WGE_POSTPROCESSOR_SSAO" ); 00071 00072 // also add the m_effectOnly property as shader preprocessor 00073 s->addPreprocessor( m_effectOnlyPreprocessor ); 00074 s->addPreprocessor( WGEShaderPreprocessor::SPtr( 00075 new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_SSAO_SAMPLES", ssaoSamples ) ) 00076 ); 00077 00078 // create the rendering pass 00079 osg::ref_ptr< WGEOffscreenTexturePass > pass = offscreen->addTextureProcessingPass( s, "SSAO" ); 00080 pass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_ssaoTotalStrength", ssaoTotalStrength ) ); 00081 pass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_ssaoStrength", ssaoStrength ) ); 00082 pass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_ssaoRadius", ssaoRadius ) ); 00083 pass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_ssaoFalloff", ssaoFalloff ) ); 00084 00085 // attach color0 output 00086 m_resultTextures.push_back( pass->attach( WGECamera::COLOR_BUFFER0, GL_RGB ) ); 00087 00088 // provide the Gbuffer input 00089 size_t gBufUnitOffset = gbuffer.bind( pass ); 00090 00091 // this effect needs some additional noise texture: 00092 // some of the post-processors need some white noise, like the ssao 00093 const size_t size = 64; 00094 osg::ref_ptr< WGETexture2D > randTex = wge::genWhiteNoiseTexture( size, size, 3 ); 00095 pass->bind( randTex, gBufUnitOffset ); 00096 } 00097 00098 WGEPostprocessorSSAO::~WGEPostprocessorSSAO() 00099 { 00100 // cleanup 00101 } 00102 00103 WGEPostprocessor::SPtr WGEPostprocessorSSAO::create( osg::ref_ptr< WGEOffscreenRenderNode > offscreen, 00104 const WGEPostprocessor::PostprocessorInput& gbuffer ) const 00105 { 00106 return WGEPostprocessor::SPtr( new WGEPostprocessorSSAO( offscreen, gbuffer ) ); 00107 }