Iso-Contouring with Graphics Hardware
The pixel-based iso line algorithm is perfect for porting it as a pixel shader onto graphics hardware.
For this purpose we replace the standard vertex and pixel shader by two custom vertex and pixel shaders:
Vertex program that passes texture coordinates to the fragment program:
!!ARBvp1.0 OPTION ARB_position_invariant; MOV result.color,vertex.color; MOV result.texcoord[0],vertex.texcoord[0]; END
Fragment program that samples the texture coordinates and performs a thresholding operation on the distance to the iso line:
!!ARBfp1.0 PARAM isoval=program.env[0]; PARAM threshold=program.env[1]; TEMP val,col; TEX val,fragment.texcoord[0],texture[0],2D; SUB val.x,val.x,isoval.x; ABS val.x,val.x; SUB val.x,val.x,threshold.x; CMP col,val.x,1.0,0.25; MUL col,col,vertex.color; MOV result.color,col; END
With GLSL, a high level language compiler for vertex and pixel shaders, the above shader snippets become more readable:
GLSL vertex shader:
varying vec4 color;
varying vec2 texcoord;
void main()
{
// transforming the vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// writing varying color and texture coordinate
color = gl_Color;
texcoord = gl_MultiTexCoord0;
}
GLSL fragment shader:
uniform float isovalue, threshold;
varying vec4 color;
varying vec2 texcoord;
uniform sampler2D texture;
void main()
{
vec4 texcol;
// sample the texture
texcol = texture2D(texture, texcoord);
// calculate distance to iso value and threshold it
if (abs(texcol.x-isovalue) > threshold)
texcol *= vec4(0.25,0.25,0.25,1);
// modulate texture with per-vertex color
gl_FragColor = texcol * color;
}