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 "../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.0 ); 00058 lineaoRadiusSS->setMax( 100.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 WPropBool lineaoUseGaussedNDMap = m_properties->addProperty( "Use Gaussed ND-Map", "When enabling, the LineAO algorithm uses a scale-base " 00074 "pyramid for sampling the depth and normal maps. Unlike " 00075 "described in the paper, this is turned off by default to " 00076 "ensure that details of far occluders are retained (the " 00077 "images look crispier).", false ); 00078 WPropBool lineaoUseOccluderLight = m_properties->addProperty( "Use Occluder Light", "When enabling, the LineAO algorithm uses the light " 00079 "reflected by the occluder as contribution to ambient " 00080 "light energy of the pixel. This creates a more realistic " 00081 "rendering but might brighten areas you might want to stay " 00082 "dark.", true ); 00083 00084 // 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 00085 // more crispy and more detailed at local scope. 00086 00087 // use the standard postprocessor uber-shader 00088 WGEShader::RefPtr s = new WGEShader( "WGEPostprocessor" ); 00089 s->setDefine( "WGE_POSTPROCESSOR_LINEAO" ); 00090 00091 // also add the m_effectOnly property as shader preprocessor 00092 s->addPreprocessor( m_effectOnlyPreprocessor ); 00093 s->addPreprocessor( WGEShaderPreprocessor::SPtr( 00094 new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_LINEAO_SCALERS", lineaoScalers ) ) 00095 ); 00096 s->addPreprocessor( WGEShaderPreprocessor::SPtr( 00097 new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_LINEAO_SAMPLES", lineaoSamples ) ) 00098 ); 00099 00100 s->addPreprocessor( WGEShaderPreprocessor::SPtr( 00101 new WGEShaderPropertyDefineOptions< WPropBool >( lineaoUseGaussedNDMap, "WGE_POSTPROCESSOR_LINEAO_USEDIRECTNDMAP", 00102 "WGE_POSTPROCESSOR_LINEAO_USEGAUSSPYRAMID" ) ) 00103 ); 00104 00105 s->addPreprocessor( WGEShaderPreprocessor::SPtr( 00106 new WGEShaderPropertyDefineOptions< WPropBool >( lineaoUseOccluderLight, "WGE_POSTPROCESSOR_LINEAO_NOOCCLUDERLIGHT", 00107 "WGE_POSTPROCESSOR_LINEAO_OCCLUDERLIGHT" ) ) 00108 ); 00109 00110 // create the LineAO rendering pass 00111 osg::ref_ptr< WGEOffscreenTexturePass > lineAOPass = offscreen->addTextureProcessingPass( s, "LineAO" ); 00112 lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoDensityWeight", lineaoDensityWeight ) ); 00113 lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoTotalStrength", lineaoTotalStrength ) ); 00114 lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoRadiusSS", lineaoRadiusSS ) ); 00115 00116 // attach color0 output 00117 m_resultTextures.push_back( lineAOPass->attach( WGECamera::COLOR_BUFFER0, GL_RGB ) ); 00118 00119 // provide the Gbuffer input, with several mipmap levels 00120 gbuffer.m_depthTexture->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR ); 00121 gbuffer.m_normalTexture->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR ); 00122 gbuffer.m_tangentTexture->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR ); 00123 00124 size_t gBufUnitOffset = gbuffer.bind( lineAOPass ); 00125 00126 // this effect needs some additional noise texture: 00127 const size_t size = 64; 00128 osg::ref_ptr< WGETexture2D > randTex = wge::genWhiteNoiseTexture( size, size, 3 ); 00129 lineAOPass->bind( randTex, gBufUnitOffset ); 00130 00131 // also utilize the pre-blend scale 00132 m_effectScale->setHidden( false ); 00133 lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_effectPreBlendScale", m_effectScale ) ); 00134 } 00135 00136 WGEPostprocessorLineAO::~WGEPostprocessorLineAO() 00137 { 00138 // cleanup 00139 } 00140 00141 WGEPostprocessor::SPtr WGEPostprocessorLineAO::create( osg::ref_ptr< WGEOffscreenRenderNode > offscreen, 00142 const WGEPostprocessor::PostprocessorInput& gbuffer ) const 00143 { 00144 return WGEPostprocessor::SPtr( new WGEPostprocessorLineAO( offscreen, gbuffer ) ); 00145 }