00001 !!ARBfp1.0
00002 OPTION NV_fragment_program2;
00003
00004 # Copyright (c) 2005 Institute for Visualization and Interactive
00005 # Systems, University of Stuttgart, Germany
00006 #
00007 # This source code is distributed as part of the single-pass volume
00008 # rendering project. Details about this project can be found on the
00009 # project web page at http://www.vis.uni-stuttgart.de/eng/research/
00010 # fields/current/spvolren. This file may be distributed, modified,
00011 # and used free of charge as long as this copyright notice is
00012 # included in its original form. Commercial use is strictly
00013 # prohibited.
00014 #
00015 # Filename: isosurface_sm3.fp
00016
00017 #! VOLUME = 0
00018 #! TRANSFERFUNCTION = 1
00019 #! BACKGROUND = 2
00020
00021 # r = step
00022 # g = gradient scale
00023 # b = gradient offset
00024 # a = z-value of background plane
00025 PARAM params = program.local[0];
00026
00027 # r = texture coordinate scale
00028 # g = number of iterations
00029 # b = isovalue of isosurface
00030 PARAM params2 = program.local[1];
00031 PARAM center = program.local[2];
00032 PARAM texMax = program.local[3];
00033
00034 PARAM scaleFactors = program.local[5];
00035
00036 TEMP geomDir;
00037 TEMP geomPos;
00038 TEMP lightVec;
00039 TEMP texCoord;
00040 TEMP prevPos;
00041 TEMP texblen;
00042 TEMP diffVec;
00043 TEMP halfway;
00044 TEMP eyeVec;
00045 TEMP intens;
00046 TEMP camera;
00047 TEMP normal;
00048 TEMP weight;
00049 TEMP temp1;
00050 TEMP temp2;
00051 TEMP temp;
00052 TEMP grad;
00053 #TEMP sign;
00054 TEMP pos;
00055 TEMP src;
00056 TEMP dst;
00057 TEMP dir;
00058 TEMP tex;
00059 TEMP scalAct;
00060 TEMP scalPre;
00061
00062 # Compute the ray's starting point
00063 MOV geomPos, fragment.texcoord[0];
00064 MUL pos, geomPos, scaleFactors;
00065 MOV pos.a, 0.0;
00066
00067 # Compute the camera position by translating the origin to the center of the
00068 # volume
00069 MOV camera, state.matrix.modelview.invtrans.row[3];
00070
00071 # Compute the ray direction
00072 SUB geomDir, geomPos, camera;
00073
00074 # Normalize the direction
00075 DP3 geomDir.w, geomDir, geomDir;
00076 RSQ geomDir.w, geomDir.w;
00077 MUL geomDir, geomDir, geomDir.w;
00078 MOV geomDir.w, 0.0;
00079
00080 MUL dir, geomDir, scaleFactors;
00081
00082 # Initialize the 'previous' intensity
00083 TXL intens, pos, texture[0], 3D;
00084 MOV intens.g, intens.a;
00085
00086 # Initialize texture corrdinates
00087 # texcood.a inherits level of detail
00088 MOV texCoord, 0.0;
00089
00090 # Initialize destination color
00091 MOV dst, 0.0;
00092
00093 REP params2.g;
00094
00095 REP params2.g;
00096 # Lookup scalar and gradient
00097 TXL tex, pos, texture[0], 3D;
00098 MOV intens.r, tex.a;
00099
00100 # Isosurface if differences with past and present
00101 # scalar values and isovalue have different signs
00102 SUB temp.rg, intens, params2.b;
00103 MULC temp, temp.r, temp.g;
00104 IF LE.x;
00105 # Isosurface found
00106
00107 # Get scalar value from actual position
00108 TXL scalAct, pos, texture[0], 3D;
00109
00110 # Get scalar value from previous position
00111 MAD prevPos, -dir, params.r, pos;
00112 TXL scalPre, prevPos, texture[0], 3D;
00113
00114 SUB temp.r, params2.b, scalPre.a;
00115 SUB temp.g, scalAct.a, scalPre.a;
00116
00117 # Perform linear interpolation to increase accuracy
00118 DIV_SAT temp.b, temp.r, temp.g;
00119 LRP pos, temp.b, pos, prevPos;
00120
00121 # Determine gradient at corrected position (same as above)
00122 TXL tex, pos, texture[0], 3D;
00123 MOV grad.rgb, tex;
00124
00125 # Determine scale factor for gradient
00126 SNE temp.rgb, grad, 0.0;
00127 DP3_SAT temp.r, temp, 1.0;
00128
00129 # Reconstruct the gradient
00130 MAD_SSAT grad.rgb, tex, 2.0, -1.0;
00131 NRM_SSAT grad.rgb, grad;
00132
00133 # Set gradient to zero if it was zero
00134 MUL grad.rgb, grad, temp.r;
00135
00136 # Re-orient the gradient to get a
00137 # correct surface normal
00138 MOV temp, 0.0;
00139 DP3 temp.r, -geomDir, grad;
00140 NRM temp, temp;
00141 MUL grad.rgb, grad, temp.r;
00142
00143 # Perform the lighting calculation (yes, we know LIT!)
00144
00145 # Look up the color based on the isovalue
00146 MOV texCoord.rgb, params2.b;
00147 TXL src, texCoord, texture[1], 2D;
00148 # 'Normalize' color
00149 NRM src, src;
00150
00151 # Ambient term
00152 MUL dst, state.light[0].ambient, src;
00153
00154 # Transform isosurface intersection to object space
00155 DIV temp.x, pos.x, scaleFactors.x;
00156 DIV temp.y, pos.y, scaleFactors.y;
00157 DIV temp.z, pos.z, scaleFactors.z;
00158
00159 # Diffuse term
00160 SUB lightVec.rgb, state.light[0].position, temp;
00161 MOV lightVec.a, 0.0;
00162 NRM lightVec, lightVec;
00163 DP3_SAT temp.a, lightVec, grad;
00164 MUL temp, src, temp.a;
00165 MAD dst, state.light[0].diffuse, temp, dst;
00166
00167 # Specular term
00168 # First calculate halfway vector
00169 ADD halfway, lightVec, -geomDir;
00170 MOV halfway.a, 0.0;
00171 NRM halfway, halfway;
00172 # Specular Lighting
00173 SUB eyeVec.rgb, camera, geomPos;
00174 MOV eyeVec.a, 0.0;
00175 NRM eyeVec, eyeVec;
00176 DP3_SAT temp.a, halfway, grad;
00177 POW temp.a, temp.a, 10.0;
00178 MUL eyeVec, src, state.light[0].specular;
00179 MAD dst, eyeVec, temp.a, dst;
00180 # Isosurfaces are opaque
00181 MOV dst.a, 1.0;
00182
00183 # Everything is done, jump out of loop
00184 MOVC temp.x, 0.0;
00185 BRK (EQ.x);
00186 ENDIF;
00187
00188 # Move one step forward
00189 MAD pos, dir, params.r, pos;
00190
00191 # Set values to zero if outside volume
00192 SGE temp1, pos, 0.0;
00193 SLE temp2, pos, texMax;
00194 DP3 weight.r, temp1, temp2;
00195 SEQC weight.r, weight.r, 3.0;
00196
00197 # Already outside volume, skip the rest
00198 BRK (EQ.x);
00199
00200 # Update old scalar value
00201 MOV intens.g, intens.r;
00202 ENDREP;
00203
00204 BRK (EQ.x);
00205
00206 ENDREP;
00207
00208 # Compute the normal of the background plane (this is just the negative view
00209 # direction which initially is (0, 0, -1))
00210 MOV normal, state.matrix.modelview.row[2];
00211
00212 # Compute the plane constant (we want the plane to be located in the volume
00213 # center)
00214 DP3 temp1.r, normal, center;
00215
00216 # Move the plane behind the volume: d' = <n,(x - l n)> = <n, x> - l <n, n>;
00217 # l = 0.71 is chosen since it is greater than half the cube diagonal
00218 DP3 temp1.g, normal, normal;
00219 MAD temp1.r, temp1.g, -.71, temp1.r;
00220
00221 # Compute ray parameter
00222 DP3 temp1.g, normal, geomPos;
00223 SUB temp1.g, temp1.r, temp1.g;
00224 DP3 temp1.b, normal, geomDir;
00225 DIV temp.r, temp1.g, temp1.b;
00226
00227 # Compute ray/plane intersection
00228 MAD temp.rgb, temp.r, geomDir, geomPos;
00229
00230 # Compute the difference vector
00231 SUB diffVec, temp, center;
00232
00233 # Compute the texture coordinates
00234 DP3 temp.r, diffVec, state.matrix.modelview.row[0];
00235 DP3 temp.g, diffVec, state.matrix.modelview.row[1];
00236 MUL temp.rg, temp, params2.r;
00237
00238 # Center background image
00239 ADD temp.rg, temp, .5;
00240
00241 # Look up the texel value
00242 TEX temp.rgb, temp, texture[2], 2D;
00243 MOV temp.a, 1.0;
00244
00245 # Blend the background pixel
00246 SUB texblen, 1.0, dst.a;
00247 MAD dst, temp, texblen.x, dst;
00248
00249 # Write the output color
00250 MOV result.color, dst;
00251
00252 END