ps_2_0 //////////////////////////////////////////////////////////// // textures //////////////////////////////////////////////////////////// #define PosTexture s0 #define ATan2Texture s1 #define SphAreaTexture s2 #define ColorTexture s3 dcl_2d s0 dcl_2d s1 dcl_2d s2 dcl_2d s3 //////////////////////////////////////////////////////////// // texture coordinates //////////////////////////////////////////////////////////// #define PixelPosition t0 #define EdgeVert0 t1 #define EdgeVert1 t2 dcl t0.xyzw // pixel position (x,y,z) dcl t1.xyz // EdgeVert[0] dcl t2.xyz // EdgeVert[1] //////////////////////////////////////////////////////////// // constants //////////////////////////////////////////////////////////// #define LightCenter c0 #define InvLightRadius c0.w #define InvZ c1 #define Zero c2.x #define OneHalf c2.y #define One c2.z #define InvPi c2.w #define CosPiOverFour c3.x #define Four c3.w #define NegZ c4 def c1, 1.0f, 1.0f, -1.0f, 0.0f // [1, 1, -1, 0] def c2, 0.0f, 0.5f, 1.0f, 0.318309886 // 0, 1/2, 1, 1/PI def c3, 0.707106781187, 0.0f, 0.0f, 4.0f // cos(PI/4), 0, 0, 4 def c4, 0.0f, 0.0f, -1.0f, 0.0f // [0, 0, -1, 0] /////////////////////////////////////////////////////////////////// // MAIN: /////////////////////////////////////////////////////////////////// // get world point (1t) texldp r0, PixelPosition, PosTexture // compute rotation basis (11a) add r11.xyz, LightCenter, -r0 // Light center - Point to be shaded dp3 r11.w, r11, r11 rsq r0.w, r11.w mul r3.xyz, r11, r0.w // Z axis mul r11.xyz, r3.zxyw, r3.zxyw // Cross with perpindicular vector mad r11.xyz, r3.xyzw, -r3.yzxw, r11 nrm r1.xyz, r11 // X axis crs r2.xyz, r1, r3 // Y axis // transform edgeverts into projected space (12a) add r11.xyz, EdgeVert0, -r0 dp3 r4.x, r11, r1 dp3 r4.y, r11, r2 dp3 r4.z, r11, r3 add r11.xyz, EdgeVert1, -r0 dp3 r5.x, r11, r1 dp3 r5.y, r11, r2 dp3 r5.z, r11, r3 mul r11.x, r11.w, r0.w // |L - P| mul r11.x, r11.x, InvLightRadius mul r4.xy, r4, r11.x mul r5.xy, r5, r11.x // compute quadradic coefficents (8a) add r6.xyz, r5, -r4 // E1 - E0 mul r11.xyz, r6, r6 dp3 r7.x, r11, InvZ // a mul r11.xyz, r4, r6 dp3 r7.y, r11, InvZ // b add r7.y, r7.y, r7.y mul r11.xyz, r4, r4 dp3 r7.z, r11, InvZ // c // compute sqrt(b^2-4ac) (5a) mul r11.x, r7.y, r7.y // b^2 mul r11.y, r7.x, r7.z // a*c mad r7.w, r11.y, -Four, r11.x // b^2-4ac rsq r11.z, r7.w // 1/sqrt(b^2-4ac) mul r11.z, r7.w, r11.z // sqrt(b^2-4ac) // compute r1 and r2 (5a) add r11.w, r7.x, r7.x // 2*a rcp r11.w, r11.w // 1 / (2*a) add r11.x, -r7.y, -r11.z // -b - sqrt(b^2-4ac) add r11.y, -r7.y, r11.z // -b + sqrt(b^2-4ac) mul_sat r10.xy, r11, r11.w // t0, t1 // reject intersections below the xy plane (4a) // if (-dir.z/|dir| > cos(PI/4)) t1 = zero dp3 r6.w, r6, r6 rsq r6.w, r6.w mad r0.w, -r6.z, r6.w, -CosPiOverFour cmp r10.y, r0.w, Zero, r10.y // set r10 to 0 if Disc <= 0 (1a) cmp r10.xy, -r7.w, Zero, r10 // compute r1 and r2 clipped (2a) mad r1.xyz, r6, r10.x, r4 // C0 mad r2.xyz, r6, r10.y, r4 // C1 // project (4a) rcp r11.w, r1.z mad r1.xyz, r1, r11.w, NegZ // P0 rcp r11.w, r2.z mad r2.xyz, r2, r11.w, NegZ // P1 // Compute area (3t, 5a) texld r3, r1, ATan2Texture // theta0 texld r4, r2, ATan2Texture // theta1 crs r5.z,r1,r2 // z = 2*triangle_area abs r5.z,r5.z mov r3.y, r4.x texld r4, r3, SphAreaTexture // lookup theta/PI // 2 * coverage = Theta/PI - AxB/PI (1a) mad_sat r11, -r5.z, InvPi, r4.x // lookup split coverage value (1t) texld r11, r11, ColorTexture // mov (1a) mov oC0, r11