Commit c9df513a authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[ADD] - gauss filter postprocessor added

parent 52de728f
......@@ -88,7 +88,14 @@ WGEPostprocessingNode::WGEPostprocessingNode( osg::ref_ptr< osg::Camera > refere
osg::ref_ptr< WGEOffscreenFinalPass > output = offscreen->addFinalOnScreenPass( new WGEShader( "WGEPostprocessorCombiner" ),
"Output" );
output->bind( processor->getOutput(), 0 );
output->bind( processor->getDepth(), 1 );
// does this processor provide a depth?
osg::ref_ptr< osg::Texture2D > depthTex = processor->getDepth();
if( !depthTex )
{
depthTex = buf.m_depthTexture;
}
output->bind( depthTex, 1 );
// add the offscreen renderer and the original node to the switch
addChild( offscreen );
......
......@@ -26,6 +26,7 @@
#include "WGEPostprocessorEdgeEnhance.h"
#include "WGEPostprocessorCelShading.h"
#include "WGEPostprocessorGauss.h"
#include "WGEPostprocessorSSAO.h"
#include "WGEPostprocessorLineAO.h"
......@@ -33,18 +34,8 @@
WGEPostprocessor::WGEPostprocessor( std::string name, std::string description ):
WPrototyped(),
m_name( name ),
m_description( description )
{
}
WGEPostprocessor::WGEPostprocessor( osg::ref_ptr< WGEOffscreenRenderNode > /* offscreen */,
const WGEPostprocessor::PostprocessorInput& gbuffer,
std::string name,
std::string description ):
WPrototyped(),
m_resultTexture( gbuffer.m_colorTexture ),
m_depthTexture( gbuffer.m_depthTexture ),
m_resultTexture(),
m_depthTexture(),
m_properties( boost::shared_ptr< WProperties >( new WProperties( "Settings for " + name, "Post-processing properties" ) ) ),
m_name( name ),
m_description( description )
......@@ -108,6 +99,7 @@ WGEPostprocessor::ProcessorList WGEPostprocessor::getPostprocessors()
// create prototypes of the postprocessors OW knows about
postprocs.push_back( WGEPostprocessor::SPtr( new WGEPostprocessorEdgeEnhance() ) );
postprocs.push_back( WGEPostprocessor::SPtr( new WGEPostprocessorCelShading() ) );
postprocs.push_back( WGEPostprocessor::SPtr( new WGEPostprocessorGauss() ) );
postprocs.push_back( WGEPostprocessor::SPtr( new WGEPostprocessorSSAO() ) );
postprocs.push_back( WGEPostprocessor::SPtr( new WGEPostprocessorLineAO() ) );
return postprocs;
......
......@@ -138,7 +138,8 @@ public:
virtual ~WGEPostprocessor();
/**
* Create instance. Uses the protected constructor. Implement it if you derive from this class!
* Create instance. Uses the protected constructor. Implement it if you derive from this class! This is called whenever your postprocessor is
* applied to the standard render-output. You can add your own constructors and creators for other cases.
*
* \param offscreen use this offscreen node to add your texture pass'
* \param gbuffer the input textures you should use
......@@ -160,7 +161,7 @@ public:
virtual osg::ref_ptr< osg::Texture2D > getOutput() const;
/**
* Returns the new depth texture. Allows you to modify the depth values. By default, this is the input depth texture.
* Returns the new depth texture. Allows you to modify the depth values. By default, this is NULL. Check this!
*
* \return the depth texture
*/
......@@ -180,17 +181,6 @@ public:
*/
virtual const std::string getDescription() const;
protected:
/**
* Constructor. Call this constructor from your derived class.
*
* \param offscreen use this offscreen node to add your texture pass'
* \param gbuffer the input textures you should use
* \param name a name for this postprocessor
* \param description a useful description
*/
WGEPostprocessor( osg::ref_ptr< WGEOffscreenRenderNode > offscreen, const PostprocessorInput& gbuffer,
std::string name, std::string description );
/**
* The texture contains the result
*/
......
......@@ -36,7 +36,7 @@ WGEPostprocessorCelShading::WGEPostprocessorCelShading():
WGEPostprocessorCelShading::WGEPostprocessorCelShading( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
const WGEPostprocessor::PostprocessorInput& gbuffer ):
WGEPostprocessor( offscreen, gbuffer, "Cel Shading",
WGEPostprocessor( "Cel Shading",
"This postprocessor reduces color by binning colors." )
{
// we also provide a property
......
......@@ -37,7 +37,7 @@ WGEPostprocessorEdgeEnhance::WGEPostprocessorEdgeEnhance():
WGEPostprocessorEdgeEnhance::WGEPostprocessorEdgeEnhance( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
const WGEPostprocessor::PostprocessorInput& gbuffer ):
WGEPostprocessor( offscreen, gbuffer, "Edge Enhance",
WGEPostprocessor( "Edge Enhance",
"Edge detection filter to emphasize edges in complex geometry." )
{
// we also provide a property
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <osg/Camera>
#include "../shaders/WGEPropertyUniform.h"
#include "../shaders/WGEShaderPropertyDefineOptions.h"
#include "WGEPostprocessorGauss.h"
WGEPostprocessorGauss::WGEPostprocessorGauss():
WGEPostprocessor( "Gauss Filtering",
"Gauss filter all specified input textures." )
{
}
WGEPostprocessorGauss::WGEPostprocessorGauss( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
osg::ref_ptr< osg::Texture2D > tex0,
osg::ref_ptr< osg::Texture2D > tex1,
osg::ref_ptr< osg::Texture2D > tex2,
osg::ref_ptr< osg::Texture2D > tex3,
osg::ref_ptr< osg::Texture2D > tex4,
osg::ref_ptr< osg::Texture2D > tex5,
osg::ref_ptr< osg::Texture2D > tex6,
osg::ref_ptr< osg::Texture2D > tex7 ):
WGEPostprocessor( "Gauss Filtering",
"Gauss filter all specified input textures." )
{
// Use the standard postprocessor uber-shader
WGEShader::RefPtr s = new WGEShader( "WGEPostprocessor" );
s->setDefine( "WGE_POSTPROCESSOR_GAUSS" );
// also add the m_effectOnly property as shader preprocessor
s->addPreprocessor( m_effectOnlyPreprocessor );
// create the rendering pass
osg::ref_ptr< WGEOffscreenTexturePass > pass = offscreen->addTextureProcessingPass( s, "Gauss Filter" );
// for each of the textures do:
// attach color0 output and bind tex0
m_resultTexture = pass->attach( osg::Camera::COLOR_BUFFER0, GL_RGBA );
m_resultTextures.push_back( m_resultTexture );
pass->bind( tex0 );
s->setDefine( "WGE_POSTPROCESSOR_GAUSS_UNIT0" );
// attach color1 output and bind tex1
if( tex1 )
{
m_resultTextures.push_back( pass->attach( osg::Camera::COLOR_BUFFER1, GL_RGBA ) );
pass->bind( tex1 );
s->setDefine( "WGE_POSTPROCESSOR_GAUSS_UNIT1" );
}
// attach color2 output and bind tex2
if( tex2 )
{
m_resultTextures.push_back( pass->attach( osg::Camera::COLOR_BUFFER2, GL_RGBA ) );
pass->bind( tex2 );
s->setDefine( "WGE_POSTPROCESSOR_GAUSS_UNIT2" );
}
// attach color3 output and bind tex3
if( tex3 )
{
m_resultTextures.push_back( pass->attach( osg::Camera::COLOR_BUFFER3, GL_RGBA ) );
pass->bind( tex3 );
s->setDefine( "WGE_POSTPROCESSOR_GAUSS_UNIT3" );
}
// attach color4 output and bind tex4
if( tex4 )
{
m_resultTextures.push_back( pass->attach( osg::Camera::COLOR_BUFFER4, GL_RGBA ) );
pass->bind( tex4 );
s->setDefine( "WGE_POSTPROCESSOR_GAUSS_UNIT4" );
}
// attach color5 output and bind tex5
if( tex5 )
{
m_resultTextures.push_back( pass->attach( osg::Camera::COLOR_BUFFER5, GL_RGBA ) );
pass->bind( tex5 );
s->setDefine( "WGE_POSTPROCESSOR_GAUSS_UNIT5" );
}
// attach color6 output and bind tex6
if( tex6 )
{
m_resultTextures.push_back( pass->attach( osg::Camera::COLOR_BUFFER6, GL_RGBA ) );
pass->bind( tex6 );
s->setDefine( "WGE_POSTPROCESSOR_GAUSS_UNIT6" );
}
// attach color7 output and bind tex7
if( tex7 )
{
m_resultTextures.push_back( pass->attach( osg::Camera::COLOR_BUFFER7, GL_RGBA ) );
pass->bind( tex7 );
s->setDefine( "WGE_POSTPROCESSOR_GAUSS_UNIT7" );
}
}
WGEPostprocessorGauss::~WGEPostprocessorGauss()
{
// cleanup
}
WGEPostprocessor::SPtr WGEPostprocessorGauss::create( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
const WGEPostprocessor::PostprocessorInput& gbuffer ) const
{
return WGEPostprocessor::SPtr( new WGEPostprocessorGauss( offscreen, gbuffer.m_colorTexture ) );
}
const std::vector< osg::ref_ptr< osg::Texture2D > >& WGEPostprocessorGauss::getResultTextures() const
{
return m_resultTextures;
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WGEPOSTPROCESSORGAUSS_H
#define WGEPOSTPROCESSORGAUSS_H
#include <boost/shared_ptr.hpp>
#include <osg/Texture2D>
#include "WGEPostprocessor.h"
/**
* Gauss filtering of the input. It does filter all the textures you bind on it and returns a gauss filtered version. If you want to define the
* exact list of textures to filter in one pass, use the alternative \ref create call.
*/
class WGEPostprocessorGauss: public WGEPostprocessor
{
public:
/**
* Convenience typedef for a boost::shared_ptr< WGEPostprocessorGauss >.
*/
typedef boost::shared_ptr< WGEPostprocessorGauss > SPtr;
/**
* Convenience typedef for a boost::shared_ptr< const WGEPostprocessorGauss >.
*/
typedef boost::shared_ptr< const WGEPostprocessorGauss > ConstSPtr;
/**
* Default constructor.
*/
WGEPostprocessorGauss();
/**
* Constructor. We implement a public constructor which can take more textures as input
*
* \param offscreen use this offscreen node to add your texture pass'
* \param tex0 texture to filter
* \param tex1 texture to filter
* \param tex2 texture to filter
* \param tex3 texture to filter
* \param tex4 texture to filter
* \param tex5 texture to filter
* \param tex6 texture to filter
* \param tex7 texture to filter
*/
WGEPostprocessorGauss( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
osg::ref_ptr< osg::Texture2D > tex0,
osg::ref_ptr< osg::Texture2D > tex1 = osg::ref_ptr< osg::Texture2D >(),
osg::ref_ptr< osg::Texture2D > tex2 = osg::ref_ptr< osg::Texture2D >(),
osg::ref_ptr< osg::Texture2D > tex3 = osg::ref_ptr< osg::Texture2D >(),
osg::ref_ptr< osg::Texture2D > tex4 = osg::ref_ptr< osg::Texture2D >(),
osg::ref_ptr< osg::Texture2D > tex5 = osg::ref_ptr< osg::Texture2D >(),
osg::ref_ptr< osg::Texture2D > tex6 = osg::ref_ptr< osg::Texture2D >(),
osg::ref_ptr< osg::Texture2D > tex7 = osg::ref_ptr< osg::Texture2D >() );
/**
* Destructor.
*/
virtual ~WGEPostprocessorGauss();
/**
* Create instance. Uses the protected constructor. Implement it if you derive from this class!
*
* \param offscreen use this offscreen node to add your texture pass'
* \param gbuffer the input textures you should use
*/
virtual WGEPostprocessor::SPtr create( osg::ref_ptr< WGEOffscreenRenderNode > offscreen, const PostprocessorInput& gbuffer ) const;
/**
* This processor can produce multiple outputs. Grab them here. This vector always contains at least the first filtered texture in unit 0
*
* \return the vector
*/
const std::vector< osg::ref_ptr< osg::Texture2D > >& getResultTextures() const;
protected:
private:
/**
* Contains all output textures we produce in the order of binding.
*/
std::vector< osg::ref_ptr< osg::Texture2D > > m_resultTextures;
};
#endif // WGEPOSTPROCESSORGAUSS_H
......@@ -37,8 +37,7 @@ WGEPostprocessorLineAO::WGEPostprocessorLineAO():
WGEPostprocessorLineAO::WGEPostprocessorLineAO( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
const WGEPostprocessor::PostprocessorInput& gbuffer ):
WGEPostprocessor( offscreen, gbuffer,
"LineAO",
WGEPostprocessor( "LineAO",
"LineAO is a special ambient occlusion technique optimized for dense line and tube rendering." )
{
// the LineAO algorithm has some parameters. Provide these parameters to the user
......
......@@ -38,8 +38,7 @@ WGEPostprocessorSSAO::WGEPostprocessorSSAO():
WGEPostprocessorSSAO::WGEPostprocessorSSAO( osg::ref_ptr< WGEOffscreenRenderNode > offscreen,
const WGEPostprocessor::PostprocessorInput& gbuffer ):
WGEPostprocessor( offscreen, gbuffer,
"SSAO",
WGEPostprocessor( "SSAO",
"SSAO is a special ambient occlusion technique." )
{
// the SSAO algorithm has some parameters. Provide these parameters to the user
......
......@@ -139,6 +139,51 @@ vec4 getCelShading()
#endif
#ifdef WGE_POSTPROCESSOR_GAUSS
/**
* Returns the gauss-smoothed color of the specified pixel from the input texture.
*
* \param where the pixel to grab
* \param sampler the texture to gauss
*
* \return the color
*/
vec4 getGaussedColor( vec2 where, sampler2D sampler )
{
// get the 8-neighbourhood
vec4 gaussedColorc = texture2D( sampler, where );
vec4 gaussedColorbl = texture2D( sampler, where + vec2( -offsetX, -offsetY ) );
vec4 gaussedColorl = texture2D( sampler, where + vec2( -offsetX, 0.0 ) );
vec4 gaussedColortl = texture2D( sampler, where + vec2( -offsetX, offsetY ) );
vec4 gaussedColort = texture2D( sampler, where + vec2( 0.0, offsetY ) );
vec4 gaussedColortr = texture2D( sampler, where + vec2( offsetX, offsetY ) );
vec4 gaussedColorr = texture2D( sampler, where + vec2( offsetX, 0.0 ) );
vec4 gaussedColorbr = texture2D( sampler, where + vec2( offsetX, offsetY ) );
vec4 gaussedColorb = texture2D( sampler, where + vec2( 0.0, -offsetY ) );
// apply Gauss filter
vec4 gaussed = ( 1.0 / 16.0 ) * (
1.0 * gaussedColortl + 2.0 * gaussedColort + 1.0 * gaussedColortr +
2.0 * gaussedColorl + 4.0 * gaussedColorc + 2.0 * gaussedColorr +
1.0 * gaussedColorbl + 2.0 * gaussedColorb + 1.0 * gaussedColorbr );
return gaussed;
}
/**
* Returns the gauss-smoothed color of the current pixel from the input color texture.
*
* \param sampler the texture to gauss
*
* \return the color
*/
vec4 getGaussedColor( sampler2D sampler )
{
return getGaussedColor( pixelCoord, sampler );
}
#endif
#ifdef WGE_POSTPROCESSOR_SSAO
#ifndef WGE_POSTPROCESSOR_SSAO_SAMPLES
......@@ -467,7 +512,7 @@ void main()
// don't do this stuff for background pixel
float depth = getDepth();
gl_FragDepth = depth;
gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
gl_FragData[0] = vec4( 1.0, 0.0, 0.0, 1.0 );
if( depth > 0.99 )
{
discard;
......@@ -486,7 +531,7 @@ void main()
#endif
// apply operation and output color
gl_FragColor = vec4( getColor().rgb EDGEOP, 1.0 );
gl_FragData[0] = vec4( getColor().rgb EDGEOP, 1.0 );
#else
// also do this for the effect-only output
#ifdef WGE_POSTPROCESSOR_EDGE_BLACKEDGE
......@@ -495,30 +540,58 @@ void main()
// for white borders, add
#define EDGEOP 0.0 +
#endif
gl_FragColor = vec4( vec3( EDGEOP getEdge() ), 1.0 );
gl_FragData[0] = vec4( vec3( EDGEOP getEdge() ), 1.0 );
#endif
#endif
#ifdef WGE_POSTPROCESSOR_CEL
// output the depth and final color.
gl_FragColor = getCelShading();
gl_FragData[0] = getCelShading();
#endif
#ifdef WGE_POSTPROCESSOR_GAUSS
// output the depth and final color.
#ifdef WGE_POSTPROCESSOR_GAUSS_UNIT0
gl_FragData[0] = getGaussedColor( pixelCoord, u_texture0Sampler );
#endif
#ifdef WGE_POSTPROCESSOR_GAUSS_UNIT1
gl_FragData[1] = getGaussedColor( pixelCoord, u_texture1Sampler );
#endif
#ifdef WGE_POSTPROCESSOR_GAUSS_UNIT2
gl_FragData[2] = getGaussedColor( pixelCoord, u_texture2Sampler );
#endif
#ifdef WGE_POSTPROCESSOR_GAUSS_UNIT3
gl_FragData[3] = getGaussedColor( pixelCoord, u_texture3Sampler );
#endif
#ifdef WGE_POSTPROCESSOR_GAUSS_UNIT4
gl_FragData[4] = getGaussedColor( pixelCoord, u_texture4Sampler );
#endif
#ifdef WGE_POSTPROCESSOR_GAUSS_UNIT5
gl_FragData[5] = getGaussedColor( pixelCoord, u_texture5Sampler );
#endif
#ifdef WGE_POSTPROCESSOR_GAUSS_UNIT6
gl_FragData[6] = getGaussedColor( pixelCoord, u_texture6Sampler );
#endif
#ifdef WGE_POSTPROCESSOR_GAUSS_UNIT7
gl_FragData[7] = getGaussedColor( pixelCoord, u_texture7Sampler );
#endif
#endif
#ifdef WGE_POSTPROCESSOR_SSAO
// output color AND SSAO?
#ifdef WGE_POSTPROCESSOR_OUTPUT_COMBINE
gl_FragColor = vec4( getColor().rgb * getSSAO(), 1.0 );
gl_FragData[0] = vec4( getColor().rgb * getSSAO(), 1.0 );
#else
gl_FragColor = vec4( vec3( getSSAO() ), 1.0 );
gl_FragData[0] = vec4( vec3( getSSAO() ), 1.0 );
#endif
#endif
#ifdef WGE_POSTPROCESSOR_LINEAO
// output color AND SSAO?
#ifdef WGE_POSTPROCESSOR_OUTPUT_COMBINE
gl_FragColor = vec4( getColor().rgb * getLineAO(), 1.0 );
gl_FragData[0] = vec4( getColor().rgb * getLineAO(), 1.0 );
#else
gl_FragColor = vec4( vec3( getLineAO() ), 1.0 );
gl_FragData[0] = vec4( vec3( getLineAO() ), 1.0 );
#endif
#endif
}
......
......@@ -56,6 +56,12 @@ uniform sampler2D u_texture2Sampler;
uniform sampler2D u_texture3Sampler;
#define u_depthSampler u_texture3Sampler
/**
* The tangent data
*/
uniform sampler2D u_texture4Sampler;
#define u_tangentSampler u_texture4Sampler
/**
* The white-noise 3 channel texture: sampler
*/
......@@ -63,10 +69,14 @@ uniform sampler2D u_texture5Sampler;
#define u_noiseSampler u_texture5Sampler
/**
* The tangent data
* Texture in unit 6
*/
uniform sampler2D u_texture4Sampler;
#define u_tangentSampler u_texture4Sampler
uniform sampler2D u_texture6Sampler;
/**
* Texture in unit 7
*/
uniform sampler2D u_texture7Sampler;
/**
* Size of texture in pixels
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment