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: volume_isosurface_sm3.fp
00016
00017 #! VOLUME = 0
00018 #! BACKGROUND = 1
00019 #! TRANSFERFUNCTION = 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 # Color(s) must be premultiplied by alpha
00037 #PARAM isColor1 = {0.0, 0.15, 0.0, 0.15};
00038 PARAM isColor1 = {0.33, 0.33, 0.25, 0.15};
00039
00040 TEMP geomPos;
00041 TEMP geomDir;
00042 TEMP localDst;
00043 TEMP lightVec;
00044 TEMP origPos;
00045 TEMP prevPos;
00046 TEMP texblen;
00047 TEMP diffVec;
00048 TEMP halfway;
00049 TEMP eyeVec;
00050 TEMP intens;
00051 TEMP camera;
00052 TEMP normal;
00053 TEMP weight;
00054 TEMP temp1;
00055 TEMP temp2;
00056 TEMP temp;
00057 TEMP grad;
00058 TEMP pos;
00059 TEMP dst;
00060 TEMP dir;
00061 TEMP tex;
00062 TEMP scalActInner;
00063 TEMP scalPreInner;
00064 TEMP scalActOuter;
00065 TEMP scalPreOuter;
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 scalPreOuter, intens.a;
00090
00091 # Initialize destination color
00092 MOV dst, 0.0;
00093
00094 REP params2.g;
00095
00096 REP params2.g;
00097 # Lookup scalar and gradient
00098 TXL tex, pos, texture[0], 3D;
00099 MOV scalActOuter, tex.a;
00100
00101 # ---
00102 # Lookup color in pre-int texture
00103 MOV intens.r, scalActOuter;
00104 MOV intens.g, scalPreOuter;
00105 TXL tex, intens, texture[2], 2D;
00106
00107 # Perform blending
00108 SUB texblen.r, 1.0, dst.a;
00109 MAD_SAT dst, tex, texblen.r, dst;
00110 # ---
00111
00112 # Move one step forward
00113 MAD pos, dir, params.r, pos;
00114
00115 # Isosurface if differences with past and present
00116 # scalar values and isovalue have different signs
00117 SUB temp.rg, intens, params2.b;
00118 MULC temp, temp.r, temp.g;
00119 IF LE.x;
00120 # Isosurface found
00121 MOV origPos, pos;
00122
00123 # Get scalar value from actual position
00124 MAD pos, -dir, params.r, pos;
00125 TXL scalActInner, pos, texture[0], 3D;
00126
00127 # Get scalar value from previous position
00128 MAD prevPos, -dir, params.r, pos;
00129 TXL scalPreInner, prevPos, texture[0], 3D;
00130
00131 SUB temp.r, params2.b, scalPreInner.a;
00132 SUB temp.g, scalActInner.a, scalPreInner.a;
00133
00134 # Perform linear interpolation to increase accuracy
00135 DIV_SAT temp.b, temp.r, temp.g;
00136 LRP pos, temp.b, pos, prevPos;
00137
00138 # Determine gradient at corrected position (same as above)
00139 TXL grad.rgb, pos, texture[0], 3D;
00140
00141 # Determine scale factor for gradient
00142 SNE temp.rgb, grad, 0.0;
00143 DP3_SAT temp.r, temp, 1.0;
00144
00145 # Reconstruct the gradient
00146 MAD_SSAT grad.rgb, grad, 2.0, -1.0;
00147 NRM_SSAT grad.rgb, grad;
00148
00149 # Set gradient to zero if it was zero
00150 MUL grad.rgb, grad, temp.r;
00151
00152 # Re-orient the gradient to get a
00153 # correct surface normal
00154 MOV temp, 0.0;
00155 DP3 temp.r, -geomDir, grad;
00156 NRM temp, temp;
00157 MUL grad.rgb, grad, temp.r;
00158
00159 # Perform the lighting calculation (yes, we know LIT!)
00160
00161 # Ambient term
00162 MUL localDst, state.light[0].ambient, isColor1;
00163
00164 # Diffuse term
00165 SUB lightVec.rgb, state.light[0].position, pos;
00166 MOV lightVec.a, 0.0;
00167 NRM lightVec, lightVec;
00168 DP3_SAT temp.a, lightVec, grad;
00169 MUL temp, isColor1, temp.a;
00170 MAD localDst, state.light[0].diffuse, temp, localDst;
00171
00172 # Specular term
00173 # First calculate halfway vector
00174 ADD halfway, lightVec, -dir;
00175 MOV halfway.a, 0.0;
00176 NRM halfway, halfway;
00177 # Specular Lighting
00178 SUB eyeVec.rgb, camera, pos;
00179 MOV eyeVec.a, 0.0;
00180 NRM eyeVec, eyeVec;
00181 DP3_SAT temp.a, halfway, grad;
00182 POW temp.a, temp.a, 100.0;
00183 MAD localDst, state.light[0].specular, temp.a, localDst;
00184
00185 # Perform the blending
00186 SUB texblen.g, 1.0, dst.a;
00187 MAD dst, localDst, texblen.g, dst;
00188
00189 # Set the new position (otherwise the isosurface would be
00190 # intersected again -- we don't know why -- and it actually would
00191 # be better to just restore the original position)
00192 #MUL temp, params.r, dir;
00193 MOV pos, origPos;
00194 ENDIF;
00195
00196 # Set values to zero if outside volume
00197 SGE temp1, pos, 0.0;
00198 SLE temp2, pos, texMax;
00199 DP3 weight.r, temp1, temp2;
00200 SEQC weight.r, weight.r, 3.0;
00201
00202 # Already outside volume, skip the rest
00203 BRK (EQ.x);
00204
00205 MOV scalPreOuter, scalActOuter;
00206 ENDREP;
00207
00208 # Already outside volume, skip the rest
00209 BRK (EQ.x);
00210
00211 ENDREP;
00212
00213 # Compute the normal of the background plane (this is just the negative view
00214 # direction which initially is (0, 0, -1))
00215 MOV normal, state.matrix.modelview.row[2];
00216
00217 # Compute the plane constant (we want the plane to be located in the volume
00218 # center)
00219 DP3 temp1.r, normal, center;
00220
00221 # Move the plane behind the volume: d' = <n,(x - l n)> = <n, x> - l <n, n>;
00222 # l = 0.71 is chosen since it is greater than half the cube diagonal
00223 DP3 temp1.g, normal, normal;
00224 MAD temp1.r, temp1.g, -.71, temp1.r;
00225
00226 # Compute ray parameter
00227 DP3 temp1.g, normal, geomPos;
00228 SUB temp1.g, temp1.r, temp1.g;
00229 DP3 temp1.b, normal, geomDir;
00230 DIV temp.r, temp1.g, temp1.b;
00231
00232 # Compute ray/plane intersection
00233 MAD temp.rgb, temp.r, geomDir, geomPos;
00234
00235 # Compute the difference vector
00236 SUB diffVec, temp, center;
00237
00238 # Compute the texture coordinates
00239 DP3 temp.r, diffVec, state.matrix.modelview.row[0];
00240 DP3 temp.g, diffVec, state.matrix.modelview.row[1];
00241 MUL temp.rg, temp, params2.r;
00242
00243 # Center background image
00244 ADD temp.rg, temp, .5;
00245
00246 # Look up the texel value
00247 TEX temp.rgb, temp, texture[1], 2D;
00248 MOV temp.a, 1.0;
00249
00250 # Blend the background pixel
00251 SUB texblen, 1.0, dst.a;
00252 MAD dst, temp, texblen.x, dst;
00253
00254 # Write the output color
00255 MOV result.color, dst;
00256
00257 END