Skip to content

Commit

Permalink
Change the effect compositor to fix a near/far bug
Browse files Browse the repository at this point in the history
  • Loading branch information
xarray committed Mar 10, 2013
1 parent b6bfbdf commit 70adf59
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 36 deletions.
3 changes: 2 additions & 1 deletion effectcompositor/EffectCompositor
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public:
manage the scene using internal cameras, and won't return back znear/zfar to the
main camera in osgUtil::CullVisitor
*/
void setPreservedNearAndFar( double zn, double zf ) { _preservedZNear = zn; _preservedZFar = zf; }
void setPreservedNearAndFar( unsigned int frame, double zn, double zf );
void getPreservedNearAndFar( double& zn, double& zf ) { zn = _preservedZNear; zf = _preservedZFar; }

/** Create a new pass from XML
Expand Down Expand Up @@ -260,6 +260,7 @@ protected:
osg::Camera::RenderTargetImplementation _renderTargetImpl;
double _preservedZNear;
double _preservedZFar;
unsigned int _preservingNearFarFrameNumber;
};

/** Read effect compositor from the XML file/stream */
Expand Down
32 changes: 28 additions & 4 deletions effectcompositor/EffectCompositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ class PassCullCallback : public osg::NodeCallback
_compositor->osg::Group::traverse( *nv );

// We obtain the actual near/far values at the end of forward pass traversing
_compositor->setPreservedNearAndFar( cv->getCalculatedNearPlane(), cv->getCalculatedFarPlane() );
double znear = cv->getCalculatedNearPlane();
double zfar = cv->getCalculatedFarPlane();
osg::Matrixd projection = *(cv->getProjectionMatrix());
cv->clampProjectionMatrix( projection, znear, zfar );

const osg::FrameStamp* fs = cv->getFrameStamp();
if ( fs ) _compositor->setPreservedNearAndFar( fs->getFrameNumber(), znear, zfar );
}
else if ( camera->getNumChildren()>0 ) // Use camera's own children as display surface
camera->osg::Group::traverse( *nv );
Expand All @@ -54,7 +60,9 @@ class PassCullCallback : public osg::NodeCallback
/* EffectCompositor */

