Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
OpenWalnut
OpenWalnut Core
Commits
7e5d0d74
Commit
7e5d0d74
authored
Dec 14, 2011
by
Sebastian Eichelbaum
Browse files
[ADD] - added SSAO and LineAO skeleton to new posprocessor scheme
parent
2bb01c26
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
528 additions
and
22 deletions
+528
-22
src/core/graphicsEngine/postprocessing/WGEPostprocessingNode.cpp
...e/graphicsEngine/postprocessing/WGEPostprocessingNode.cpp
+0
-6
src/core/graphicsEngine/postprocessing/WGEPostprocessor.cpp
src/core/graphicsEngine/postprocessing/WGEPostprocessor.cpp
+7
-2
src/core/graphicsEngine/postprocessing/WGEPostprocessor.h
src/core/graphicsEngine/postprocessing/WGEPostprocessor.h
+3
-1
src/core/graphicsEngine/postprocessing/WGEPostprocessorLineAO.cpp
.../graphicsEngine/postprocessing/WGEPostprocessorLineAO.cpp
+84
-0
src/core/graphicsEngine/postprocessing/WGEPostprocessorLineAO.h
...re/graphicsEngine/postprocessing/WGEPostprocessorLineAO.h
+78
-0
src/core/graphicsEngine/postprocessing/WGEPostprocessorSSAO.cpp
...re/graphicsEngine/postprocessing/WGEPostprocessorSSAO.cpp
+109
-0
src/core/graphicsEngine/postprocessing/WGEPostprocessorSSAO.h
...core/graphicsEngine/postprocessing/WGEPostprocessorSSAO.h
+78
-0
src/core/graphicsEngine/shaders/shaders/WGEPostprocessor-fragment.glsl
...hicsEngine/shaders/shaders/WGEPostprocessor-fragment.glsl
+134
-13
src/core/graphicsEngine/shaders/shaders/WGEPostprocessorUtils-fragment.glsl
...ngine/shaders/shaders/WGEPostprocessorUtils-fragment.glsl
+22
-0
src/modules/isosurfaceRaytracer/shaders/WMIsosurfaceRaytracer-fragment.glsl
...faceRaytracer/shaders/WMIsosurfaceRaytracer-fragment.glsl
+4
-0
src/modules/isosurfaceRaytracer/shaders/WMIsosurfaceRaytracer-varyings.glsl
...faceRaytracer/shaders/WMIsosurfaceRaytracer-varyings.glsl
+3
-0
src/modules/isosurfaceRaytracer/shaders/WMIsosurfaceRaytracer-vertex.glsl
...urfaceRaytracer/shaders/WMIsosurfaceRaytracer-vertex.glsl
+6
-0
No files found.
src/core/graphicsEngine/postprocessing/WGEPostprocessingNode.cpp
View file @
7e5d0d74
...
...
@@ -96,12 +96,6 @@ WGEPostprocessingNode::WGEPostprocessingNode( osg::ref_ptr< osg::Camera > refere
// let the props control some stuff
addUpdateCallback
(
new
WGESwitchCallback
<
WPropSelection
>
(
m_activePostprocessor
)
);
// some of the post-processors need some white noise, like the ssao
/* const size_t size = 64;
osg::ref_ptr< WGETexture2D > randTex = wge::genWhiteNoiseTexture( size, size, 3 );
m_postprocess->bind( randTex, 4 );
*/
}
WGEPostprocessingNode
::~
WGEPostprocessingNode
()
...
...
src/core/graphicsEngine/postprocessing/WGEPostprocessor.cpp
View file @
7e5d0d74
...
...
@@ -24,6 +24,8 @@
#include "WGEPostprocessorEdgeEnhance.h"
#include "WGEPostprocessorCelShading.h"
#include "WGEPostprocessorSSAO.h"
#include "WGEPostprocessorLineAO.h"
#include "WGEPostprocessor.h"
...
...
@@ -86,13 +88,15 @@ WGEPostprocessor::PostprocessorInput WGEPostprocessor::PostprocessorInput::attac
return
buf
;
}
void
WGEPostprocessor
::
PostprocessorInput
::
bind
(
osg
::
ref_ptr
<
WGEOffscreenRenderPass
>
to
)
const
size_t
WGEPostprocessor
::
PostprocessorInput
::
bind
(
osg
::
ref_ptr
<
WGEOffscreenRenderPass
>
to
)
const
{
to
->
bind
(
m_colorTexture
,
0
);
to
->
bind
(
m_normalTexture
,
1
);
to
->
bind
(
m_parameterTexture
,
2
);
to
->
bind
(
m_depthTexture
,
3
);
to
->
bind
(
m_tangentTexture
,
4
);
return
5
;
}
WGEPostprocessor
::
ProcessorList
WGEPostprocessor
::
getPostprocessors
()
...
...
@@ -102,7 +106,8 @@ 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
WGEPostprocessorSSAO
()
)
);
postprocs
.
push_back
(
WGEPostprocessor
::
SPtr
(
new
WGEPostprocessorLineAO
()
)
);
return
postprocs
;
}
...
...
src/core/graphicsEngine/postprocessing/WGEPostprocessor.h
View file @
7e5d0d74
...
...
@@ -71,8 +71,10 @@ public:
* Attaches these textures to the specified renderpass
*
* \param to attach to this
*
* \return the ID of the NEXT free texture unit you can use
*/
void
bind
(
osg
::
ref_ptr
<
WGEOffscreenRenderPass
>
to
)
const
;
size_t
bind
(
osg
::
ref_ptr
<
WGEOffscreenRenderPass
>
to
)
const
;
/**
* Color in RGBA
...
...
src/core/graphicsEngine/postprocessing/WGEPostprocessorLineAO.cpp
0 → 100644
View file @
7e5d0d74
//---------------------------------------------------------------------------
//
// 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 "WGEPostprocessorLineAO.h"
WGEPostprocessorLineAO
::
WGEPostprocessorLineAO
()
:
WGEPostprocessor
(
"LineAO"
,
"LineAO is a special ambient occlusion technique optimized for dense line and tube rendering."
)
{
}
WGEPostprocessorLineAO
::
WGEPostprocessorLineAO
(
osg
::
ref_ptr
<
WGEOffscreenRenderNode
>
offscreen
,
const
WGEPostprocessor
::
PostprocessorInput
&
gbuffer
)
:
WGEPostprocessor
(
offscreen
,
gbuffer
,
"LineAO"
,
"LineAO is a special ambient occlusion technique optimized for dense line and tube rendering."
)
{
// we also provide a property
WPropBool
whiteEdge
=
m_properties
->
addProperty
(
"White Edge"
,
"If set, the edge is drawn in white instead of black."
,
false
);
WPropDouble
edgeThresholdL
=
m_properties
->
addProperty
(
"Edge Lower Threshold"
,
"Define the edge threshold. Filters way
\"
weak
\"
edges."
,
0.0
);
WPropDouble
edgeThresholdU
=
m_properties
->
addProperty
(
"Edge Upper Threshold"
,
"Define the edge threshold. Filters way
\"
weak
\"
edges."
,
1.0
);
edgeThresholdL
->
setMin
(
0.0
);
edgeThresholdL
->
setMax
(
1.0
);
edgeThresholdU
->
setMin
(
0.0
);
edgeThresholdU
->
setMax
(
1.0
);
// Use the standard postprocessor uber-shader
WGEShader
::
RefPtr
s
=
new
WGEShader
(
"WGEPostprocessor"
);
s
->
setDefine
(
"WGE_POSTPROCESSOR_EDGE"
);
// also add the m_effectOnly property as shader preprocessor
s
->
addPreprocessor
(
m_effectOnlyPreprocessor
);
s
->
addPreprocessor
(
WGEShaderPreprocessor
::
SPtr
(
new
WGEShaderPropertyDefineOptions
<
WPropBool
>
(
whiteEdge
,
"WGE_POSTPROCESSOR_EDGE_BLACKEDGE"
,
"WGE_POSTPROCESSOR_EDGE_WHITEEDGE"
)
)
);
// create the rendering pass
osg
::
ref_ptr
<
WGEOffscreenTexturePass
>
pass
=
offscreen
->
addTextureProcessingPass
(
s
,
"Edge Detection"
);
pass
->
getOrCreateStateSet
()
->
addUniform
(
new
WGEPropertyUniform
<
WPropDouble
>
(
"u_edgeEdgeThresholdUpper"
,
edgeThresholdU
)
);
pass
->
getOrCreateStateSet
()
->
addUniform
(
new
WGEPropertyUniform
<
WPropDouble
>
(
"u_edgeEdgeThresholdLower"
,
edgeThresholdL
)
);
// attach color0 output
m_resultTexture
=
pass
->
attach
(
osg
::
Camera
::
COLOR_BUFFER0
,
GL_RGB
);
// provide the Gbuffer input
gbuffer
.
bind
(
pass
);
}
WGEPostprocessorLineAO
::~
WGEPostprocessorLineAO
()
{
// cleanup
}
WGEPostprocessor
::
SPtr
WGEPostprocessorLineAO
::
create
(
osg
::
ref_ptr
<
WGEOffscreenRenderNode
>
offscreen
,
const
WGEPostprocessor
::
PostprocessorInput
&
gbuffer
)
const
{
return
WGEPostprocessor
::
SPtr
(
new
WGEPostprocessorLineAO
(
offscreen
,
gbuffer
)
);
}
src/core/graphicsEngine/postprocessing/WGEPostprocessorLineAO.h
0 → 100644
View file @
7e5d0d74
//---------------------------------------------------------------------------
//
// 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 WGEPOSTPROCESSORLINEAO_H
#define WGEPOSTPROCESSORLINEAO_H
#include <boost/shared_ptr.hpp>
#include "WGEPostprocessor.h"
/**
* LineAO implementation.
*/
class
WGEPostprocessorLineAO
:
public
WGEPostprocessor
{
public:
/**
* Convenience typedef for a boost::shared_ptr< WGEPostprocessorLineAO >.
*/
typedef
boost
::
shared_ptr
<
WGEPostprocessorLineAO
>
SPtr
;
/**
* Convenience typedef for a boost::shared_ptr< const WGEPostprocessorLineAO >.
*/
typedef
boost
::
shared_ptr
<
const
WGEPostprocessorLineAO
>
ConstSPtr
;
/**
* Default constructor.
*/
WGEPostprocessorLineAO
();
/**
* Destructor.
*/
virtual
~
WGEPostprocessorLineAO
();
/**
* 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
;
protected:
/**
* Constructor. Implement this constructor and build your processing pipeline in here
*
* \param offscreen use this offscreen node to add your texture pass'
* \param gbuffer the input textures you should use
*/
WGEPostprocessorLineAO
(
osg
::
ref_ptr
<
WGEOffscreenRenderNode
>
offscreen
,
const
PostprocessorInput
&
gbuffer
);
private:
};
#endif // WGEPOSTPROCESSORLINEAO_H
src/core/graphicsEngine/postprocessing/WGEPostprocessorSSAO.cpp
0 → 100644
View file @
7e5d0d74
//---------------------------------------------------------------------------
//
// 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 "../WGETextureUtils.h"
#include "../shaders/WGEPropertyUniform.h"
#include "../shaders/WGEShaderPropertyDefine.h"
#include "WGEPostprocessorSSAO.h"
WGEPostprocessorSSAO
::
WGEPostprocessorSSAO
()
:
WGEPostprocessor
(
"SSAO"
,
"SSAO is a special ambient occlusion technique."
)
{
}
WGEPostprocessorSSAO
::
WGEPostprocessorSSAO
(
osg
::
ref_ptr
<
WGEOffscreenRenderNode
>
offscreen
,
const
WGEPostprocessor
::
PostprocessorInput
&
gbuffer
)
:
WGEPostprocessor
(
offscreen
,
gbuffer
,
"SSAO"
,
"SSAO is a special ambient occlusion technique."
)
{
// the SSAO algorithm has some parameters. Provide these parameters to the user
WPropInt
ssaoSamples
=
m_properties
->
addProperty
(
"Samples"
,
"The number of samples to take in screen-space. Higher values produce better "
"quality but can reduce FPS dramatically."
,
16
);
ssaoSamples
->
setMin
(
1
);
ssaoSamples
->
setMax
(
128
);
WPropDouble
ssaoRadius
=
m_properties
->
addProperty
(
"Radius"
,
"The radius around the pixel to sample for occluders in pixels."
,
10.0
);
ssaoRadius
->
setMin
(
0.0
);
ssaoRadius
->
setMax
(
100.0
);
WPropDouble
ssaoTotalStrength
=
m_properties
->
addProperty
(
"Total Strength"
,
"The strength of the effect. Higher values emphasize the effect."
,
2.0
);
ssaoTotalStrength
->
setMin
(
0.0
);
ssaoTotalStrength
->
setMax
(
100.0
);
WPropDouble
ssaoStrength
=
m_properties
->
addProperty
(
"Strength"
,
"This defines the influence of one occluder to the overall AO effect."
,
1.0
);
ssaoStrength
->
setMin
(
0.0
);
ssaoStrength
->
setMax
(
1.0
);
WPropDouble
ssaoFalloff
=
m_properties
->
addProperty
(
"Falloff"
,
"Define the edge at which a depth difference between two pixels is assumed to "
"be non-zero."
,
0.0
);
ssaoFalloff
->
setMin
(
0.0
);
ssaoFalloff
->
setMax
(
1.0
);
// Use the standard postprocessor uber-shader
WGEShader
::
RefPtr
s
=
new
WGEShader
(
"WGEPostprocessor"
);
s
->
setDefine
(
"WGE_POSTPROCESSOR_SSAO"
);
// also add the m_effectOnly property as shader preprocessor
s
->
addPreprocessor
(
m_effectOnlyPreprocessor
);
s
->
addPreprocessor
(
WGEShaderPreprocessor
::
SPtr
(
new
WGEShaderPropertyDefine
<
WPropInt
>
(
"WGE_POSTPROCESSOR_SSAO_SAMPLES"
,
ssaoSamples
)
)
);
// create the rendering pass
osg
::
ref_ptr
<
WGEOffscreenTexturePass
>
pass
=
offscreen
->
addTextureProcessingPass
(
s
,
"SSAO"
);
pass
->
getOrCreateStateSet
()
->
addUniform
(
new
WGEPropertyUniform
<
WPropDouble
>
(
"u_ssaoTotalStrength"
,
ssaoTotalStrength
)
);
pass
->
getOrCreateStateSet
()
->
addUniform
(
new
WGEPropertyUniform
<
WPropDouble
>
(
"u_ssaoStrength"
,
ssaoStrength
)
);
pass
->
getOrCreateStateSet
()
->
addUniform
(
new
WGEPropertyUniform
<
WPropDouble
>
(
"u_ssaoRadius"
,
ssaoRadius
)
);
pass
->
getOrCreateStateSet
()
->
addUniform
(
new
WGEPropertyUniform
<
WPropDouble
>
(
"u_ssaoFalloff"
,
ssaoFalloff
)
);
// attach color0 output
m_resultTexture
=
pass
->
attach
(
osg
::
Camera
::
COLOR_BUFFER0
,
GL_RGB
);
// provide the Gbuffer input
size_t
gBufUnitOffset
=
gbuffer
.
bind
(
pass
);
// this effect needs some additional noise texture:
// some of the post-processors need some white noise, like the ssao
const
size_t
size
=
64
;
osg
::
ref_ptr
<
WGETexture2D
>
randTex
=
wge
::
genWhiteNoiseTexture
(
size
,
size
,
3
);
pass
->
bind
(
randTex
,
gBufUnitOffset
);
}
WGEPostprocessorSSAO
::~
WGEPostprocessorSSAO
()
{
// cleanup
}
WGEPostprocessor
::
SPtr
WGEPostprocessorSSAO
::
create
(
osg
::
ref_ptr
<
WGEOffscreenRenderNode
>
offscreen
,
const
WGEPostprocessor
::
PostprocessorInput
&
gbuffer
)
const
{
return
WGEPostprocessor
::
SPtr
(
new
WGEPostprocessorSSAO
(
offscreen
,
gbuffer
)
);
}
src/core/graphicsEngine/postprocessing/WGEPostprocessorSSAO.h
0 → 100644
View file @
7e5d0d74
//---------------------------------------------------------------------------
//
// 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 WGEPOSTPROCESSORSSAO_H
#define WGEPOSTPROCESSORSSAO_H
#include <boost/shared_ptr.hpp>
#include "WGEPostprocessor.h"
/**
* Naive SSAO implementation.
*/
class
WGEPostprocessorSSAO
:
public
WGEPostprocessor
{
public:
/**
* Convenience typedef for a boost::shared_ptr< WGEPostprocessorSSAO >.
*/
typedef
boost
::
shared_ptr
<
WGEPostprocessorSSAO
>
SPtr
;
/**
* Convenience typedef for a boost::shared_ptr< const WGEPostprocessorSSAO >.
*/
typedef
boost
::
shared_ptr
<
const
WGEPostprocessorSSAO
>
ConstSPtr
;
/**
* Default constructor.
*/
WGEPostprocessorSSAO
();
/**
* Destructor.
*/
virtual
~
WGEPostprocessorSSAO
();
/**
* 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
;
protected:
/**
* Constructor. Implement this constructor and build your processing pipeline in here
*
* \param offscreen use this offscreen node to add your texture pass'
* \param gbuffer the input textures you should use
*/
WGEPostprocessorSSAO
(
osg
::
ref_ptr
<
WGEOffscreenRenderNode
>
offscreen
,
const
PostprocessorInput
&
gbuffer
);
private:
};
#endif // WGEPOSTPROCESSORSSAO_H
src/core/graphicsEngine/shaders/shaders/WGEPostprocessor-fragment.glsl
View file @
7e5d0d74
...
...
@@ -32,21 +32,10 @@
#include "WGEPostprocessorUtils-fragment.glsl"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Uniforms
//
Global
Uniforms
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// These are specific to the postprocessor
/**
* The number of bins to use for cel shading
*/
uniform
int
u_celShadingBins
=
2
;
/**
* The threshold used to clip away "unwanted" borders. Basically removes noise
*/
uniform
float
u_edgeEdgeThresholdLower
=
0
.
25
;
uniform
float
u_edgeEdgeThresholdUpper
=
0
.
75
;
// These are NOT specific to any postprocessor
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Varying
...
...
@@ -64,6 +53,14 @@ uniform float u_edgeEdgeThresholdUpper = 0.75;
// Postprocessors
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef WGE_POSTPROCESSOR_EDGE
/**
* The threshold used to clip away "unwanted" borders. Basically removes noise
*/
uniform
float
u_edgeEdgeThresholdLower
=
0
.
25
;
uniform
float
u_edgeEdgeThresholdUpper
=
0
.
75
;
/**
* Apply laplace-filter to depth buffer. An edge is > 0.0.
*
...
...
@@ -105,6 +102,15 @@ float getEdge()
return
smoothstep
(
u_edgeEdgeThresholdLower
,
u_edgeEdgeThresholdUpper
,
edge
);
}
#endif
#ifdef WGE_POSTPROCESSOR_CEL
/**
* The number of bins to use for cel shading
*/
uniform
int
u_celShadingBins
=
2
;
/**
* Calculate the cel-shading of a specified color. The number of colors is defined by the u_celShadingSamples uniform.
*
...
...
@@ -131,6 +137,111 @@ vec4 getCelShading()
return
getCelShading
(
getColor
()
);
}
#endif
#ifdef WGE_POSTPROCESSOR_SSAO
#ifndef WGE_POSTPROCESSOR_SSAO_SAMPLES
#define WGE_POSTPROCESSOR_SSAO_SAMPLES 16
#endif
/**
* Overall effect strength. In (0,100]
*/
uniform
float
u_ssaoTotalStrength
=
2
.
0
;
/**
* Strength of occlusion caused by one occluder. In (0,1]
*/
uniform
float
u_ssaoStrength
=
1
.
0
;
/**
* Radius in screen-space. This value influences whether local or global effects influence the occlusion. In (0, 100];
*/
uniform
float
u_ssaoRadius
=
10
.
0
;
/**
* Defines a falloff at which the depthDifference is assumed to be 0 (occluder is on same height)
*/
uniform
float
u_ssaoFalloff
=
0
.
0
;
/**
* Calculate SSAO effect for the specified pixel. Requires a noise texture in u_noiseSampler. This implementation is taken from
* http://www.gamerendering.com/2009/01/14/ssao/ and slightly modified. We added a small hack to provide scaling-invariance to the effect.
*
* \param where coordinate in screenspace
* \param radius additional radius scaler.
*
* \return AO
*/
float
getSSAO
(
vec2
where
,
float
radius
)
{
float
totStrength
=
u_ssaoTotalStrength
;
float
strength
=
u_ssaoStrength
;
float
falloff
=
u_ssaoFalloff
;
float
rad
=
radius
*
u_ssaoRadius
;
#define SAMPLES WGE_POSTPROCESSOR_SSAO_SAMPLES
const
float
invSamples
=
1
.
0
/
float
(
SAMPLES
);
// grab a normal for reflecting the sample rays later on
vec3
fres
=
normalize
(
(
texture2D
(
u_noiseSampler
,
where
*
u_noiseSizeX
).
xyz
*
2
.
0
)
-
vec3
(
1
.
0
)
);
vec4
currentPixelSample
=
getNormal
(
where
);
float
currentPixelDepth
=
getDepth
(
where
);
float
radiusSS
=
(
getZoom
()
*
u_ssaoRadius
/
float
(
u_texture0SizeX
)
)
/
(
1
.
0
-
currentPixelDepth
);
// current fragment coords in screen space
vec3
ep
=
vec3
(
where
.
xy
,
currentPixelDepth
);
// get the normal of current fragment
vec3
norm
=
currentPixelSample
.
xyz
;
float
bl
=
0
.
0
;
// adjust for the depth ( not shure if this is good..)
float
radD
=
rad
/
currentPixelDepth
;
vec3
ray
,
se
;
float
occluderDepth
,
depthDifference
,
normDiff
;
for
(
int
i
=
0
;
i
<
SAMPLES
;
++
i
)
{
// get a vector (randomized inside of a sphere with radius 1.0) from a texture and reflect it
// grab a rand normal from the noise texture
vec3
randSphereNormal
=
getNoiseAsVector
(
vec2
(
float
(
i
)
/
float
(
SAMPLES
),
fres
.
y
)
);
ray
=
radiusSS
*
reflect
(
randSphereNormal
,
fres
);
// if the ray is outside the hemisphere then change direction
se
=
ep
+
sign
(
dot
(
ray
,
norm
)
)
*
ray
;
// get the depth of the occluder fragment
vec4
occluderFragment
=
getNormal
(
se
.
xy
);
occluderFragment
.
a
=
getDepth
(
se
.
xy
);
// if depthDifference is negative = occluder is behind current fragment
depthDifference
=
currentPixelDepth
-
occluderFragment
.
a
;
// calculate the difference between the normals as a weight
normDiff
=
(
1
.
0
-
dot
(
occluderFragment
.
xyz
,
norm
)
);
// the falloff equation, starts at falloff and is kind of 1/x^2 falling
bl
+=
step
(
falloff
,
depthDifference
)
*
normDiff
*
(
1
.
0
-
smoothstep
(
falloff
,
strength
,
depthDifference
)
);
}
// output the result
return
1
.
0
-
totStrength
*
bl
*
invSamples
;
}
/**
* Calculate the screen-space ambient occlusion from normal and depth map for the current pixel.
*
* \return the SSAO factor
*/
float
getSSAO
()
{
return
getSSAO
(
pixelCoord
,
1
.
0
);
}
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
...
...
@@ -143,6 +254,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
);
if
(
depth
>
0
.
99
)
{
discard
;
...
...
@@ -178,6 +290,15 @@ void main()
// output the depth and final color.
gl_FragColor
=
getCelShading
();
#endif
#ifdef WGE_POSTPROCESSOR_SSAO