Commit 8d63dadf authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[ADD] Now improved coupling from coronal slice (still present, but shader are...

[ADD] Now improved coupling from coronal slice (still present, but shader are almost independt. Also bounding box is now taken from probability data instead of WGEColormapper. Implemented threshold, where probabilities below are discarded. Fixed several typos as well as focal point computation which had a few bugs. Now everything should work again.
parent 2c19a937
......@@ -107,7 +107,7 @@ void WMFiberStipples::properties()
m_Pos->setMax( 0 );
m_Pos->setMin( 0 );
m_color = m_properties->addProperty( "Color", "Color for the fiber stipples", WColor( 1.0, 0.0, 0.0, 1.0 );
m_color = m_properties->addProperty( "Color", "Color for the fiber stipples", WColor( 1.0, 0.0, 0.0, 1.0 ) );
m_threshold = m_properties->addProperty( "Threshold", "Connectivity scores below this threshold will be discarded.", 0.01 );
m_threshold->setMin( 0.0 );
m_threshold->setMax( 1.0 );
......@@ -192,7 +192,7 @@ namespace {
}
}
void WMFiberStipples::initOSG()
void WMFiberStipples::initOSG( boost::shared_ptr< WDataSetScalar > probTract )
{
debugLog() << "Init OSG";
......@@ -208,7 +208,7 @@ void WMFiberStipples::initOSG()
}
// grab the current bounding box for computing the size of the slice
WBoundingBox bb = WGEColormapping::instance()->getBoundingBox();
WBoundingBox bb = probTract->getGrid()->getBoundingBox();
WVector3d minV = bb.getMin();
WVector3d maxV = bb.getMax();
WVector3d sizes = ( maxV - minV );
......@@ -236,6 +236,7 @@ void WMFiberStipples::initOSG()
osg::ref_ptr< osg::Uniform > u_WorldTransform = new osg::Uniform( "u_WorldTransform", osg::Matrix::identity() );
osg::ref_ptr< osg::Uniform > u_color = new WGEPropertyUniform< WPropColor >( "u_color", m_color );
osg::ref_ptr< osg::Uniform > u_threshold = new WGEPropertyUniform< WPropDouble >( "u_threshold", m_threshold );
osg::ref_ptr< osg::Uniform > u_maxConnectivityScore = new osg::Uniform( "u_maxConnectivityScore", static_cast< float >( probTract->getMax() ) );
osg::StateSet *states = slice->getOrCreateStateSet();
states->addUniform( u_aVec );
......@@ -243,6 +244,7 @@ void WMFiberStipples::initOSG()
states->addUniform( u_WorldTransform );
states->addUniform( u_color );
states->addUniform( u_threshold );
states->addUniform( u_maxConnectivityScore );
slice->setCullingActive( false );
// each slice is child of an transformation node
......@@ -251,7 +253,7 @@ void WMFiberStipples::initOSG()
// Control transformation node by properties. We use an additional uniform here to provide the shader
// the transformation matrix used to translate the slice.
mT->addUpdateCallback( new WGELinearTranslationCallback< WPropDouble >( osg::Vec3( 0.0, 1.0, 0.0 ), m_Pos, sliceUniform ) );
mT->addUpdateCallback( new WGELinearTranslationCallback< WPropDouble >( osg::Vec3( 0.0, 1.0, 0.0 ), m_Pos, u_WorldTransform ) );
m_output->getOrCreateStateSet()->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
m_output->getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON );
......@@ -271,7 +273,6 @@ void WMFiberStipples::moduleMain()
// graphics setup
m_output = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );
initOSG();
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_output );
osg::ref_ptr< WGEShader > shader = new WGEShader( "WFiberStipples", m_localPath );
shader->apply( m_output ); // this automatically applies the shader
......@@ -298,7 +299,7 @@ void WMFiberStipples::moduleMain()
continue;
}
initOSG();
initOSG( probTract );
wge::bindTexture( m_output, vectors->getTexture(), 0, "u_vectors" );
wge::bindTexture( m_output, probTract->getTexture(), 1, "u_probTract" );
......
......@@ -100,8 +100,12 @@ protected:
private:
/**
* Initialize OSG root node for this module. All other nodes from this module should be attached to this root node.
*
* \param probTract Pointer to dataset containing the connectivity scores or probabilities. We need this for two things:
* First, determine the maxium of connectivity scores to, scale the tracts between 0.0...1.0 and secondly to determine the
* boundingbox for the scene. (Furthermore it is assumed that the vectors are also available within this BB.)
*/
void initOSG();
void initOSG( boost::shared_ptr< WDataSetScalar > probTract );
/**
* The probabilistic tractogram input connector.
......@@ -123,8 +127,14 @@ private:
*/
WPropDouble m_Pos;
/**
* Color for the fiber stipples.
*/
WPropColor m_color;
/**
* Connectivity scores below that threshold will not be rendered.
*/
WPropDouble m_threshold;
/**
......
......@@ -24,24 +24,50 @@
#version 120
#include "WGETextureTools.glsl"
/**
* Color of the fiber stipples. This will be further combined with tract probability.
*/
uniform vec4 u_color;
/**
* First focal point, which is one of the endings of the projected diffusion direction.
*/
varying vec3 focalPoint1;
/**
* Second focal point, which is one of the endings of the projected diffusion direction.
*/
varying vec3 focalPoint2;
uniform sampler3D u_vectorsSampler;
uniform sampler3D u_probTractSampler;
/**
* First focal point, scaled.
*/
varying vec3 scaledFocalPoint1;
/**
* These two uniforms are needed to transform the vectors out of their texture back to their original form
* as they are stored in RBGA (for example allowing only values between 0..1 for components but no negative
* ones).
* Second focal point, scaled.
*/
uniform float u_vectorsMin;
uniform float u_vectorsScale;
varying vec3 scaledFocalPoint2;
varying vec4 diffusionDirection;
/**
* Middle point of the quad in texture coordinates, needed for scaling the projection of the principal diffusion direction to fit inside quad.
*/
uniform vec3 middlePoint_tex = vec3( 0.5, 0.5, 0.0 );
//uniform float u_glyphThickness;
//uniform float u_glyphSize;
/**
* Probability of the tract, used for further color mapping.
*/
varying float probability;
/**
* Computes the minimal distance from segment vw and point p.
*
* \param v start point of the segment
* \param w end point of the segment
* \param p point for which the minimal distance should be computed
*
* \return minimal distance from segment vw to point p.
*/
float minimum_distance( vec3 v, vec3 w, vec3 p )
{
// Return minimum distance between line segment vw and point p
......@@ -69,9 +95,6 @@ float minimum_distance( vec3 v, vec3 w, vec3 p )
void main()
{
// u_glyphSize controls the area each line stipple must use, radius is then derived from that.
float area = u_glyphSize * u_glyphSize / 10.0;
// generally the area of a line stipple is a circle with radius R (each half for the endings of the line stipple) plus
// a quad with height 2R and width length of the focalPoints v and w. hence we have this equation in R to solve:
//
......@@ -79,35 +102,21 @@ void main()
//
// where A is the area to fill.
focalPoint1 = 0.8 * focalPoint1;
focalPoint2 = 0.8 * focalPoint1;
float l = distance( focalPoint1, focalPoint2 );
float area = 0.1; // this is arbitrarily set
float l = distance( scaledFocalPoint1, scaledFocalPoint2 );
float p2 = -l / 3.14159265;
float q = area / 3.14159265;
float r1 = p2 + sqrt( p2 * p2 + q );
float r2 = p2 - sqrt( p2 * p2 + q );
float radius = max( r1, r2 );
// vec4 direction = abs( texture3DUnscaled( u_vectorsSampler, gl_TexCoord[0].xyz, u_vectorsMin, u_vectorsScale ) );
// vec4 probRGBA = texture3D( u_probTractSampler, gl_TexCoord[0].xyz );
// probRGBA.a = 1.0; // set alpha explicity to 1
// vec4 value = texture3D( u_probTractSampler, vec3(gl_TexCoord[0].x, gl_TexCoord[0].y, gl_TexCoord[0].z) );
// gl_FragColor = vec4( gl_TexCoord[0].xyz, 1.0 ); // vec4( value, 1.0, 0.0, 1.0 );
// gl_FragColor = vec4( value, 0.0, 0.0, 1.0 );
// gl_FragColor = vec4( texture3D( u_probTractSampler, pansen.xyz ).rgb, 1.0 );//vec4( 1.0, 0.0, 0.0, 1.0 );
gl_FragColor = vec4( gl_TexCoord[1].xyz, 1.0 );
// gl_FragColor = 0.8 * probRGBA + 0.2 * direction;
if( minimum_distance( focalPoint1, focalPoint2, gl_TexCoord[1].xyz ) < u_glyphThickness * radius )
if( minimum_distance( scaledFocalPoint1, scaledFocalPoint2, gl_TexCoord[1].xyz ) < radius )
{
gl_FragColor = gl_Color;
gl_FragColor = u_color * probability;
}
else
{
// if( minimum_distance( focalPoint1, focalPoint2, gl_TexCoord[0].xyz ) < u_glyphThickness * ( radius + 0.01 ) )
// if( minimum_distance( scaledFocalPoint1, scaledFocalPoint2, gl_TexCoord[1].xyz ) < ( radius + 0.01 ) )
// {
// gl_FragColor = vec4( 1.0, 1.0, 1.0, gl_Color.w );
// }
......@@ -115,58 +124,55 @@ void main()
discard;
// // Draw quad and inner cricle
//
// gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 );
// float lp = length( gl_TexCoord[0].xyz );
// if( lp >= ( u_glyphSize / 2.0 ) )
// float lp = distance( gl_TexCoord[1].xyz, middlePoint_tex );
// if( lp >= 0.5 )
// {
// gl_FragColor = vec4( 0.7, 0.7, 1.0, 1.0 ); // discard;
// }
}
// // display middle point
// if( length( gl_TexCoord[0].xyz ) <= 0.01 )
// {
// gl_FragColor = vec4( 1.0, 0.1, 0.1, 1.0 ); // discard;
// }
// // display evec end points
//
// if( ( distance( gl_TexCoord[0].xyz, gl_TexCoord[1].xyz ) < 0.01 ) )
// // Color debugging facilities
// if( minimum_distance( focalPoint1, focalPoint2, gl_TexCoord[1].xyz ) < 0.01 )
// {
// gl_FragColor = vec4( 1.0, 1.0, 0.0, 1.0 ); // yellow
// if( l <= 1.1 )
// {
// gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
// }
// else if( l < 1.225 )
// {
// gl_FragColor = vec4( 0.0, 1.0, 0.0, 1.0 );
// }
// else
// {
// gl_FragColor = vec4( 0.0, 0.0, 1.0, 1.0 );
// }
// }
// if( ( distance( gl_TexCoord[0].xyz, gl_TexCoord[2].xyz ) < 0.01 ) )
// // display middle point
// if( distance( gl_TexCoord[1].xyz, middlePoint_tex ) <= 0.01 )
// {
// gl_FragColor = vec4( 0.0, 1.0, 0.0, 1.0 ); // green
// }
// // display new focal points
//
// if( ( distance( gl_TexCoord[0].xyz, focalPoint1 ) < 0.01 ) )
// if( ( distance( gl_TexCoord[1].xyz, scaledFocalPoint1 ) < 0.01 ) )
// {
// gl_FragColor = vec4( 0.0, 1.0, 1.0, 1.0 ); // cyan
// }
// if( ( distance( gl_TexCoord[0].xyz, focalPoint2 ) < 0.01 ) )
// if( ( distance( gl_TexCoord[1].xyz, scaledFocalPoint2 ) < 0.01 ) )
// {
// gl_FragColor = vec4( 0.0, 0.0, 1.0, 1.0 ); // blue
// }
// // Color debugging facilities
// if( minimum_distance( gl_TexCoord[1].xyz, gl_TexCoord[2].xyz, gl_TexCoord[0].xyz ) < 0.01 )
// // display evec end points
// if( ( distance( gl_TexCoord[1].xyz, focalPoint1 ) < 0.01 ) )
// {
// if( l <= 1.1 )
// {
// gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
// }
// else if( l < 1.225 )
// {
// gl_FragColor = vec4( 0.0, 1.0, 0.0, 1.0 );
// }
// else
// {
// gl_FragColor = vec4( 0.0, 0.0, 1.0, 1.0 );
// }
// gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); // red
// }
// if( ( distance( gl_TexCoord[1].xyz, focalPoint2 ) < 0.01 ) )
// {
// gl_FragColor = vec4( 1.0, 1.0, 0.0, 1.0 ); // yellow
// }
}
......@@ -27,19 +27,25 @@
#include "WGETextureTools.glsl"
/**
* These two uniforms are needed to transform the vectors out of their texture back to their original form
* as they are stored in RBGA (for example allowing only values between 0..1 for components but no negative
* ones).
* These two uniforms are needed to transform the vectors out of their texture
* back to their original form as they are stored in RBGA (for example allowing
* only values between 0..1 for components but no negative ones).
*/
uniform float u_vectorsMin;
uniform float u_vectorsScale;
uniform float u_vectorsMin; uniform float u_vectorsScale;
/**
* The matrix describes the transformation of gl_Vertex to OpenWalnut Scene Space
*/
uniform mat4 u_WorldTransform;
/**
* Vector dataset as texture.
*/
uniform sampler3D u_vectorsSampler;
/**
* Probabilistic tract as texture.
*/
uniform sampler3D u_probTractSampler;
uniform int u_probTractSizeX;
......@@ -50,24 +56,73 @@ uniform int u_probTractSizeZ;
uniform vec3 u_aVec;
uniform vec3 u_bVec;
varying vec3 diffusionDirection;
/**
* First focal point, which is one of the endings of the projected diffusion direction.
*/
varying vec3 focalPoint1;
/**
* Second focal point, which is one of the endings of the projected diffusion direction.
*/
varying vec3 focalPoint2;
// Scaled focal points, as otherwise the the stipple endings may not fit inside quad.
/**
* Fixed factor for scaling.
*/
uniform float scale = 0.8;
/**
* First focal point, scaled.
*/
varying vec3 scaledFocalPoint1;
/**
* Second focal poin, scaled.
*/
varying vec3 scaledFocalPoint2;
/**
* Maximum connectivity score withing the probabilistic tract dataset. This is
* needed for scaling the connectivities between 0.0 and 1.0.
*/
uniform float u_maxConnectivityScore;
/**
* Scaled connectivity score; now between 0.0...1.0.
*/
varying float probability;
/**
* Probabilities below this threshold are ignored and discarded.
*/
uniform float u_threshold;
/**
* Middle point of the quad in texture coordinates, needed for scaling the
* projection of the principal diffusion direction to fit inside quad.
*/
uniform vec3 middlePoint_tex = vec3( 0.5, 0.5, 0.0 );
/**
* Vertex Main. Simply transforms the geometry. The work is done per fragment.
*/
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_MultiTexCoord1;
gl_TexCoord[0] = gl_MultiTexCoord0; // for distinguishing the verties of the quad
gl_TexCoord[1] = gl_MultiTexCoord1; // for coordinate system within fragment shader (enable unit quad coordinates)
// compute texture coordinates from worldspace coordinates for texture access
vec3 texturePosition = ( u_WorldTransform * gl_Vertex ).xyz;
texturePosition.x /= u_probTractSizeX;
texturePosition.y /= u_probTractSizeY;
texturePosition.z /= u_probTractSizeZ;
// compute texture coordinate
vec3 texturePosition = vec3( gl_Vertex.x / float(u_probTractSizeX), gl_Vertex.y / float(u_probTractSizeY), gl_Vertex.z / float(u_probTractSizeZ) );
// get connectivity score from probTract and with maximum value scale it between 0.0..1.0. from now on we call it probability
probability = texture3D( u_probTractSampler, texturePosition ).r / float( u_maxConnectivityScore );
// span quad incase of regions with high probablility
texturePosition.y = ( u_WorldTransform[3] / u_probTractSizeY ).y;
if( texture3D( u_probTractSampler, texturePosition ).r > 0.01 ) // rgb are the same
if( probability > u_threshold ) // rgb are the same
{
// transform position, the 4th component must be explicitly set, as otherwise they would have been scaled
gl_Position = gl_ModelViewProjectionMatrix * ( vec4( gl_TexCoord[0].xyz + gl_Vertex.xyz, 1.0 ) );
......@@ -78,14 +133,19 @@ void main()
}
// get principal diffusion direction
diffusionDirection = abs( texture3DUnscaled( u_vectorsSampler, texturePosition, u_vectorsMin, u_vectorsScale ) ).xyz;
vec3 diffusionDirection = abs( texture3DUnscaled( u_vectorsSampler, texturePosition, u_vectorsMin, u_vectorsScale ).xyz );
diffusionDirection = normalize( diffusionDirection );
// project into plane (given by two vectors aVec and bVec)
vec3 normal = normalize( cross( aVec, bVec ) );
vec3 normal = normalize( cross( u_aVec, u_bVec ) );
vec3 projectedDirection = diffusionDirection - dot( diffusionDirection, normal ) * normal;
vec3 middlePoint = vec3( 0.5, 0.5, 0.0 ); // in texture coordinates
focalPoint1 = middlePoint + projectedDirection;
focalPoint2 = middlePoint - projectedDirection;
vec3 projectedDirectionTextCoords = 0.5 * vec3( dot( normalize( u_aVec ), projectedDirection ),
dot( normalize( u_bVec ), projectedDirection ),
0.0 );
scaledFocalPoint1 = middlePoint_tex + scale * projectedDirectionTextCoords;
scaledFocalPoint2 = middlePoint_tex - scale * projectedDirectionTextCoords;
// but scale directions to fit 1x1 unit square, these 0.8 are just arbitrary choosen
focalPoint1 = middlePoint_tex + projectedDirectionTextCoords;
focalPoint2 = middlePoint_tex - projectedDirectionTextCoords;
}
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