// Code for non-textured rectangular light ps_2_0 ; ; Inputs ; dcl_2d s0 ; xyz in light space dcl_cube s1 ; ATAN2 texture dcl_2d s2 ; Area texture dcl_2d s3 ; Color encoding texture dcl t0.xyzw ; screenspace x,y dcl t1.xyz ; EDGE0 in light space dcl t2.xyz ; EDGE1 in light space #define vEDGE0 t1 #define vEDGE1 t2 #define vEDGE_PLANE t3 ; ; Constants ; ; c0-c2 = 3x4 light transform ; c3 = 1/light_extent_x, 0, 1/light_extent_y, 0 def c4, 0.125, 0.0, 0.0, 0.0 ; 0.5 * 0.25 def c8, 0.0, 0.0, 0.0, 0.0 ; all zero #define ZERO c8 #define vLIGHT_XFORM0 c0 #define vLIGHT_XFORM1 c1 #define vLIGHT_XFORM2 c2 #define ONE_OVER_EXTENT_X c3.x #define ONE_OVER_EXTENT_Y c3.z #define AREA_SCALE c4.x ; Sample postion in world space texldp r11, t0, s0 ; Transform position into light co-ordinates dp4 r0.x, r11, vLIGHT_XFORM0 dp4 r0.y, r11, vLIGHT_XFORM1 dp4 r0.z, r11, vLIGHT_XFORM2 ; Build projection matrix ; -p.z/hx, 0, p.x/hx, 0 ; 0, -p.z/hy, p.y/hy, 0 mul r3.xy, -r0.zxyw, c3.xyzw ; [1/hx, 0] mul r3.z, r0.yzxw, c3.x ; 1/hx mul r4.xy, -r0.yzxw, c3.yzxw ; [0, 1/hy] mul r4.z, r0.zxyw, c3.z ; 1/hy ; Transform edge add r9.xyz, vEDGE0, -r0 ; offset by point add r10.xyz, vEDGE1, -r0 dp3 r9.x, r9, r3 dp3 r9.y, r9, r4 ; r9.x is not used dp3 r10.x, r10, r3 dp3 r10.y, r10, r4 ; r10.x is not used ; Homogenous clipping to each edge (36 instructions) add r1.w, r9.x, r9.z ; w1 + x1 add r2.w, r10.x, r10.z ; w2 + x2 sub r3.w, r1.w, r2.w ; d1-d2 rcp r3.w, r3.w ; 1/(d1-d2) mul r3.w, r1.w, r3.w ; t = d1/(d1-d2) sub r4.xyz, r10, r9 ; E1-E0 mad r5.xyz, r3.w, r4, r9 ; I = E0 + t*(E1-E0) cmp r9.xyz, r1.w, r9, r5 ; clipped edge in r9,r10 cmp r10.xyz, r2.w, r10, r5 add r1.w, -r9.x, r9.z ; w1 - x1 add r2.w, -r10.x, r10.z ; w2 - x2 sub r3.w, r1.w, r2.w rcp r3.w, r3.w mul r3.w, r1.w, r3.w sub r4.xyz, r10, r9 mad r5.xyz, r3.w, r4, r9 cmp r9.xyz, r1.w, r9, r5 cmp r10.xyz, r2.w, r10, r5 add r1.w, r9.y, r9.z ; w1 + y1 add r2.w, r10.y, r10.z ; w2 + y2 sub r3.w, r1.w, r2.w rcp r3.w, r3.w mul r3.w, r1.w, r3.w sub r4.xyz, r10, r9 mad r5.xyz, r3.w, r4, r9 cmp r9.xyz, r1.w, r9, r5 cmp r10.xyz, r2.w, r10, r5 add r1.w, -r9.y, r9.z ; w1 - y1 add r2.w, -r10.y, r10.z ; w2 - y2 sub r3.w, r1.w, r2.w rcp r3.w, r3.w mul r3.w, r1.w, r3.w sub r4.xyz, r10, r9 mad r5.xyz, r3.w, r4, r9 cmp r9.xyz, r1.w, r9, r5 cmp r10.xyz, r2.w, r10, r5 ; Project onto light source plane rcp r9.w, r9.z mul r9.xyz, r9, r9.w ; x1 y1 rcp r10.w, r10.z mul r10.xyz, r10, r10.w ; x2 y2 ; Compute angles. texld r5, r9, s1 ; theta1 = atan2(x1,y1) texld r6, r10, s1 ; theta2 = atan2(x2,y2) mov r5.y,r6.x ; Combine the two angles texld r0, r5, s2 ; Lookup total area based on angles crs r2.z, r10, r9 ; 2x the area (in z) abs r2.z, r2.z mad r1, r2.z, -AREA_SCALE, r0 ; total_area - area texld r0, r1, s3 ; Lookup encoded color value cmp r1, c9.x, r0.wzyx, r0 ; Choose additve or subtractive mov oC0, r0