!!VP1.0 ################################################### ################################################### # PART I - Transform the vertices by the # modelview/projection matrix, compute the # three vectors of interest and the z-coordinates # of some cross products # # v[0].x - which run this is (0,1,2,3 or 4) # # (Note that program is called *6* times, with run values # of 0, 1, 2, 3, 4, 1. The last vertex output is the # same as the 2nd vertex output.) # # v[1] - vertex 1 # v[2] - vertex 2 # v[3] - vertex 3 # v[4] - vertex 4 # # v[5] - lighting factor # # v[6] - color # v[7] - color # v[8] - color # v[9] - color # # c[0-3] modelview/projection matrix # # c[14] = (30, 60, 0, 0) # c[18] = (1, 2, 3, 4) # c[19] = (.5, 0, 0, 0) # # c[30] - c[49] - masks for choosing output vertex # # c[60] - c[91] - masks for vertex reordering ################################################### # # transform the vertices by model/view/projection: R0, R1, R2, R3 # DP4 R0.x, c[0], v[1]; DP4 R0.y, c[1], v[1]; DP4 R0.z, c[2], v[1]; DP4 R0.w, c[3], v[1]; DP4 R1.x, c[0], v[2]; DP4 R1.y, c[1], v[2]; DP4 R1.z, c[2], v[2]; DP4 R1.w, c[3], v[2]; DP4 R2.x, c[0], v[3]; DP4 R2.y, c[1], v[3]; DP4 R2.z, c[2], v[3]; DP4 R2.w, c[3], v[3]; DP4 R3.x, c[0], v[4]; DP4 R3.y, c[1], v[4]; DP4 R3.z, c[2], v[4]; DP4 R3.w, c[3], v[4]; # # the three vectors: R4, R5 and R6 # ADD R4, R1, -R0; ADD R5, R2, -R0; ADD R6, R3, -R0; # # the z-coordinates of R4 X R5, R4 X R6, # and the z-coord of -(R5 X R6) # put these in R7 # MUL R10, R4.xyzz, R5.yxzz; MUL R9, R4.xyzz, R6.yxzz; MUL R11, R6.xyzz, R5.yxzz; ADD R7.x, R10.x, -R10.y; # R4 X R5 ADD R7.y, R9.x, -R9.y; # R4 X R6 ADD R7.z, R11.x, -R11.y; # R6 X R5 ################################################### ################################################### # PART II - Compute 3 tests, save in R4 # # Test1 = (R7.x * R7.y < 0) # Test2 = (R7.x * R7.z < 0) # Test4 = (R7.x > 0) # MUL R11, R7.xxzz, R7.yzzz; SLT R4, R11.xyzz, c[14].z; # t1 & t2 SLT R4.w, -R7.x, c[14].z; # t4 ################################################### ################################################### # PART III - Reorder the vertices (R0, R1, R2, R3) # into (R8, R9, R10, R11) such that their projected convex hull in # CCW order is R8, R11, R9, R10 or R8, R11, R10 with R9 inside the # hull. Until the intersection test proves otherwise, we will # assume all points are on the hull. # # t1 t2 t4 | R8 R9 R10 R11 # ----------+----------------- # 0 0 0 | R0 R3 R1 R2 # 0 0 1 | R0 R3 R2 R1 # 0 1 0 | R0 R2 R1 R3 # 0 1 1 | R0 R2 R3 R1 # 1 0 0 | R0 R1 R3 R2 # 1 0 1 | R0 R1 R2 R3 # 1 1 0 | R2 R0 R3 R1 # 1 1 1 | R3 R0 R2 R1 # ################################################### # Get index into truth table: R5 MAD R5, R4.y, c[18].y, R4.w; # R5 = (t2 * 2) + t4 MAD R5, R4.x, c[18].w, R5; # R5 = (t1 * 4) + (t2 * 2) + t4 MUL R5, R5, c[18].w; # (val * 4) ADD R5, R5, c[14].y; # + offset into parameter array # have to save R5 for later. DON'T REUSE IT. ARL A0.x, R5.x; # location of masks # Copy reordered vertices MUL R8, R0, c[A0.x].xxxx; # Copy appropriate vertex. MAD R8, R1, c[A0.x].yyyy, R8; MAD R8, R2, c[A0.x].zzzz, R8; MAD R8, R3, c[A0.x].wwww, R8; MUL R9, R0, c[A0.x + 1].xxxx; # Copy appropriate vertex. MAD R9, R1, c[A0.x + 1].yyyy, R9; MAD R9, R2, c[A0.x + 1].zzzz, R9; MAD R9, R3, c[A0.x + 1].wwww, R9; MUL R10, R0, c[A0.x + 2].xxxx; # Copy appropriate vertex. MAD R10, R1, c[A0.x + 2].yyyy, R10; MAD R10, R2, c[A0.x + 2].zzzz, R10; MAD R10, R3, c[A0.x + 2].wwww, R10; MUL R11, R0, c[A0.x + 3].xxxx; # Copy appropriate vertex. MAD R11, R1, c[A0.x + 3].yyyy, R11; MAD R11, R2, c[A0.x + 3].zzzz, R11; MAD R11, R3, c[A0.x + 3].wwww, R11; ################################################### # PART IV - Compute the coordinates of the # intersection of the lines R8-R9 and R10-R11 ################################################### # This algorithm is based of that in Graphics Gems III # pg. 199-202 # We find the intersection by linearly interpreting between the points. # First, we define the two equations # R8 + A(R9 - R8) # R10 + B(R11 - R10) # and then find the A and B with which the two # equations are equal. Subtracting these two equations, we get: # 0 = (R8 - R10) + A(R9 - R8) + B(R10 - R11) ADD R0, R9, -R8; ADD R1, R10, -R11; ADD R2, R8, -R10; # Now our equation is: # 0 = R2 + A*R0 + B*R1 # By looking seperately at the equations for x and y coordinates # (we ignore z since we are only interested in the intersection in # the projection on X-Y plane) we find that A and B are: # A = (R1.y*R2.x - R1.x*R2.y)/(R0.y*R1.x - R0.x*R1.y) # B = (R0.x*R2.y - R0.y*R2.x)/(R0.y*R1.x - R0.x*R1.y) # (Note that the demoninators are the same. # Denominator MUL R6.x, R0.x, R1.y; MAD R6.x, R0.y, R1.x, -R6; RCP R6, R6.x; # A numerator MUL R3.x, R1.x, R2.y; MAD R3.x, R1.y, R2.x, -R3; # B numerator MUL R3.y, R0.y, R2.x; MAD R3.y, R0.x, R2.y, -R3.y; # The final A & B. MUL R3, R3, R6; # Line 60 # Get the intersection points coordinates: # I = R8 + A*(R9 - R8) = R8 + R3.x*R0 # or # I = R10 + B*(R11 - R10) = R10 - R3.y*R1 # Note that the x and y coordinates of these two "intersections" # are the same (a good debugging check), but the z will be # different. This difference can aid us in the depth caluclation. MAD R7, R3.xxxx, R0, R8; MAD R6, R3.yyyy, -R1, R10; # Hack: store A&B for later MOV R5.y, R3.x; MOV R5.z, R3.y; # To find the intersection point above, we found the value for A # for which the equation # R8 + A(R9 - R8) # equals the intersection point. Notice that if A < 1.0, then the # the intersection is in the middle of segment R8R9 and the distance # from R8 to the intersection (R7) is less then to R9. If A > 1.0, # the intersection is outside the line segment, and the distance to # R7 is greater. Therefore, to do test 3, we only have to compare # A (stored in R3.x) to 1.0 # # Test 3: Distance R8-R9 exceeds distance R8-R7 # SLT R4.z, R3.x, c[18].x; ################################################### ################################################### # PART V - Compute the thickness at the "thick" # point. If this run is generating the # "thick" point, output that thickness as # the texture coordinate. # ################################################### # # In Part IV, we actually calculated two intersection points, # R7 and R6, which should only differ by z values. The difference # will give us the depth at the intersection point. ADD R0, R7, -R6; MAX R0.z, R0.z, -R0.z; # R0.z = intersection depth # If t3 is true, then the intersection point is where the depth # value is located. If it is false, the depth should be calculated # at R9. In this case, we can get the depth by simply interpolating # back from R7 to R9. We can reuse the A value (R3.x) for this. RCP R1.x, R3.x; MUL R1.z, R0.z, R1.x; # R1.z = scaled depth # Pick correct thickness based on t3. Put in R0.x ADD R3.x, c[18].x, -R4.z; # R3.x = 1-t1 = !t1 MUL R0.x, R0.z, R4.z; MAD R0.x, R1.z, R3.x, R0.x; # # input multiplier - it's non-zero only on run 0 # # Note: the texture value output to the 1D texture map must # be of the form (coord, coord, 0, 1) # MOV R0.yzw, c[18].xxxx; # R0 = (thickness, 1, 1, 1) MUL R0.x, R0.x, v[0].y; # zero out the thickness if it's not run 0 MUL o[TEX0], v[5], R0; # (multiplier*R0.x, 0, 0, 1) ################################################### ################################################### # # Part VI - Move the chosen vertex to the output # # Given the reordering of Part III, select the following as output # given the run number: # 0 - R9 if !t3, R7 if t3 # 1 - R10 # 2 - R8 # 3 - R11 # 4 - R10 if !t3, R9 if t3 MUL R3, v[0].x, c[18].w; # run * 4 ADD R3, c[14].x, R3; # add 30, offset into parameter indices MAD R3, R4.z, c[18].y, R3; # add in 2 more if t3 is true ARL A0.x, R3.x; # DON'T OVERWRITE R3 - it's used again MUL R2, R7, c[A0.x].xxxx; MAD R2, R8, c[A0.x].yyyy, R2; MAD R2, R9, c[A0.x].zzzz, R2; MAD R2, R10, c[A0.x].wwww, R2; MAD R2, R11, c[A0.x + 1].xxxx, R2; MOV o[HPOS], R2; ################################################### # Compute color. In the case of the thick vertex # (also known as run 0), # it is the average of all the colors. In the case # of the other vertices, it is simply the color of # that vertex. ################################################### # # reorder the input colors as the vertices were # ARL A0.x, R5.x; # location of masks MUL R8, v[6], c[A0.x].xxxx; # Copy appropriate color. MAD R8, v[7], c[A0.x].yyyy, R8; MAD R8, v[8], c[A0.x].zzzz, R8; MAD R8, v[9], c[A0.x].wwww, R8; MUL R9, v[6], c[A0.x + 1].xxxx; # Copy appropriate color. MAD R9, v[7], c[A0.x + 1].yyyy, R9; MAD R9, v[8], c[A0.x + 1].zzzz, R9; MAD R9, v[9], c[A0.x + 1].wwww, R9; MUL R10, v[6], c[A0.x + 2].xxxx; # Copy appropriate color. MAD R10, v[7], c[A0.x + 2].yyyy, R10; MAD R10, v[8], c[A0.x + 2].zzzz, R10; MAD R10, v[9], c[A0.x + 2].wwww, R10; MUL R11, v[6], c[A0.x + 3].xxxx; # Copy appropriate color. MAD R11, v[7], c[A0.x + 3].yyyy, R11; # Line 100 MAD R11, v[8], c[A0.x + 3].zzzz, R11; MAD R11, v[9], c[A0.x + 3].wwww, R11; # # copy the color of the selected vertex to R2 # ARL A0.x, R3.x; MUL R2, R8, c[A0.x].yyyy; MAD R2, R9, c[A0.x].zzzz, R2; MAD R2, R10, c[A0.x].wwww, R2; MAD R2, R11, c[A0.x + 1].xxxx, R2; # # Now compute (Cf+Cb)/2 # # set temp registers ADD R0, R9, -R8; # R0 = (R9-R8) ADD R1, R11, -R10; # R1 = (R11-R10) SLT R3.x, c[18].x, R5.y; # R3.x = true/false (1