📜 ⬆️ ⬇️

Isosurface rendering using reykasting algorithm

In this article I want to tell you about Isosurface rendering or rendering isosurfaces.

On duty, I always use the documentation only in English or German. Therefore, in the text I will often use the English word for all sorts of terms.

So, what is the Isosurface is, as Wikipedia tells us, a 3-dimensional variant of the contour, which in turn "represents a line, at each point of which the measured quantity retains the same value." In words, it may not be entirely clear - we’ll look at the pictures better.
')
imageimage

These images show surfaces with different values ​​of the “measured value” - density. The first value is less than the second.

To begin with a brief theory.

I do medical image processing. The data obtained from medical devices mainly contain the so-called raw or grayscale image - from 8 bits (256 shades) to 16 bits (65536 shades of gray). Since in fact 16 bits is a lot, an abbreviated version is often used - 12 bits, that is, a part from the high byte is used, this gives us 4,096 shades of gray.
Further, to convert a gray image into a color one, you can use the so-called LUT - look up table. This table is a set of rows, each of which contains an RGBA value. For 12 bits, this table contains 4096 rows. And when we encounter a voxel with a value of, for example, 542, we respectively take from the 542 rows of this table the RGBA values ​​specified there.
These tables are compiled by qualified doctors / engineers who know how to correlate the density value with the RGBA. Using the alpha channel, that is, transparency, allows you to create tables, the use of which will allow us to display only bones, or only veins, or arteries - the rest will be transparent. That is, changing the LUT on the fly, we get every time a new display of the same object.

The main way of rendering image data is Volume ray casting (something similar to Russian - Volumetric rendering ). I will not describe it in too much detail here. But understanding his work is important for us to understand the process of rendering isosurfaces.

The ray casting algorithm is that we penetrate our object with rays. The beam emanates from our eye (camera), passes through each point of the screen (each pixel), and intersects with our object in a specific voxel (if there is an intersection). The beam does not stop at this, but goes further, crossing further voxels and accumulating information from each point in a certain way. The criteria for stopping the beam can be several, the most common is when the accumulated value alpha is close to 1 (in practice, a value of a> 0.95 is used), or, for example, if we have moved beyond the boundaries of the image. That is, in fact, during the tracing we discard the transparent voxels and in a certain way we accumulate the translucent values ​​until we reach the whole object, which does not pass our beam further because of its opacity. The resulting value is used to draw on the screen.

Returning to the main theme, I want to say that the rendering of isosurfaces differs mainly in the breakpoint. In our case, as soon as we find a voxel with a value that is greater than or equal to the initially specified density value, we stop ray casting for the current beam and proceed to the next one. Since at all points the values ​​should be equal, all isosurfaces are usually drawn with the same color. One value - respectively one color.

This algorithm can be implemented on the CPU (and, in principle, the first implementations were just like that), but it will work very slowly. Everything is processed much faster on the GPU using the fragment shader ( GLSL ). The required parameters are transmitted from the outside - the limit value, color, speed of passage, etc. Below is the code for the simplest fragmentary shader that renders an isosurface. Since all previous or subsequent voxels are not important for an isosurface, here it is not the accumulation of values ​​that takes place, but just one color boundary value is used - isoColor.

  1. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  2. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  3. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  4. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  5. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  6. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  7. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  8. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  9. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  10. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  11. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  12. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  13. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  14. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  15. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  16. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  17. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  18. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  19. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  20. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  21. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  22. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  23. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  24. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  25. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  26. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  27. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  28. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  29. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  30. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  31. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  32. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  33. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  34. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  35. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  36. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  37. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  38. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  39. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }
  40. uniform sampler3D volume ; uniform float sampleRate ; uniform float isoValue ; uniform vec4 isoColor ; varying vec4 texCoord0 ; void main ( ) { floast steps = 1.0 / sampleRate ; vec4 outputColor = vec4 ( 0 ., 0 ., 0 ., 0 . ) ; float isoThr ; // get ray position and ray direction vec4 vPosition = gl_ModelViewMatrixInverse [ 3 ] ; vec3 rayPosition = texCoord0 . xyz ; vec3 vecDif = rayPosition - vPosition . xyz ; vec3 rayDirection = sampleRate * normalize ( vecDif ) ; // for all samples along the ray while ( steps ) { steps --; // get trilinear interpolated value from 3d texture float value = texture3D ( volume , rayPosition ) ; isoThr = value - isoValue ; // check if we get isosurface line if ( isoThr < 0 ) { // march to the next sample rayPosition = rayPosition + rayDirection ; // get next density continue ; } // else we do color transformation outputColor = isoColor ; outputColor . rgb = outputColor . rgb * outputColor . a ; #ifdef SHADER // do shading #endif break ; } gl_FragColor . rgba = outputColor ; }

______________________
The text was prepared in the Blog Editor from © SoftCoder.ru

One of the main parameters of ray casting is the trace step - how fast the beam passes through our object. If we render a cube of dimension X * Y * Z, then the ideal speed will be 1 / MAX (X, Y, Z). That is, the gain must be no more than 1 voxel in order to not miss anything. But on the other hand, often this level of detail is not needed, which also affects performance.

imageimage

In the presented pictures we see images rendered with different sampleRate. In the first case, the ideal 1 / MAX (X, Y, Z) was used - the image turned out smooth, without visible transitions, since we did not miss a single voxel, BUT! The FPS is only 13 frames per second.
For the second option, sampleRate was used twice as much - that is, we processed every second voxel, and at the same time, circles that are formed due to an error in the calculation of finding the first voxel of the isosurface are already visible. But FPS at the same time increased to 37 frames.
How to increase the speed of the algorithm and at the same time not to lose in quality, I will try to consider in the next article.

Source: https://habr.com/ru/post/123632/


All Articles