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_shadowed_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 specular;
00039 TEMP lightVec;
00040 TEMP texCoord;
00041 TEMP ambient;
00042 TEMP diffuse;
00043 TEMP prevPos;
00044 TEMP texblen;
00045 TEMP diffVec;
00046 TEMP halfway;
00047 TEMP shadow;
00048 TEMP eyeVec;
00049 TEMP intens;
00050 TEMP camera;
00051 TEMP normal;
00052 TEMP weight;
00053 TEMP temp1;
00054 TEMP temp2;
00055 TEMP temp;
00056 TEMP grad;
00057 TEMP sign;
00058 TEMP pos2;
00059 TEMP pos;
00060 TEMP src;
00061 TEMP dst;
00062 TEMP dir;
00063 TEMP tex;
00064 TEMP scalAct;
00065 TEMP scalPre;
00066
00067 # Compute the ray's starting point
00068 MOV geomPos, fragment.texcoord[0];
00069 MUL pos, geomPos, scaleFactors;
00070 MOV pos.a, 0.0;
00071
00072 # Compute the camera position by translating the origin to the center of the
00073 # volume
00074 MOV camera, state.matrix.modelview.invtrans.row[3];
00075
00076 # Compute the ray direction
00077 SUB geomDir, geomPos, camera;
00078
00079 # Normalize the direction
00080 DP3 geomDir.w, geomDir, geomDir;
00081 RSQ geomDir.w, geomDir.w;
00082 MUL geomDir, geomDir, geomDir.w;
00083 MOV geomDir.w, 0.0;
00084
00085 MUL dir, geomDir, scaleFactors;
00086
00087 # Initialize the 'previous' intensity
00088 TXL intens, pos, texture[0], 3D;
00089 MOV intens.g, intens.a;
00090
00091 # Initialize texture corrdinates
00092 # texcood.a inherits level of detail
00093 MOV texCoord, 0.0;
00094
00095 # Initialize destination color
00096 MOV dst, 0.0;
00097
00098 REP params2.g;
00099 REP params2.g;
00100 # Lookup scalar and gradient
00101 MOV texCoord.rgb, pos;
00102 TXL tex, texCoord, texture[0], 3D;
00103
00104 # Component 'b' written to circumvent driver bug
00105 MOV intens.rb, tex.a;
00106
00107 # Move one step forward
00108 MAD pos, dir, params.r, pos;
00109
00110 # Look up the color based on the isovalue
00111 MOV texCoord.rgb, params2.b;
00112 TXL src, texCoord, texture[1], 2D;
00113 # 'Normalize' color
00114 MOV src.a, 0.0;
00115 NRM src, src;
00116
00117 # We assume that isosurfaces are opaque
00118 MOV src.a, 1.0;
00119
00120 # Isosurface if differences with past and present
00121 # scalar values and isovalue have different signs
00122 SUB temp.rg, intens, params2.b;
00123 MULC temp, temp.r, temp.g;
00124 IF LE.x;
00125 # Isosurface found
00126
00127
00128 # Get scalar value from actual position
00129 MAD pos, -dir, params.r, pos;
00130 TXL scalAct, pos, texture[0], 3D;
00131
00132 # Get scalar value from previous position
00133 MAD prevPos, -dir, params.r, pos;
00134 TXL scalPre, prevPos, texture[0], 3D;
00135
00136 SUB temp.r, params2.b, scalPre.a;
00137 SUB temp.g, scalAct.a, scalPre.a;
00138
00139 # Perform linear interpolation to increase accuracy
00140 DIV_SAT temp.b, temp.r, temp.g;
00141 LRP pos, temp.b, pos, prevPos;
00142
00143 # Determine gradient at corrected position (same as above)
00144 TEX grad.rgb, pos, texture[0], 3D;
00145
00146 # Determine scale factor for gradient
00147 SNE temp.rgb, grad, 0.0;
00148 DP3_SAT temp.r, temp, 1.0;
00149
00150 # Reconstruct the gradient
00151 MAD_SSAT grad.rgb, grad, 2.0, -1.0;
00152 NRM_SSAT grad.rgb, grad;
00153
00154 # Set gradient to zero if it was zero
00155 MUL grad.rgb, grad, temp.r;
00156
00157 # Re-orient the gradient to get a
00158 # correct surface normal
00159 MOV temp, 0.0;
00160 DP3 temp.r, -geomDir, grad;
00161 NRM temp, temp;
00162 MUL grad.rgb, grad, temp.r;
00163
00164 # Perform the lighting calculation (yes, we know LIT!)
00165
00166 # Ambient term
00167 MUL ambient, state.light[0].ambient, src;
00168
00169 # Diffuse term
00170 SUB lightVec.rgb, state.light[0].position, pos;
00171 MOV lightVec.a, 0.0;
00172 NRM lightVec, lightVec;
00173 DP3_SAT temp.a, lightVec, grad;
00174 MUL temp, src, temp.a;
00175 MUL diffuse, state.light[0].diffuse, temp;
00176
00177 # Specular term
00178 ADD halfway, lightVec, -dir;
00179 MOV halfway.a, 0.0;
00180 NRM halfway, halfway;
00181
00182 SUB eyeVec.rgb, camera, pos;
00183 MOV eyeVec.a, 0.0;
00184 NRM eyeVec, eyeVec;
00185 DP3_SAT temp.a, halfway, grad;
00186 POW temp.a, temp.a, 10.0;
00187 MUL eyeVec, src, state.light[0].specular;
00188 MUL specular, eyeVec, temp.a;
00189
00190 # Isosurfaces are opaque
00191 ADD_SAT dst.rgb, ambient, diffuse;
00192 ADD_SAT dst.rgb, dst, specular;
00193 MOV dst.a, 1.0;
00194
00195 # Everything is done, jump out of loop
00196 MOVC temp.x, 0.0;
00197 BRK (EQ.x);
00198 ENDIF;
00199
00200 MOV intens.g, intens.r;
00201
00202 # Set values to zero if outside volume
00203 SGE temp1, pos, 0.0;
00204 SLE temp2, pos, texMax;
00205 DP3 weight.r, temp1, temp2;
00206 SEQC weight.r, weight.r, 3.0;
00207
00208 # Already outside volume, skip the rest
00209 BRK (EQ.x);
00210
00211 ENDREP;
00212
00213 BRK (EQ.x);
00214
00215 ENDREP;
00216
00217 # -------------- Shadow Code Begin -----------------------
00218
00219 # Only need to compute shadows for non-transparent fragments
00220 MOVC dst.a, dst.a;
00221 IF NE.w;
00222
00223 MOV pos2, pos;
00224 MOV shadow, 1.0;
00225
00226 SUB lightVec.rgb, state.light[0].position, pos2;
00227 MOV lightVec.a, 0.0;
00228 NRM lightVec, lightVec;
00229
00230 MOV sign, -5.0;
00231
00232 REP 255;
00233 # Move one step forward
00234 MAD pos2, lightVec, params.r, pos2;
00235
00236 MOV texCoord.rgb, pos2;
00237 TXL tex, texCoord, texture[0], 3D;
00238
00239 # Component 'b' written to circumvent driver bug
00240 MOV intens.rb, tex.a;
00241
00242 # Exit loop when leaving volume
00243 SGE temp1, pos2, 0.0;
00244 SLE temp2, pos2, texMax;
00245 DP3 weight.r, temp1, temp2;
00246 SEQC weight.r, weight.r, 3.0;
00247 BRK (EQ.x);
00248
00249 # Isosurface if differences with past and present
00250 # scalar values and isovalue have different signs
00251 SUB temp.rg, intens, params2.b;
00252 MULC temp, temp.r, temp.g;
00253 IF LE.x;
00254 # Isosurface found
00255
00256 MOVC_SAT temp.g, sign;
00257 IF NE.y;
00258 MAD_SAT dst.rgb, diffuse, .25, ambient;
00259 BRK;
00260 ENDIF;
00261
00262 ENDIF;
00263
00264 MOV intens.g, intens.r;
00265
00266 ADD sign, sign, 1.0;
00267 ENDREP;
00268 ENDIF;
00269 # -------------- Shadow Code End -------------------------
00270
00271 # Compute the normal of the background plane (this is just the negative view
00272 # direction which initially is (0, 0, -1))
00273 MOV normal, state.matrix.modelview.row[2];
00274
00275 # Compute the plane constant (we want the plane to be located in the volume
00276 # center)
00277 DP3 temp1.r, normal, center;
00278
00279 # Move the plane behind the volume: d' = <n,(x - l n)> = <n, x> - l <n, n>;
00280 # l = 0.71 is chosen since it is greater than half the cube diagonal
00281 DP3 temp1.g, normal, normal;
00282 MAD temp1.r, temp1.g, -.71, temp1.r;
00283
00284 # Compute ray parameter
00285 DP3 temp1.g, normal, geomPos;
00286 SUB temp1.g, temp1.r, temp1.g;
00287 DP3 temp1.b, normal, geomDir;
00288 DIV temp.r, temp1.g, temp1.b;
00289
00290 # Compute ray/plane intersection
00291 MAD temp.rgb, temp.r, geomDir, geomPos;
00292
00293 # Compute the difference vector
00294 SUB diffVec, temp, center;
00295
00296 # Compute the texture coordinates
00297 DP3 temp.r, diffVec, state.matrix.modelview.row[0];
00298 DP3 temp.g, diffVec, state.matrix.modelview.row[1];
00299 MUL temp.rg, temp, params2.r;
00300
00301 # Center background image
00302 ADD temp.rg, temp, .5;
00303
00304 # Look up the texel value
00305 TEX temp.rgb, temp, texture[2], 2D;
00306 MOV temp.a, 1.0;
00307
00308 # Blend the background pixel
00309 SUB texblen, 1.0, dst.a;
00310 MAD dst, temp, texblen.x, dst;
00311
00312 # Write the output color
00313 MOV result.color, dst;
00314
00315 END