Commit 748b7fef authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[CHANGE] the LineAO can now switch between ND-gaussian-pyramid and unfiltered ND-map

parent 4c60ac16
......@@ -79,7 +79,12 @@ void WGEOffscreenRenderPass::attach( BufferComponent buffer, osg::ref_ptr< osg::
m_hud->addTexture( new WGETextureHud::WGETextureHudEntry( texture, m_name + " - " + getBufferName( buffer ) ) );
}
osg::Camera::attach( buffer, texture );
// allow mipmap generation, but set desired levels to 0. Allow the user to set this higher
texture->setUseHardwareMipMapGeneration( true );
texture->setNumMipmapLevels( 0 );
// attach
osg::Camera::attach( buffer, texture, 0, 0, true );
}
void WGEOffscreenRenderPass::attach( BufferComponent buffer, osg::ref_ptr< osg::Image > image )
......
......@@ -70,6 +70,12 @@ WGEPostprocessorLineAO::WGEPostprocessorLineAO( osg::ref_ptr< WGEOffscreenRender
lineaoDensityWeight->setMin( 0.001 );
lineaoDensityWeight->setMax( 2.0 );
WPropBool lineaoUseGaussedNDMap = m_properties->addProperty( "Use Gaussed ND-Map", "When enabling, the LineAO algorithm uses a scale-base "
"pyramid for sampling the depth and normal maps. Unlike "
"described in the paper, this is turned off by default to "
"ensure that details of far occluders are retained (the "
"images look crispier).", false );
// 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
// more crispy and more detailed at local scope.
......@@ -86,6 +92,11 @@ WGEPostprocessorLineAO::WGEPostprocessorLineAO( osg::ref_ptr< WGEOffscreenRender
new WGEShaderPropertyDefine< WPropInt >( "WGE_POSTPROCESSOR_LINEAO_SAMPLES", lineaoSamples ) )
);
s->addPreprocessor( WGEShaderPreprocessor::SPtr(
new WGEShaderPropertyDefineOptions< WPropBool >( lineaoUseGaussedNDMap, "WGE_POSTPROCESSOR_LINEAO_USEDIRECTNDMAP",
"WGE_POSTPROCESSOR_LINEAO_USEGAUSSPYRAMID" ) )
);
// create the LineAO rendering pass
osg::ref_ptr< WGEOffscreenTexturePass > lineAOPass = offscreen->addTextureProcessingPass( s, "LineAO" );
lineAOPass->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropDouble >( "u_lineaoDensityWeight", lineaoDensityWeight ) );
......@@ -95,7 +106,11 @@ WGEPostprocessorLineAO::WGEPostprocessorLineAO( osg::ref_ptr< WGEOffscreenRender
// attach color0 output
m_resultTextures.push_back( lineAOPass->attach( osg::Camera::COLOR_BUFFER0, GL_RGB ) );
// provide the Gbuffer input
// provide the Gbuffer input, with several mipmap levels
gbuffer.m_depthTexture->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
gbuffer.m_normalTexture->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
gbuffer.m_tangentTexture->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
size_t gBufUnitOffset = gbuffer.bind( lineAOPass );
// this effect needs some additional noise texture:
......
......@@ -25,7 +25,7 @@
#ifndef WGEPOSTPROCESSOR_FRAGMENT_GLSL
#define WGEPOSTPROCESSOR_FRAGMENT_GLSL
#version 120
#version 130
#include "WGEShadingTools.glsl"
#include "WGETextureTools.glsl"
......@@ -412,11 +412,19 @@ float getLineAO( vec2 where )
// Count the samples we really use.
numSamplesAdded++;
// use LOD based on current hemisphere?
float lod = 0.0;
#ifdef WGE_POSTPROCESSOR_LINEAO_USEGAUSSPYRAMID
// select the Level in the gaussian pyramid of the normal, depth and tangent map. When NOT using this, you retain more local detail
// at more far away occluders which creates crispier images.
lod = float( l );
#endif
// get the depth of the occluder fragment
occluderDepth = getDepth( hemispherePoint.xy );
occluderDepth = getDepth( hemispherePoint.xy, lod );
// get the normal of the occluder fragment
occluderNormal = getNormal( hemispherePoint.xy ).xyz;
occluderNormal = getNormal( hemispherePoint.xy, lod ).xyz;
// if depthDifference is negative = occluder is behind the current fragment -> occluding this fragment
depthDifference = currentPixelDepth - occluderDepth;
......@@ -425,7 +433,7 @@ float getLineAO( vec2 where )
float pointDiffuse = max( dot( hemisphereVector, normal ), 0.0 ); // this equals the diffuse term in Phong if lightDir is the
// occluder's surface
vec3 t = getTangent( hemispherePoint.xy ).xyz;
vec3 t = getTangent( hemispherePoint.xy, lod ).xyz;
vec3 newnorm = normalize( cross( normalize( cross( t, normalize( hemisphereVector ) ) ), t ) );
float occluderDiffuse = max( dot( newnorm, gl_LightSource[0].position.xyz ), 0.0 );
......
......@@ -25,7 +25,7 @@
#ifndef WGEPOSTPROCESSORUTILS_FRAGMENT_GLSL
#define WGEPOSTPROCESSORUTILS_FRAGMENT_GLSL
#version 120
#version 130
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Input-Texture Uniforms
......@@ -128,16 +128,37 @@ const vec2 zeroOneList = vec2( 1.0, 0.0 );
// * Get normal and depth at certain point
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Grabs and unscales the value inside the texture and returns it. Although this is implemented in WGETextureTools, we re-implement it
* for having mip-map support
*
* \param texture the texture unit to use
* \param point the texture coordinates
* \param minimum the minumum value of all values inside the texture
* \param scale the scaling value for all values inside the texture
* \param lod the LOD level if using mip-maps.
*
* \note The minimum and scale values are normally transferred to the shader using uniforms, as the CPU scales the textures
*
* \return the value at the given point
*/
vec4 texture2DUnscaledLOD( sampler2D texture, vec2 point, float minimum, float scale, float lod = 0.0 )
{
return ( scale * texture2DLod( texture, point, lod ) ) + vec4( minimum );
}
/**
* Returns the original unprocessed color value at the specified point
*
* \param where the pixel to grab
* \param lod the LOD level if using mip-maps.
*
* \return the color
*/
vec4 getColor( in vec2 where )
vec4 getColor( in vec2 where, in float lod = 0.0 )
{
return texture2D( u_colorSampler, where );
return texture2DLod( u_colorSampler, where, lod );
}
/**
......@@ -156,12 +177,13 @@ vec4 getColor()
* Grabs the normal at the specified point. The returned normal has been de-scaled to [-1,1] and normalized The w component is 1.
*
* \param where the pixel to grab
* \param lod the LOD level if using mip-maps.
*
* \return the normal
*/
vec4 getNormal( in vec2 where )
vec4 getNormal( in vec2 where, in float lod = 0.0 )
{
return normalize( texture2DUnscaled( u_normalSampler, where, -1.0, 2.0 ).xyz ).xyzz * zeroOneList.xxxy + zeroOneList.yyyx;
return normalize( texture2DUnscaledLOD( u_normalSampler, where, -1.0, 2.0, lod ).xyz ).xyzz * zeroOneList.xxxy + zeroOneList.yyyx;
}
/**
......@@ -180,12 +202,13 @@ vec4 getNormal()
* Grabs the normal at the specified point. The returned normal has been de-scaled to [-1,1] and normalized The w component is 1.
*
* \param where the pixel to grab
* \param lod the LOD level if using mip-maps.
*
* \return the normal
*/
vec4 getTangent( in vec2 where )
vec4 getTangent( in vec2 where, in float lod = 0.0 )
{
return normalize( texture2DUnscaled( u_tangentSampler, where, -1.0, 2.0 ).xyz ).xyzz * zeroOneList.xxxy + zeroOneList.yyyx;
return normalize( texture2DUnscaledLOD( u_tangentSampler, where, -1.0, 2.0, lod ).xyz ).xyzz * zeroOneList.xxxy + zeroOneList.yyyx;
}
/**
......@@ -204,12 +227,13 @@ vec4 getTangent()
* Grabs the depth at the specified point.
*
* \param where the position where to grab it.
* \param lod the LOD level if using mip-maps.
*
* \return the depth
*/
float getDepth( in vec2 where )
float getDepth( in vec2 where, in float lod = 0.0 )
{
return texture2D( u_depthSampler, where ).r;
return texture2DLod( u_depthSampler, where, lod ).r;
}
/**
......
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