Commit 02bd5e56 authored by Sebastian Eichelbaum's avatar 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, ...@@ -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 ) for( size_t i = 0; i < channels * sizeX * sizeY * sizeZ; ++i )
{ {
// - stylechecker says "use rand_r" but I am not sure about portability. // - 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; randomLuminance[ i ] = r;
} }
......
...@@ -43,12 +43,12 @@ ...@@ -43,12 +43,12 @@
#include "../../graphicsEngine/WGETextureUtils.h" #include "../../graphicsEngine/WGETextureUtils.h"
#include "../../graphicsEngine/callbacks/WGELinearTranslationCallback.h" #include "../../graphicsEngine/callbacks/WGELinearTranslationCallback.h"
#include "../../graphicsEngine/callbacks/WGENodeMaskCallback.h" #include "../../graphicsEngine/callbacks/WGENodeMaskCallback.h"
#include "../../graphicsEngine/callbacks/WGEShaderAnimationCallback.h"
#include "../../graphicsEngine/offscreen/WGEOffscreenRenderNode.h" #include "../../graphicsEngine/offscreen/WGEOffscreenRenderNode.h"
#include "../../graphicsEngine/offscreen/WGEOffscreenRenderPass.h" #include "../../graphicsEngine/offscreen/WGEOffscreenRenderPass.h"
#include "../../graphicsEngine/shaders/WGEPropertyUniform.h" #include "../../graphicsEngine/shaders/WGEPropertyUniform.h"
#include "../../graphicsEngine/shaders/WGEShader.h" #include "../../graphicsEngine/shaders/WGEShader.h"
#include "../../graphicsEngine/shaders/WGEShaderDefineOptions.h" #include "../../graphicsEngine/shaders/WGEShaderDefineOptions.h"
#include "../../graphicsEngine/shaders/WGEShaderPropertyDefineOptions.h"
#include "../../kernel/WKernel.h" #include "../../kernel/WKernel.h"
#include "WMImageSpaceLIC.h" #include "WMImageSpaceLIC.h"
...@@ -134,24 +134,32 @@ void WMImageSpaceLIC::properties() ...@@ -134,24 +134,32 @@ void WMImageSpaceLIC::properties()
m_licGroup = m_properties->addPropertyGroup( "LIC", "LIC 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_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_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_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 = m_licGroup->addProperty( "Ratio Colormap to LIC", "Blending ratio between LIC and colormap.", 0.5 );
m_cmapRatio->setMin( 0.0 ); m_cmapRatio->setMin( 0.0 );
m_cmapRatio->setMax( 1.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 // call WModule's initialization
WModule::properties(); WModule::properties();
} }
...@@ -247,6 +255,14 @@ void WMImageSpaceLIC::moduleMain() ...@@ -247,6 +255,14 @@ void WMImageSpaceLIC::moduleMain()
// finally, create a texture from the image // finally, create a texture from the image
osg::ref_ptr< osg::Texture2D > randTexture = wge::genWhiteNoiseTexture( resX, resX, 1 ); 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. // done.
ready(); ready();
...@@ -269,18 +285,23 @@ void WMImageSpaceLIC::moduleMain() ...@@ -269,18 +285,23 @@ void WMImageSpaceLIC::moduleMain()
osg::ref_ptr< WGEShader > transformationShader = new WGEShader( "WMImageSpaceLIC-Transformation", m_localPath ); osg::ref_ptr< WGEShader > transformationShader = new WGEShader( "WMImageSpaceLIC-Transformation", m_localPath );
WGEShaderDefineOptions::SPtr availableDataDefines = WGEShaderDefineOptions::SPtr( new WGEShaderDefineOptions( "SCALARDATA", "VECTORDATA" ) ); WGEShaderDefineOptions::SPtr availableDataDefines = WGEShaderDefineOptions::SPtr( new WGEShaderDefineOptions( "SCALARDATA", "VECTORDATA" ) );
transformationShader->addPreprocessor( availableDataDefines ); transformationShader->addPreprocessor( availableDataDefines );
transformationShader->addPreprocessor( define3dNoise );
osg::ref_ptr< WGEOffscreenRenderPass > transformation = offscreen->addGeometryRenderPass( osg::ref_ptr< WGEOffscreenRenderPass > transformation = offscreen->addGeometryRenderPass(
m_output, m_output,
transformationShader, transformationShader,
"Transformation" "Transformation"
); );
transformation->bind( rand3DTexture, 1 );
// apply colormapping to transformation // 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( osg::ref_ptr< WGEOffscreenRenderPass > edgeDetection = offscreen->addTextureProcessingPass(
new WGEShader( "WMImageSpaceLIC-Edge", m_localPath ), edgeShader,
"Edge Detection" "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 // 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). // 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() ...@@ -304,6 +325,8 @@ void WMImageSpaceLIC::moduleMain()
osg::ref_ptr< osg::Texture2D > transformationOut1 = transformation->attach( osg::Camera::COLOR_BUFFER0 ); 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 > transformationColormapped = transformation->attach( osg::Camera::COLOR_BUFFER1 );
osg::ref_ptr< osg::Texture2D > transformationDepth = transformation->attach( osg::Camera::DEPTH_BUFFER ); 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 // Edge Detection Pass, needs Depth as input
// * Edges in R // * Edges in R
...@@ -391,7 +414,6 @@ void WMImageSpaceLIC::moduleMain() ...@@ -391,7 +414,6 @@ void WMImageSpaceLIC::moduleMain()
initOSG( grid, mesh ); initOSG( grid, mesh );
// prepare offscreen render chain // prepare offscreen render chain
edgeDetection->bind( randTexture, 1 );
availableDataDefines->activateOption( 1 ); // vector input availableDataDefines->activateOption( 1 ); // vector input
transformation->bind( dataSetVec->getTexture2(), 0 ); transformation->bind( dataSetVec->getTexture2(), 0 );
} }
...@@ -407,7 +429,6 @@ void WMImageSpaceLIC::moduleMain() ...@@ -407,7 +429,6 @@ void WMImageSpaceLIC::moduleMain()
initOSG( grid, mesh ); initOSG( grid, mesh );
// prepare offscreen render chain // prepare offscreen render chain
edgeDetection->bind( randTexture, 1 );
availableDataDefines->activateOption( 0 ); // scalar input availableDataDefines->activateOption( 0 ); // scalar input
transformation->bind( dataSetScal->getTexture2(), 0 ); transformation->bind( dataSetScal->getTexture2(), 0 );
} }
......
...@@ -177,6 +177,21 @@ private: ...@@ -177,6 +177,21 @@ private:
WPropInt m_numIters; //!< the number of iterations done per frame WPropInt m_numIters; //!< the number of iterations done per frame
WPropDouble m_cmapRatio; //!< the ratio between colormap and LIC 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 #endif // WMIMAGESPACELIC_H
......
...@@ -55,12 +55,12 @@ uniform int u_texture0SizeZ; ...@@ -55,12 +55,12 @@ uniform int u_texture0SizeZ;
/** /**
* The blending ratio between noise and advected noise * The blending ratio between noise and advected noise
*/ */
uniform float u_noiseRatio; uniform float u_noiseRatio = 0.0;
/** /**
* Number of iterations per frame. * Number of iterations per frame.
*/ */
uniform int u_numIter; uniform int u_numIter = 30;
/** /**
* Returns the vector at the given point. * Returns the vector at the given point.
...@@ -74,6 +74,18 @@ vec2 getVec( in vec2 pos ) ...@@ -74,6 +74,18 @@ vec2 getVec( in vec2 pos )
return ( 2.0 * ( texture2D( u_texture0Sampler, pos ).rg - vec2( 0.5, 0.5 ) ) ); return ( 2.0 * ( texture2D( u_texture0Sampler, pos ).rg - vec2( 0.5, 0.5 ) ) );
} }
/**
* 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. * Main. Calculates the Laplace Filter for each pixel.
*/ */
...@@ -84,7 +96,7 @@ void main() ...@@ -84,7 +96,7 @@ void main()
// get some needed values // get some needed values
float edge = texture2D( u_texture1Sampler, texCoord ).r; float edge = texture2D( u_texture1Sampler, texCoord ).r;
float depth = texture2D( u_texture1Sampler, texCoord ).g; float depth = texture2D( u_texture1Sampler, texCoord ).g;
float noise = texture2D( u_texture1Sampler, texCoord ).b; float noise = getNoise( texCoord );
vec2 vec = getVec( texCoord ); vec2 vec = getVec( texCoord );
// simply iterate along the line using the vector at each point // simply iterate along the line using the vector at each point
...@@ -108,8 +120,8 @@ void main() ...@@ -108,8 +120,8 @@ void main()
// } // }
// it is also possible to scale using a Geometric progression: float( u_numIter - i ) / u_numIter * texture2D // it is also possible to scale using a Geometric progression: float( u_numIter - i ) / u_numIter * texture2D
sum += texture2D( u_texture1Sampler, newPos1 ).b; sum += getNoise( newPos1 );
sum += texture2D( u_texture1Sampler, newPos2 ).b; sum += getNoise( newPos2 );
lastPos1 = newPos1; lastPos1 = newPos1;
lastVec1 = newVec1; lastVec1 = newVec1;
......
...@@ -80,7 +80,11 @@ void main() ...@@ -80,7 +80,11 @@ void main()
vec4 br = texture2D( u_texture0Sampler, texCoord + vec2( offsetW, offsetH ) ); vec4 br = texture2D( u_texture0Sampler, texCoord + vec2( offsetW, offsetH ) );
vec4 b = texture2D( u_texture0Sampler, texCoord + vec2( 0.0, -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; float noise = texture2D( u_texture1Sampler, texCoord ).r;
#endif
float light = texture2D( u_texture2Sampler, texCoord ).b; float light = texture2D( u_texture2Sampler, texCoord ).b;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
......
...@@ -40,6 +40,11 @@ ...@@ -40,6 +40,11 @@
*/ */
uniform sampler3D u_texture0Sampler; uniform sampler3D u_texture0Sampler;
/**
* The texture unit sampler for the 3D noise texture
*/
uniform sampler3D u_texture1Sampler;
/** /**
* Scaling factor to unscale the texture * Scaling factor to unscale the texture
*/ */
...@@ -65,6 +70,13 @@ uniform int u_texture0SizeY = 255; ...@@ -65,6 +70,13 @@ uniform int u_texture0SizeY = 255;
*/ */
uniform int u_texture0SizeZ = 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. * Transforms each vector on each pixel to image space.
*/ */
...@@ -72,6 +84,13 @@ void main() ...@@ -72,6 +84,13 @@ void main()
{ {
vec3 vecProjected; // contains the final vector at each fragment 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 #ifdef VECTORDATA
// get the current vector at this position // get the current vector at this position
vec3 vec = texture3DUnscaled( u_texture0Sampler, gl_TexCoord[0].xyz, u_texture0Min, u_texture0Scale ).rgb; vec3 vec = texture3DUnscaled( u_texture0Sampler, gl_TexCoord[0].xyz, u_texture0Min, u_texture0Scale ).rgb;
...@@ -129,7 +148,7 @@ void main() ...@@ -129,7 +148,7 @@ void main()
// is the vector very orthogonal to the surface? // is the vector very orthogonal to the surface?
vec2 dotScaled = ( 1.0 - dot( v_normal.xyz, vec.xyz ) ) * scaleMaxToOne( vecProjected ).xy; 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(); 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