EffectCompositor::EffectCompositor()
: _renderTargetImpl(osg::Camera::FRAME_BUFFER_OBJECT), _preservedZNear(FLT_MAX), _preservedZFar(FLT_MAX)
: _renderTargetImpl(osg::Camera::FRAME_BUFFER_OBJECT),
_preservedZNear(FLT_MAX), _preservedZFar(-FLT_MAX),
_preservingNearFarFrameNumber(0)
{
getOrCreateQuad();
setCurrentTechnique( "default" );
Expand All @@ -69,7 +77,8 @@ EffectCompositor::EffectCompositor( const EffectCompositor& copy, const osg::Cop
_currentTechnique(copy._currentTechnique), _quad(copy._quad),
_renderTargetImpl(copy._renderTargetImpl),
_preservedZNear(copy._preservedZNear),
_preservedZFar(copy._preservedZFar)
_preservedZFar(copy._preservedZFar),
_preservingNearFarFrameNumber(copy._preservingNearFarFrameNumber)
{
}

Expand Down Expand Up @@ -399,6 +408,21 @@ osg::Geode* EffectCompositor::getOrCreateQuad()
return _quad.get();
}

void EffectCompositor::setPreservedNearAndFar( unsigned int frame, double zn, double zf )
{
if ( _preservingNearFarFrameNumber!=frame )
{
_preservingNearFarFrameNumber = frame;
_preservedZNear = zn;
_preservedZFar = zf;
}
else
{
_preservedZNear = osg::maximum(zn, _preservedZNear);
_preservedZFar = osg::minimum(zf, _preservedZFar);
}
}

void EffectCompositor::traverse( osg::NodeVisitor& nv )
{
if ( nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR )
Expand All @@ -410,7 +434,7 @@ void EffectCompositor::traverse( osg::NodeVisitor& nv )
double fovy = 0.0, aspectRatio = 0.0, zNear = 0.0, zFar = 0.0;
if ( projectionMatrix ) projectionMatrix->getPerspective( fovy, aspectRatio, zNear, zFar );
if ( _preservedZNear!=FLT_MAX ) zNear = _preservedZNear;
if ( _preservedZFar!=FLT_MAX ) zFar = _preservedZFar;
if ( _preservedZFar!=-FLT_MAX ) zFar = _preservedZFar;

for ( InbuiltUniformList::const_iterator itr=_inbuiltUniforms.begin();
itr!=_inbuiltUniforms.end(); ++itr )
Expand Down
39 changes: 39 additions & 0 deletions effectcompositor/EffectCompositorXML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,17 @@ osg::Camera* EffectCompositor::createPassFromXML( osgDB::XmlNode* xmlNode )
}

if ( program->getNumShaders()>0 )
{
const osg::Texture* attached = camera->getBufferAttachmentMap().size()==0 ? NULL :
camera->getBufferAttachmentMap().begin()->second._texture.get();
if ( attached )
{
osg::Vec3 texSize( attached->getTextureWidth(), attached->getTextureHeight(), attached->getTextureDepth() );
stateset->addUniform( new osg::Uniform("osg_OutputBufferSize", texSize) );
}
stateset->setAttributeAndModes( program.get() );
}

if ( !numAttached )
{
// Automatically treat cameras without outputs as nested ones in the normal scene
Expand Down Expand Up @@ -659,6 +669,8 @@ osg::Uniform* EffectCompositor::createUniformFromXML( osgDB::XmlNode* xmlNode, b
// osg_ModelViewMatrix, osg_ProjectionMatrix, osg_ModelViewProjectionMatrix, osg_NormalMatrix
// osg_FrameNumber, osg_FrameTime, osg_DeltaFrameTime, osg_SimulationTime, osg_DeltaSimulationTime,
// osg_ViewMatrix, osg_ViewMatrixInverse
// These are defined in the EffectCompositor:
// osg_OutputBufferSize

std::string valueName = xmlChild->getTrimmedContents();
if ( valueName=="eye_position" ) addInbuiltUniform( EYE_POSITION, uniform );
Expand Down Expand Up @@ -765,6 +777,7 @@ osg::Shader* EffectCompositor::createShaderFromXML( osgDB::XmlNode* xmlNode, boo
else shader = new osg::Shader;
shader->setName( name );

std::string filePath;
for ( unsigned int i=0; i<xmlNode->children.size(); ++i )
{
osgDB::XmlNode* xmlChild = xmlNode->children[i].get();
Expand Down Expand Up @@ -795,12 +808,38 @@ osg::Shader* EffectCompositor::createShaderFromXML( osgDB::XmlNode* xmlNode, boo
<< xmlChild->getTrimmedContents() << std::endl;
}
else
{
filePath = osgDB::getFilePath( shaderFile );
shader->loadShaderSourceFromFile( shaderFile );
}
}
else
OSG_NOTICE << "EffectCompositor: <shader> doesn't recognize child element " << xmlChild->name << std::endl;
}

std::string code = shader->getShaderSource();
std::string::size_type pos = 0;
while ( (pos = code.find("#include", pos))!=std::string::npos )
{
// Find all "#include" and handle them
std::string::size_type pos2 = code.find_first_not_of(" ", pos + 8);
if ( pos2==std::string::npos || code[pos2]!='\"' ) break;

std::string::size_type pos3 = code.find("\"", pos2 + 1);
if ( pos3==std::string::npos ) break;

std::string filename = code.substr(pos2 + 1, pos3 - pos2 - 1);
filename = osgDB::findDataFile( filename );
if ( filename.empty() ) filename = osgDB::findDataFile( filePath + "/" + filename );

osg::ref_ptr<osg::Shader> innerShader = osgDB::readShaderFile( shader->getType(), filename );
if ( !innerShader ) break;

code.replace( pos, pos3 - pos + 1, innerShader->getShaderSource() );
pos += innerShader->getShaderSource().size();
}
shader->setShaderSource( code );

if ( asGlobal )
{
if ( !setShader(name, shader.get()) )
Expand Down
66 changes: 35 additions & 31 deletions effectcompositor/pessao.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,21 @@
<shader name="getnormaldepth_fs" type="fragment">
<source>
<![CDATA[
#define POLY_ESTIMATED_SSAO_NORMAL_BASED 1
uniform vec3 leftDirection;
uniform vec3 upDirection;
varying vec3 normal;
varying float depthValue;
void main()
{
#if POLY_ESTIMATED_SSAO_NORMAL_BASED
float l = dot(leftDirection, normal);
float u = dot(upDirection, normal);
gl_FragColor = vec4(depthValue, l, u, step(0.9, gl_FrontMaterial.diffuse.a));
#else
gl_FragColor = vec4(depthValue, 0.0, 0.0, step(0.9, gl_FrontMaterial.diffuse.a));
#endif
}
]]>
</source>
Expand All @@ -59,16 +64,16 @@
<shader name="ssao_process_fs" type="fragment">
<source>
<![CDATA[
#define POLY_ESTIMATED_SSAO_NORMAL_BASED 1
uniform sampler2D depthTex;
uniform vec3 lookDirection;
uniform vec3 leftDirection;
uniform vec3 upDirection;
uniform float nearPlaneValue;
uniform float farPlaneValue;
uniform float viewportWidth;
uniform float viewportHeight;
uniform float contrastValue;
uniform unsigned int osg_FrameNumber;
uniform vec3 osg_OutputBufferSize;
const float subSamplingFactor = 1.0;
const float loopMaxPESSAO = 30.0;
Expand Down Expand Up @@ -115,22 +120,25 @@
vec4 readNormalDepth(in vec2 coord)
{
vec4 d = texture2D(depthTex, coord);
#if POLY_ESTIMATED_SSAO_NORMAL_BASED
vec3 normal = d.y * leftDirection;
normal += d.z * upDirection;
float q = sqrt(1.0 - d.x * d.x + d.y * d.y);
normal += q * lookDirection;
return vec4(normalize(normal), d.x);
#else
return vec4(0.0, 0.0, 0.0, d.x);
#endif
}
void main()
{
vec4 centerDepth = readNormalDepth(gl_TexCoord[0].xy);
if (centerDepth.w <= 0.0) return;
vec2 textureSize = vec2(viewportWidth, viewportHeight);
vec2 metricNearFarPlanePixelResolution = vec2(nearPlaneValue * 0.5, farPlaneValue * 2.0);
metricNearFarPlanePixelResolution *= 1.0 / viewportHeight;
metricNearFarPlanePixelResolution *= 1.0 / osg_OutputBufferSize.y;
float powContrast = pow(0.125 * contrastValue, 0.25);
float wFilter = 1.0 - centerDepth.w / (farPlaneValue * 2.0);
Expand All @@ -153,14 +161,16 @@
angle0 += pi2 + ((pi1 * max(0.0, idxMax - idx - 1.0) / (2.0 * idxMax)));
vec4 ndL1, ndL2, ndL3, ndL4, ndR1, ndR2, ndR3, ndR4;
vec2 v1 = initRadiusInPixelPESSAO * vec2(cos(angle0), sin(angle0)) / textureSize;
vec2 v1 = initRadiusInPixelPESSAO * vec2(cos(angle0), sin(angle0)) / osg_OutputBufferSize.xy;
ndL1 = ndL2 = centerDepth;
ndL3 = ndL4 = readNormalDepth(gl_TexCoord[0].xy-(v1));
ndR1 = ndR2 = centerDepth;
ndR3 = ndR4 = readNormalDepth(gl_TexCoord[0].xy+(v1));
float finalAO = 0.0, finalAOCnt = 0.0;
#if POLY_ESTIMATED_SSAO_NORMAL_BASED
float NB_maxAO = 0.0, NB_sumAO = 0.0, NB_sumAOCNT = 0.0;
#endif
float currentAngle1 = angle0;
float diffZDepthSum = 1.0, maxDiffZDepth = 0.0;
Expand All @@ -172,7 +182,7 @@
/* read next depth/normal value */
float radius = initRadiusInPixelPESSAO + pow(sin(pi2 * sLoop), 3.0) * prAtPOIRadius;
vec2 v4 = radius * vec2(cos(angle1), sin(angle1)) / textureSize;
vec2 v4 = radius * vec2(cos(angle1), sin(angle1)) / osg_OutputBufferSize.xy;
ndL4 = readNormalDepth(gl_TexCoord[0].xy - v4);
ndR4 = readNormalDepth(gl_TexCoord[0].xy + v4);
Expand Down Expand Up @@ -209,7 +219,7 @@
r = k * r;
finalAOCnt += r;
finalAO += r * (1.0 - updateAO);
#if POLY_ESTIMATED_SSAO_NORMAL_BASED
/* use normal for special effects */
float NB_angleDiff = dot(ndL4.xyz, ndR4.xyz);
float classifier = -dot(cross(ndL4.xyz, centerDepth.xyz), cross(centerDepth.xyz, ndR4.xyz));
Expand All @@ -219,17 +229,19 @@
float nr = 1.0 + (1.0 - att * sLoop) * (1.0 - finalAO / finalAOCnt);
NB_sumAO += nr * clamp(1.0 - NB_maxAO, 0.0, 1.0);
NB_sumAOCNT += nr;
#endif
/* update iLoop */
float speedUP = max(1.0, pow(1.0 + speedUpILoopPESSAO, diffZDepthSum));
iLoop += speedUP;
}
/* increase/decrease contrast*/
float NB_ao = clamp(pow((NB_sumAO / NB_sumAOCNT), 1.0 - finalAO + contrastPESSAO), 0.0, 1.0);
finalAO = clamp(1.0 - (1.0 - pow(finalAO / finalAOCnt, powContrast)), 0.0, 1.0);
#if POLY_ESTIMATED_SSAO_NORMAL_BASED
float NB_ao = clamp(pow((NB_sumAO / NB_sumAOCNT), 1.0 - finalAO + contrastPESSAO), 0.0, 1.0);
finalAO = finalAO * (1.0- (1.0 - finalAO) * NB_ao);
#endif
AO2Write += abs(finalAO);
AO2WriteDIV += 1.0;
idx += max(1.0, ceil((1.0 - fastOffPESSAO) * step(0.995, AO2Write / AO2WriteDIV) * idxMax));
Expand Down Expand Up @@ -295,10 +307,9 @@
<![CDATA[
uniform sampler2D aoTex;
uniform sampler2D sceneTex;
uniform vec3 lightDirUniform;
uniform float colorBlendFactor;
uniform float viewportWidth;
uniform float viewportHeight;
uniform vec3 lightDirUniform;
uniform vec3 osg_OutputBufferSize;
varying vec3 normal;
varying vec3 localNormal;
Expand All @@ -317,8 +328,7 @@
void main()
{
vec2 textureSize = vec2(viewportWidth, viewportHeight);
vec2 aoTexFactor = vec2(1.0) / textureSize / subSamplingFactor;
vec2 aoTexFactor = vec2(1.0) / osg_OutputBufferSize.xy / subSamplingFactor;
vec2 aoTexCoord = gl_FragCoord.xy * aoTexFactor;
vec2 texCoord0 = gl_TexCoord[0].st;
vec2 texCoord1 = gl_TexCoord[1].st;
Expand All @@ -330,14 +340,14 @@
float off = max(0.0, 1.0 - (artifactsRemoveCountPESSAO - 1.0) * 0.5)
* (0.25 + 0.75 * pow(1.0 - poiSSAO.z, 3.0));
ssao4.x = texture2D(aoTex, vec2((gl_FragCoord.x - off) / textureSize.x,
(gl_FragCoord.y + off) / textureSize.y) / subSamplingFactor).x;
ssao4.y = texture2D(aoTex, vec2((gl_FragCoord.x - off) / textureSize.x,
(gl_FragCoord.y - off) / textureSize.y) / subSamplingFactor).x;
ssao4.z = texture2D(aoTex, vec2((gl_FragCoord.x + off) / textureSize.x,
(gl_FragCoord.y - off) / textureSize.y) / subSamplingFactor).x;
ssao4.w = texture2D(aoTex, vec2((gl_FragCoord.x + off) / textureSize.x,
(gl_FragCoord.y + off) / textureSize.y) / subSamplingFactor).x;
ssao4.x = texture2D(aoTex, vec2((gl_FragCoord.x - off) / osg_OutputBufferSize.x,
(gl_FragCoord.y + off) / osg_OutputBufferSize.y) / subSamplingFactor).x;
ssao4.y = texture2D(aoTex, vec2((gl_FragCoord.x - off) / osg_OutputBufferSize.x,
(gl_FragCoord.y - off) / osg_OutputBufferSize.y) / subSamplingFactor).x;
ssao4.z = texture2D(aoTex, vec2((gl_FragCoord.x + off) / osg_OutputBufferSize.x,
(gl_FragCoord.y - off) / osg_OutputBufferSize.y) / subSamplingFactor).x;
ssao4.w = texture2D(aoTex, vec2((gl_FragCoord.x + off) / osg_OutputBufferSize.x,
(gl_FragCoord.y + off) / osg_OutputBufferSize.y) / subSamplingFactor).x;
ssao = sum4(ssao4) + 2.0 * ssao - max(ssao, max4(ssao4)) - min(ssao, min4(ssao4));
ssao *= 0.25;
Expand Down Expand Up @@ -399,17 +409,15 @@
</uniform>

<uniform name="contrastValue" type="float">
<value>16.0</value>
<value>10.0</value>
</uniform>

<uniform name="colorBlendFactor" type="float">
<value>1.0</value>
<value>0.5</value>
</uniform>

<uniform name="nearPlaneValue" type="float"><inbuilt_value>near_plane</inbuilt_value></uniform>
<uniform name="farPlaneValue" type="float"><inbuilt_value>far_plane</inbuilt_value></uniform>
<uniform name="viewportWidth" type="float"><inbuilt_value>viewport_width</inbuilt_value></uniform>
<uniform name="viewportHeight" type="float"><inbuilt_value>viewport_height</inbuilt_value></uniform>
<uniform name="eyePosition" type="vec3"><inbuilt_value>eye_position</inbuilt_value></uniform>
<uniform name="lookDirection" type="vec3"><inbuilt_value>look_vector</inbuilt_value></uniform>
<uniform name="leftDirection" type="vec3"><inbuilt_value>left_vector</inbuilt_value></uniform>
Expand Down Expand Up @@ -469,8 +477,6 @@
<uniform>farPlaneValue</uniform>
<uniform>leftDirection</uniform>
<uniform>upDirection</uniform>
<uniform>viewportWidth</uniform>
<uniform>viewportHeight</uniform>
<uniform>contrastValue</uniform>
<input_buffer unit="0" varname="depthTex">normalDepthScene</input_buffer>
<output_buffer target="color">aoScene</output_buffer>
Expand All @@ -479,8 +485,6 @@
</deferred_pass>

<deferred_pass name="SSAO_Combining">
<uniform>viewportWidth</uniform>
<uniform>viewportHeight</uniform>
<uniform>lightDirUniform</uniform>
<uniform>colorBlendFactor</uniform>
<input_buffer unit="0" varname="sceneTex">originalScene</input_buffer>
Expand Down
1 change: 1 addition & 0 deletions integrations/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ ADD_SUBDIRECTORY(osgsilverlining) # OSG & Sundog Silverlining
#ADD_SUBDIRECTORY(osgnewton) # OSG & Newton Physics
#ADD_SUBDIRECTORY(osgnurbs) # OSG & openNURBS
#ADD_SUBDIRECTORY(osgrecast) # OSG & Recastnavigation
#ADD_SUBDIRECTORY(osgdb_nanosvg) # OSG & NanoSVG

#ADD_SUBDIRECTORY(osganimata) # OSG & Animata
#ADD_SUBDIRECTORY(osgdance) # OSG & DANCE
Expand Down

0 comments on commit 70adf59

Please sign in to comment.