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; }