next up previous contents index
Next: Volume Rendering Integral with Up: Vertex and Fragment Programs Previous: Clipped Tetrahedron Projection Vertex   Contents   Index


Fragment Program for Clipped Tetrahedron Projection

This listing is a fragment program that is part of the tetrahedra projection with adaptive transfer function sampling. Section 1.3 discusses the algorithm in its entirety.

The following program relies on the function IntegrateRay, which is not defined. Instead, subsequent sections provide various algorithms for IntegrateRay.

struct rayseg {
  float4 position       : POSITION;  /* Position of front face. */
  float4 distances      : TEXCOORD0; /* Distance of front face to each
                                        face in direction of view
					vector. */
  float3 isovalues      : TEXCOORD1; /* x and y are Color lookups for
                                        scalar values of where tetrahedra
                                        (ray segment) is clipped.  x value
                                        is closer to viewer.  z is the
                                        distance between the two isoplanes
                                        in the view direction. */
  float frontinterp     : TEXCOORD2; /* Interpolates the color of the
                                        front face from the front isovalue
					to the back. */
  float4 backinterp     : TEXCOORD3; /* Interpolates the color of each
                                        face from the back isovalue to the
                                        front. */
};

float4 IntegrateRay(in float4 BackColor, in float4 FrontColor,
                    in float Length);

float4 mainfrag(rayseg input,
                uniform sampler1D TransferFunction,
                uniform float LengthMultiply) : COLOR
{
  float4 mask;

  /* Make mask be 1 for all distances <= 0. */
  mask = (float4)(input.distances <= 0);

  /* Make all these entries larger so that we do not select them. */
  float4 tmp1 = input.distances + mask*1.0e38;

  float2 tmp2 = min(tmp1.xy, tmp1.zw);
  /* distance is actual distance from front to back of ray segment. */
  float distance = min(tmp2.x, tmp2.y);

  /* Make mask be 1 for minimum depth. */
  mask = (float4)(tmp1 == distance);

  float2 interpolants;
  interpolants.x = input.frontinterp;
  interpolants.y = dot(mask, input.backinterp);

  /* If either interpolation variable is greater than 1, the segment is
     completely outside the iso range. */
  discard (interpolants > 1);

  /* Remove any "empty space" from the distance. */
  distance -= dot(float2(1,1),
                  input.isovalues.z*max(-interpolants, float2(0,0)));

  float4 isocolorFront = tex1D(TransferFunction, input.isovalues.x);
  float4 isocolorBack = tex1D(TransferFunction, input.isovalues.y);

  /* If either distance is negative, it means that face is in between the
     two isosurfaces.  We have to interpolate the actual scalar value in
     this case.  It is the expected case that we have to interpolate at
     least one value. */
  interpolants = max(interpolants, float2(0,0));
  float4 colorFront =lerp(isocolorFront, isocolorBack, interpolants.xxxx);
  float4 colorBack = lerp(isocolorBack, isocolorFront, interpolants.yyyy);

  return IntegrateRay(colorBack, colorFront, distance*LengthMultiply);
}



Kenneth D Moreland 2004-07-16