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_refraction_sm3.fp
00016
00017 #! VOLUME = 0
00018 #! TRANSFERFUNCTION = 1
00019 #! OPTICALDENSITY = 2
00020 #! BACKGROUND = 3
00021
00022 # r = step
00023 # g = gradient scale
00024 # b = gradient offset
00025 # a = z-value of background plane
00026 PARAM params = program.local[0];
00027
00028 # r = texture coordinate scale
00029 # g = number of iterations
00030 # b = isovalue of isosurface
00031 PARAM params2 = program.local[1];
00032 PARAM center = program.local[2];
00033 PARAM texMax = program.local[3];
00034
00035 PARAM scaleFactors = program.local[5];
00036 PARAM scaleFactorsInv = program.local[6];
00037
00038 TEMP geomDir;
00039 TEMP geomPos;
00040 TEMP lightVec;
00041 TEMP texCoord;
00042 TEMP texblen;
00043 TEMP diffVec;
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
00060 # Compute the ray's starting point
00061 MOV geomPos, fragment.texcoord[0];
00062 MUL pos, geomPos, scaleFactors;
00063 MOV pos.a, 0.0;
00064
00065 MOV texCoord, 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 optical density
00083 TXL intens, pos, texture[0], 3D;
00084 MOV intens.g, intens.a;
00085 MOV texCoord.rgb, intens.a;
00086 TXL intens.r, texCoord, texture[2], 1D;
00087 MOV intens.a, intens.r;
00088 # Scale the optical density (keep in sync with initialization below)
00089 MUL intens.a, intens.a, params.g;
00090 ADD intens.a, intens.a, params.b;
00091
00092 MOV sign, 0.0;
00093
00094 REP params2.g;
00095 REP params2.g;
00096 # Determine scalar value and gradient
00097 TXL tex, pos, texture[0], 3D;
00098 MOV intens.r, tex.a;
00099 MOV grad.rgb, tex;
00100
00101 # Determine scale factor for gradient
00102 SNE temp.rgb, grad, 0.0;
00103 DP3_SAT temp.r, temp, 1.0;
00104
00105 # Reconstruct the gradient
00106 MAD_SSAT grad.rgb, tex, 2.0, -1.0;
00107 NRM_SSAT grad.rgb, grad;
00108
00109 # Set gradient to zero if it was zero
00110 MUL grad.rgb, grad, temp.r;
00111
00112 # Determine optical density
00113 MOV texCoord.rgb, intens.r;
00114 TXL intens.b, texCoord, texture[2], 1D;
00115
00116 # Scale the optical density (keep in sync with initialization above)
00117 MUL intens.b, intens.b, params.g;
00118 ADD intens.b, intens.b, params.b;
00119
00120 # The direction vector must be in world-space and normalized
00121 MUL temp1, dir, scaleFactorsInv;
00122 NRM temp1, temp1;
00123
00124 # Determine case
00125 DP3 sign.r, temp1, grad;
00126 NRM_SSAT sign, sign;
00127 DP3 temp.r, -temp1, grad;
00128
00129 # temp.rga <- shift vector perpendicular to surface normal (a)
00130 MAD temp.rgb, temp.r, grad, temp1;
00131
00132 # temp.a <- ratio of optical densities (n1/n2)
00133 DIV temp.a, intens.a, intens.b;
00134
00135 # dir.rgb <- (n1/n2) * a
00136 MUL temp1.rgb, temp, temp.a;
00137 DP3_SAT temp.r, temp1, temp1;
00138 SUB_SAT temp.r, 1.0, temp.r;
00139 POW_SAT temp.r, temp.r, 0.5;
00140 MUL temp.r, temp.r, sign.r;
00141 MAD temp1.rgb, temp.r, grad, temp1;
00142 NRM temp1.rgb, temp1;
00143 MUL dir, temp1, scaleFactors;
00144
00145 # Move one step forward
00146 MAD pos.rgb, dir, params.r, pos;
00147
00148 # Set values to zero if outside volume
00149 SGE temp1, pos, 0.0;
00150 SLE temp2, pos, texMax;
00151 DP3 weight.r, temp1, temp2;
00152 SEQC weight.r, weight.r, 3.0;
00153 # Already outside volume, skip the rest
00154 BRK (EQ.x);
00155
00156 MOV texCoord.rg, intens;
00157 TXL src, texCoord, texture[1], 2D;
00158 SUBC texblen, 1.0, dst.a;
00159
00160 # Early ray termination (XXX DOES NOT WORK!)
00161 #BRK (EQ.x);
00162
00163 MAD dst, src, texblen.x, dst;
00164 MOV intens.g, intens.r;
00165
00166 # Copy optical density
00167 MOV intens.a, intens.b;
00168 ENDREP;
00169 BRK (EQ.x);
00170 ENDREP;
00171
00172 MUL geomPos, pos, scaleFactorsInv;
00173 MUL geomDir, dir, scaleFactorsInv;
00174
00175 # Compute the normal of the background plane (this is just the negative view
00176 # direction which initially is (0, 0, -1))
00177 MOV normal, state.matrix.modelview.row[2];
00178
00179 # Compute the plane constant (we want the plane to be located in the volume
00180 # center)
00181 DP3 temp1.r, normal, center;
00182
00183 # Move the plane behind the volume: d' = <n,(x - l n)> = <n, x> - l <n, n>;
00184 # l = 0.71 is chosen since it is greater than half the cube diagonal
00185 DP3 temp1.g, normal, normal;
00186 MAD temp1.r, temp1.g, -.71, temp1.r;
00187
00188 # Compute ray parameter
00189 DP3 temp1.g, normal, geomPos;
00190 SUB temp1.g, temp1.r, temp1.g;
00191 DP3 temp1.b, normal, geomDir;
00192 DIV temp.r, temp1.g, temp1.b;
00193
00194 # Compute ray/plane intersection
00195 MAD temp.rgb, temp.r, geomDir, geomPos;
00196
00197 # Compute the difference vector
00198 SUB diffVec, temp, center;
00199
00200 # Compute the texture coordinates
00201 DP3 temp.r, diffVec, state.matrix.modelview.row[0];
00202 DP3 temp.g, diffVec, state.matrix.modelview.row[1];
00203 MUL temp.rg, temp, params2.r;
00204
00205 # Center background image
00206 ADD temp.rg, temp, .5;
00207
00208 # Look up the texel value
00209 TEX temp.rgb, temp, texture[3], 2D;
00210 MOV temp.a, 1.0;
00211
00212 # Blend the background pixel
00213 SUB texblen, 1.0, dst.a;
00214 MAD dst, temp, texblen.x, dst;
00215
00216 # Write the output color
00217 MOV result.color, dst;
00218
00219 END