Commit 02bd5e56 by Sebastian Eichelbaum

[ADD] - imageSpaceLIC is now able to use 3D noise textures. With these, the…

[ADD] - imageSpaceLIC is now able to use 3D noise textures. With these, the noise looks more coherent during transformation.
parent 007eaa62
......@@ -107,7 +107,7 @@ osg::ref_ptr< osg::Image > wge::genWhiteNoiseImage( size_t sizeX, size_t sizeY,
for( size_t i = 0; i < channels * sizeX * sizeY * sizeZ; ++i )
{
// - stylechecker says "use rand_r" but I am not sure about portability.
unsigned char r = ( unsigned char )( std::rand() % 255 ); // NOLINT
unsigned char r = static_cast< unsigned char >( std::rand() % 255 ); // NOLINT
randomLuminance[ i ] = r;
}
......
......@@ -43,12 +43,12 @@
#include "../../graphicsEngine/WGETextureUtils.h"
#include "../../graphicsEngine/callbacks/WGELinearTranslationCallback.h"
#include "../../graphicsEngine/callbacks/WGENodeMaskCallback.h"
#include "../../graphicsEngine/callbacks/WGEShaderAnimationCallback.h"
#include "../../graphicsEngine/offscreen/WGEOffscreenRenderNode.h"
#include "../../graphicsEngine/offscreen/WGEOffscreenRenderPass.h"
#include "../../graphicsEngine/shaders/WGEPropertyUniform.h"
#include "../../graphicsEngine/shaders/WGEShader.h"
#include "../../graphicsEngine/shaders/WGEShaderDefineOptions.h"
#include "../../graphicsEngine/shaders/WGEShaderPropertyDefineOptions.h"
#include "../../kernel/WKernel.h"
#include "WMImageSpaceLIC.h"
......@@ -134,24 +134,32 @@ void WMImageSpaceLIC::properties()
m_licGroup = m_properties->addPropertyGroup( "LIC", "LIC properties." );
// show hud?
m_showHUD = m_licGroup->addProperty( "Show HUD", "Check to enable the debugging texture HUD.", false );
m_useLight = m_licGroup->addProperty( "Use Light", "Check to enable lightning using the Phong model.", false );
m_useEdges = m_licGroup->addProperty( "Edges", "Check to enable blending in edges.", true );
m_useDepthCueing = m_licGroup->addProperty( "Depth Cueing", "Use depth as additional cue? Blends in the depth. Mostly useful for isosurfaces.",
false );
m_useHighContrast = m_licGroup->addProperty( "High Contrast", "Use an extremely increased contrast.", false );
m_numIters = m_licGroup->addProperty( "Number of Iterations", "How much iterations along a streamline should be done per frame.", 30 );
m_numIters->setMin( 1 );
m_numIters->setMax( 100 );
m_cmapRatio = m_licGroup->addProperty( "Ratio Colormap to LIC", "Blending ratio between LIC and colormap.", 0.5 );
m_cmapRatio->setMin( 0.0 );
m_cmapRatio->setMax( 1.0 );
m_advancedLicGroup = m_properties->addPropertyGroup( "Advanced", "More advanced LIC properties." );
// show hud?
m_showHUD = m_advancedLicGroup->addProperty( "Show HUD", "Check to enable the debugging texture HUD.", false );
m_useDepthCueing = m_advancedLicGroup->addProperty( "Depth Cueing", "Use depth as additional cue? Mostly useful for isosurfaces.",
false );
m_3dNoise = m_advancedLicGroup->addProperty( "Use 3D noise", "Use 3D noise? This provides better coherence during transformation of "
"the geometry but might introduce resolution problems.", false );
m_3dNoiseRes = m_advancedLicGroup->addProperty( "3D Noise Resolution", "The 3D noise is of 128^3 pixels size. This scaler allows "
"modification of this size.", 4.0 );
m_3dNoiseRes->setMin( 1 );
m_3dNoiseRes->setMax( 10 );
m_numIters = m_advancedLicGroup->addProperty( "Number of Iterations", "How much iterations along a streamline should be done per frame.",
30 );
m_numIters->setMin( 1 );
m_numIters->setMax( 100 );
// call WModule's initialization
WModule::properties();
}
......@@ -247,6 +255,14 @@ void WMImageSpaceLIC::moduleMain()
// finally, create a texture from the image
osg::ref_ptr< osg::Texture2D > randTexture = wge::genWhiteNoiseTexture( resX, resX, 1 );
// create a 3D texture too. This allows transformation-invariant noise but is prone to flickering artifacts due to down/upscaling
osg::ref_ptr< osg::Texture3D > rand3DTexture = wge::genWhiteNoiseTexture( 128, 128, 128, 1 );
rand3DTexture->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
rand3DTexture->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
rand3DTexture->setWrap( osg::Texture::WRAP_R, osg::Texture::REPEAT );
WGEShaderPreprocessor::SPtr define3dNoise( new WGEShaderPropertyDefineOptions< WPropBool >( m_3dNoise, "NOISE3D_DISABLED", "NOISE3D_ENABLED" ) );
// done.
ready();
......@@ -269,18 +285,23 @@ void WMImageSpaceLIC::moduleMain()
osg::ref_ptr< WGEShader > transformationShader = new WGEShader( "WMImageSpaceLIC-Transformation", m_localPath );
WGEShaderDefineOptions::SPtr availableDataDefines = WGEShaderDefineOptions::SPtr( new WGEShaderDefineOptions( "SCALARDATA", "VECTORDATA" ) );
transformationShader->addPreprocessor( availableDataDefines );
transformationShader->addPreprocessor( define3dNoise );
osg::ref_ptr< WGEOffscreenRenderPass > transformation = offscreen->addGeometryRenderPass(
m_output,
transformationShader,
"Transformation"
);
transformation->bind( rand3DTexture, 1 );
// apply colormapping to transformation
WGEColormapping::apply( transformation, transformationShader, 1 );
WGEColormapping::apply( transformation, transformationShader, 2 );
osg::ref_ptr< WGEShader > edgeShader = new WGEShader( "WMImageSpaceLIC-Edge", m_localPath );
osg::ref_ptr< WGEOffscreenRenderPass > edgeDetection = offscreen->addTextureProcessingPass(
new WGEShader( "WMImageSpaceLIC-Edge", m_localPath ),
edgeShader,
"Edge Detection"
);
edgeShader->addPreprocessor( define3dNoise );
// we use two advection passes per frame as the input A of the first produces the output B whereas the second pass uses B as input and
// produces A as output. This way we can use A as input for the next step (clipping and blending).
......@@ -304,6 +325,8 @@ void WMImageSpaceLIC::moduleMain()
osg::ref_ptr< osg::Texture2D > transformationOut1 = transformation->attach( osg::Camera::COLOR_BUFFER0 );
osg::ref_ptr< osg::Texture2D > transformationColormapped = transformation->attach( osg::Camera::COLOR_BUFFER1 );
osg::ref_ptr< osg::Texture2D > transformationDepth = transformation->attach( osg::Camera::DEPTH_BUFFER );
// and some uniforms
transformation->addUniform( new WGEPropertyUniform< WPropDouble >( "u_noise3DResoultuion", m_3dNoiseRes ) );
// Edge Detection Pass, needs Depth as input
// * Edges in R
......@@ -391,7 +414,6 @@ void WMImageSpaceLIC::moduleMain()
initOSG( grid, mesh );
// prepare offscreen render chain
edgeDetection->bind( randTexture, 1 );
availableDataDefines->activateOption( 1 ); // vector input
transformation->bind( dataSetVec->getTexture2(), 0 );
}
......@@ -407,7 +429,6 @@ void WMImageSpaceLIC::moduleMain()
initOSG( grid, mesh );
// prepare offscreen render chain
edgeDetection->bind( randTexture, 1 );
availableDataDefines->activateOption( 0 ); // scalar input
transformation->bind( dataSetScal->getTexture2(), 0 );
}
......
......@@ -177,6 +177,21 @@ private:
WPropInt m_numIters; //!< the number of iterations done per frame
WPropDouble m_cmapRatio; //!< the ratio between colormap and LIC
/**
* The group for more advanced LIC features
*/
WPropGroup m_advancedLicGroup;
/**
* If true, a 3d noise texture is used for advection
*/
WPropBool m_3dNoise;
/**
* The resolution scaling for the 3d noise
*/
WPropDouble m_3dNoiseRes;
};
#endif // WMIMAGESPACELIC_H
......
......@@ -55,12 +55,12 @@ uniform int u_texture0SizeZ;
/**
* The blending ratio between noise and advected noise
*/
uniform float u_noiseRatio;
uniform float u_noiseRatio = 0.0;
/**
* Number of iterations per frame.
*/
uniform int u_numIter;
uniform int u_numIter = 30;
/**
* Returns the vector at the given point.
......@@ -75,6 +75,18 @@ vec2 getVec( in vec2 pos )
}
/**
* Returns noise for the given position.
*
* \param pos the position
*
* \return noise
*/
float getNoise( in vec2 pos )
{
return texture2D( u_texture1Sampler, pos ).b;
}
/**
* Main. Calculates the Laplace Filter for each pixel.
*/
void main()
......@@ -84,7 +96,7 @@ void main()
// get some needed values
float edge = texture2D( u_texture1Sampler, texCoord ).r;
float depth = texture2D( u_texture1Sampler, texCoord ).g;
float noise = texture2D( u_texture1Sampler, texCoord ).b;
float noise = getNoise( texCoord );
vec2 vec = getVec( texCoord );
// simply iterate along the line using the vector at each point
......@@ -108,8 +120,8 @@ void main()
// }
// it is also possible to scale using a Geometric progression: float( u_numIter - i ) / u_numIter * texture2D
sum += texture2D( u_texture1Sampler, newPos1 ).b;
sum += texture2D( u_texture1Sampler, newPos2 ).b;
sum += getNoise( newPos1 );
sum += getNoise( newPos2 );
lastPos1 = newPos1;
lastVec1 = newVec1;
......
......@@ -80,7 +80,11 @@ void main()
vec4 br = texture2D( u_texture0Sampler, texCoord + vec2( offsetW, offsetH ) );
vec4 b = texture2D( u_texture0Sampler, texCoord + vec2( 0.0, -offsetH ) );
#ifdef NOISE3D_ENABLED
float noise = texture2D( u_texture2Sampler, texCoord ).a;
#else
float noise = texture2D( u_texture1Sampler, texCoord ).r;
#endif
float light = texture2D( u_texture2Sampler, texCoord ).b;
/////////////////////////////////////////////////////////////////////////////////////////////
......
......@@ -41,6 +41,11 @@
uniform sampler3D u_texture0Sampler;
/**
* The texture unit sampler for the 3D noise texture
*/
uniform sampler3D u_texture1Sampler;
/**
* Scaling factor to unscale the texture
*/
uniform float u_texture0Scale = 1.0;
......@@ -65,6 +70,13 @@ uniform int u_texture0SizeY = 255;
*/
uniform int u_texture0SizeZ = 255;
#ifdef NOISE3D_ENABLED
/**
* The "virtual" resolution of the 3D noise texture in u_texture1Sampler
*/
uniform float u_noise3DResoultuion = 4.0;
#endif
/**
* Transforms each vector on each pixel to image space.
*/
......@@ -72,6 +84,13 @@ void main()
{
vec3 vecProjected; // contains the final vector at each fragment
// if we have a 3D noise texture, use it.
#ifdef NOISE3D_ENABLED
float noise3D = texture3D( u_texture1Sampler, gl_TexCoord[0].xyz * u_noise3DResoultuion ).r;
#else
float noise3D = 1.0;
#endif
#ifdef VECTORDATA
// get the current vector at this position
vec3 vec = texture3DUnscaled( u_texture0Sampler, gl_TexCoord[0].xyz, u_texture0Min, u_texture0Scale ).rgb;
......@@ -129,7 +148,7 @@ void main()
// is the vector very orthogonal to the surface?
vec2 dotScaled = ( 1.0 - dot( v_normal.xyz, vec.xyz ) ) * scaleMaxToOne( vecProjected ).xy;
gl_FragData[0] = vec4( vec2( 0.5 ) + ( 0.5 * dotScaled ), light, 1.0 );
gl_FragData[0] = vec4( vec2( 0.5 ) + ( 0.5 * dotScaled ), light, noise3D );
gl_FragData[1] = colormapping();
}
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